1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include <string.h> 17425bb815Sopenharmony_ci#include "jerryscript.h" 18425bb815Sopenharmony_ci#include "jerryscript-ext/module.h" 19425bb815Sopenharmony_ci#if defined(JERRY_FOR_IAR_CONFIG) 20425bb815Sopenharmony_ci#include "jerryscript-core.h" 21425bb815Sopenharmony_ci#include "jrt.h" 22425bb815Sopenharmony_ci#endif 23425bb815Sopenharmony_ci 24425bb815Sopenharmony_cistatic const jerry_char_t *module_name_property_name = (jerry_char_t *) "moduleName"; 25425bb815Sopenharmony_cistatic const jerry_char_t *module_not_found = (jerry_char_t *) "Module not found"; 26425bb815Sopenharmony_cistatic const jerry_char_t *module_name_not_string = (jerry_char_t *) "Module name is not a string"; 27425bb815Sopenharmony_ci 28425bb815Sopenharmony_ci/** 29425bb815Sopenharmony_ci * Create an error related to modules 30425bb815Sopenharmony_ci * 31425bb815Sopenharmony_ci * Creates an error object of the requested type with the additional property "moduleName" the value of which is a 32425bb815Sopenharmony_ci * string containing the name of the module that was requested when the error occurred. 33425bb815Sopenharmony_ci * 34425bb815Sopenharmony_ci * @return the error 35425bb815Sopenharmony_ci */ 36425bb815Sopenharmony_cistatic jerry_value_t 37425bb815Sopenharmony_cijerryx_module_create_error (jerry_error_t error_type, /**< the type of error to create */ 38425bb815Sopenharmony_ci const jerry_char_t *message, /**< the error message */ 39425bb815Sopenharmony_ci const jerry_value_t module_name) /**< the module name */ 40425bb815Sopenharmony_ci{ 41425bb815Sopenharmony_ci jerry_value_t ret = jerry_create_error (error_type, message); 42425bb815Sopenharmony_ci 43425bb815Sopenharmony_ci jerry_value_t error_object = jerry_get_value_from_error (ret, false); 44425bb815Sopenharmony_ci jerry_value_t property_name = jerry_create_string (module_name_property_name); 45425bb815Sopenharmony_ci 46425bb815Sopenharmony_ci jerry_release_value (jerry_set_property (error_object, property_name, module_name)); 47425bb815Sopenharmony_ci 48425bb815Sopenharmony_ci jerry_release_value (property_name); 49425bb815Sopenharmony_ci jerry_release_value (error_object); 50425bb815Sopenharmony_ci return ret; 51425bb815Sopenharmony_ci} /* jerryx_module_create_error */ 52425bb815Sopenharmony_ci 53425bb815Sopenharmony_ci/** 54425bb815Sopenharmony_ci * Initialize the module manager extension. 55425bb815Sopenharmony_ci */ 56425bb815Sopenharmony_cistatic void 57425bb815Sopenharmony_cijerryx_module_manager_init (void *user_data_p) 58425bb815Sopenharmony_ci{ 59425bb815Sopenharmony_ci *((jerry_value_t *) user_data_p) = jerry_create_object (); 60425bb815Sopenharmony_ci} /* jerryx_module_manager_init */ 61425bb815Sopenharmony_ci 62425bb815Sopenharmony_ci/** 63425bb815Sopenharmony_ci * Deinitialize the module manager extension. 64425bb815Sopenharmony_ci */ 65425bb815Sopenharmony_cistatic void 66425bb815Sopenharmony_cijerryx_module_manager_deinit (void *user_data_p) /**< context pointer to deinitialize */ 67425bb815Sopenharmony_ci{ 68425bb815Sopenharmony_ci jerry_release_value (*(jerry_value_t *) user_data_p); 69425bb815Sopenharmony_ci} /* jerryx_module_manager_deinit */ 70425bb815Sopenharmony_ci 71425bb815Sopenharmony_ci/** 72425bb815Sopenharmony_ci * Declare the context data manager for modules. 73425bb815Sopenharmony_ci */ 74425bb815Sopenharmony_cistatic const jerry_context_data_manager_t jerryx_module_manager = 75425bb815Sopenharmony_ci{ 76425bb815Sopenharmony_ci .init_cb = jerryx_module_manager_init, 77425bb815Sopenharmony_ci .deinit_cb = jerryx_module_manager_deinit, 78425bb815Sopenharmony_ci .bytes_needed = sizeof (jerry_value_t) 79425bb815Sopenharmony_ci}; 80425bb815Sopenharmony_ci 81425bb815Sopenharmony_ci/** 82425bb815Sopenharmony_ci * Global static entry point to the linked list of available modules. 83425bb815Sopenharmony_ci */ 84425bb815Sopenharmony_cistatic jerryx_native_module_t *first_module_p = NULL; 85425bb815Sopenharmony_ci 86425bb815Sopenharmony_civoid jerryx_native_module_register (jerryx_native_module_t *module_p) 87425bb815Sopenharmony_ci{ 88425bb815Sopenharmony_ci module_p->next_p = first_module_p; 89425bb815Sopenharmony_ci first_module_p = module_p; 90425bb815Sopenharmony_ci} /* jerryx_native_module_register */ 91425bb815Sopenharmony_ci 92425bb815Sopenharmony_civoid jerryx_native_module_unregister (jerryx_native_module_t *module_p) 93425bb815Sopenharmony_ci{ 94425bb815Sopenharmony_ci jerryx_native_module_t *parent_p = NULL, *iter_p = NULL; 95425bb815Sopenharmony_ci 96425bb815Sopenharmony_ci for (iter_p = first_module_p; iter_p != NULL; parent_p = iter_p, iter_p = iter_p->next_p) 97425bb815Sopenharmony_ci { 98425bb815Sopenharmony_ci if (iter_p == module_p) 99425bb815Sopenharmony_ci { 100425bb815Sopenharmony_ci if (parent_p) 101425bb815Sopenharmony_ci { 102425bb815Sopenharmony_ci parent_p->next_p = module_p->next_p; 103425bb815Sopenharmony_ci } 104425bb815Sopenharmony_ci else 105425bb815Sopenharmony_ci { 106425bb815Sopenharmony_ci first_module_p = module_p->next_p; 107425bb815Sopenharmony_ci } 108425bb815Sopenharmony_ci module_p->next_p = NULL; 109425bb815Sopenharmony_ci } 110425bb815Sopenharmony_ci } 111425bb815Sopenharmony_ci} /* jerryx_native_module_unregister */ 112425bb815Sopenharmony_ci 113425bb815Sopenharmony_ci/** 114425bb815Sopenharmony_ci * Attempt to retrieve a module by name from a cache, and return false if not found. 115425bb815Sopenharmony_ci */ 116425bb815Sopenharmony_cistatic bool 117425bb815Sopenharmony_cijerryx_module_check_cache (jerry_value_t cache, /**< cache from which to attempt to retrieve the module by name */ 118425bb815Sopenharmony_ci jerry_value_t module_name, /**< JerryScript string value holding the module name */ 119425bb815Sopenharmony_ci jerry_value_t *result) /**< Resulting value */ 120425bb815Sopenharmony_ci{ 121425bb815Sopenharmony_ci bool ret = false; 122425bb815Sopenharmony_ci 123425bb815Sopenharmony_ci /* Check if the cache has the module. */ 124425bb815Sopenharmony_ci jerry_value_t js_has_property = jerry_has_property (cache, module_name); 125425bb815Sopenharmony_ci 126425bb815Sopenharmony_ci /* If we succeed in getting an answer, we examine the answer. */ 127425bb815Sopenharmony_ci if (!jerry_value_is_error (js_has_property)) 128425bb815Sopenharmony_ci { 129425bb815Sopenharmony_ci bool has_property = jerry_get_boolean_value (js_has_property); 130425bb815Sopenharmony_ci 131425bb815Sopenharmony_ci /* If the module is indeed in the cache, we return it. */ 132425bb815Sopenharmony_ci if (has_property) 133425bb815Sopenharmony_ci { 134425bb815Sopenharmony_ci if (result != NULL) 135425bb815Sopenharmony_ci { 136425bb815Sopenharmony_ci (*result) = jerry_get_property (cache, module_name); 137425bb815Sopenharmony_ci } 138425bb815Sopenharmony_ci ret = true; 139425bb815Sopenharmony_ci } 140425bb815Sopenharmony_ci } 141425bb815Sopenharmony_ci 142425bb815Sopenharmony_ci jerry_release_value (js_has_property); 143425bb815Sopenharmony_ci 144425bb815Sopenharmony_ci return ret; 145425bb815Sopenharmony_ci} /* jerryx_module_check_cache */ 146425bb815Sopenharmony_ci 147425bb815Sopenharmony_ci/** 148425bb815Sopenharmony_ci * Attempt to cache a loaded module. 149425bb815Sopenharmony_ci * 150425bb815Sopenharmony_ci * @return the module on success, otherwise the error encountered when attempting to cache. In the latter case, the 151425bb815Sopenharmony_ci * @p module is released. 152425bb815Sopenharmony_ci */ 153425bb815Sopenharmony_cistatic jerry_value_t 154425bb815Sopenharmony_cijerryx_module_add_to_cache (jerry_value_t cache, /**< cache to which to add the module */ 155425bb815Sopenharmony_ci jerry_value_t module_name, /**< key at which to cache the module */ 156425bb815Sopenharmony_ci jerry_value_t module) /**< the module to cache */ 157425bb815Sopenharmony_ci{ 158425bb815Sopenharmony_ci jerry_value_t ret = jerry_set_property (cache, module_name, module); 159425bb815Sopenharmony_ci 160425bb815Sopenharmony_ci if (jerry_value_is_error (ret)) 161425bb815Sopenharmony_ci { 162425bb815Sopenharmony_ci jerry_release_value (module); 163425bb815Sopenharmony_ci } 164425bb815Sopenharmony_ci else 165425bb815Sopenharmony_ci { 166425bb815Sopenharmony_ci jerry_release_value (ret); 167425bb815Sopenharmony_ci ret = module; 168425bb815Sopenharmony_ci } 169425bb815Sopenharmony_ci 170425bb815Sopenharmony_ci return ret; 171425bb815Sopenharmony_ci} /* jerryx_module_add_to_cache */ 172425bb815Sopenharmony_ci 173425bb815Sopenharmony_cistatic const jerry_char_t *on_resolve_absent = (jerry_char_t *) "Module on_resolve () must not be NULL"; 174425bb815Sopenharmony_ci 175425bb815Sopenharmony_ci/** 176425bb815Sopenharmony_ci * Declare and define the default module resolver - one which examines what modules are defined in the above linker 177425bb815Sopenharmony_ci * section and loads one that matches the requested name, caching the result for subsequent requests using the context 178425bb815Sopenharmony_ci * data mechanism. 179425bb815Sopenharmony_ci */ 180425bb815Sopenharmony_cistatic bool 181425bb815Sopenharmony_cijerryx_resolve_native_module (const jerry_value_t canonical_name, /**< canonical name of the module */ 182425bb815Sopenharmony_ci jerry_value_t *result) /**< [out] where to put the resulting module instance */ 183425bb815Sopenharmony_ci{ 184425bb815Sopenharmony_ci const jerryx_native_module_t *module_p = NULL; 185425bb815Sopenharmony_ci#if defined(JERRY_FOR_IAR_CONFIG) 186425bb815Sopenharmony_ci jerry_char_t* name_string; 187425bb815Sopenharmony_ci#endif 188425bb815Sopenharmony_ci 189425bb815Sopenharmony_ci jerry_size_t name_size = jerry_get_utf8_string_size (canonical_name); 190425bb815Sopenharmony_ci#if defined(JERRY_FOR_IAR_CONFIG) 191425bb815Sopenharmony_ci name_string = (jerry_char_t*) jerry_vla_malloc (sizeof(jerry_char_t) * name_size); 192425bb815Sopenharmony_ci if (!name_string) 193425bb815Sopenharmony_ci { 194425bb815Sopenharmony_ci JERRY_ERROR_MSG("malloc name_string fail\n"); 195425bb815Sopenharmony_ci return false; 196425bb815Sopenharmony_ci } 197425bb815Sopenharmony_ci#else 198425bb815Sopenharmony_ci JERRY_VLA (jerry_char_t, name_string, name_size); 199425bb815Sopenharmony_ci#endif 200425bb815Sopenharmony_ci jerry_string_to_utf8_char_buffer (canonical_name, name_string, name_size); 201425bb815Sopenharmony_ci 202425bb815Sopenharmony_ci /* Look for the module by its name in the list of module definitions. */ 203425bb815Sopenharmony_ci for (module_p = first_module_p; module_p != NULL; module_p = module_p->next_p) 204425bb815Sopenharmony_ci { 205425bb815Sopenharmony_ci if (module_p->name_p != NULL 206425bb815Sopenharmony_ci && strlen ((char *) module_p->name_p) == name_size 207425bb815Sopenharmony_ci && !strncmp ((char *) module_p->name_p, (char *) name_string, name_size)) 208425bb815Sopenharmony_ci { 209425bb815Sopenharmony_ci /* If we find the module by its name we load it and cache it if it has an on_resolve () and complain otherwise. */ 210425bb815Sopenharmony_ci (*result) = ((module_p->on_resolve_p) ? module_p->on_resolve_p () 211425bb815Sopenharmony_ci : jerryx_module_create_error (JERRY_ERROR_TYPE, 212425bb815Sopenharmony_ci on_resolve_absent, 213425bb815Sopenharmony_ci canonical_name)); 214425bb815Sopenharmony_ci#if defined(JERRY_FOR_IAR_CONFIG) 215425bb815Sopenharmony_ci jerry_vla_free ((char*)name_string); 216425bb815Sopenharmony_ci#endif 217425bb815Sopenharmony_ci return true; 218425bb815Sopenharmony_ci } 219425bb815Sopenharmony_ci } 220425bb815Sopenharmony_ci#if defined(JERRY_FOR_IAR_CONFIG) 221425bb815Sopenharmony_ci jerry_vla_free ((char*)name_string); 222425bb815Sopenharmony_ci#endif 223425bb815Sopenharmony_ci 224425bb815Sopenharmony_ci return false; 225425bb815Sopenharmony_ci} /* jerryx_resolve_native_module */ 226425bb815Sopenharmony_ci 227425bb815Sopenharmony_cijerryx_module_resolver_t jerryx_module_native_resolver = 228425bb815Sopenharmony_ci{ 229425bb815Sopenharmony_ci .get_canonical_name_p = NULL, 230425bb815Sopenharmony_ci .resolve_p = jerryx_resolve_native_module 231425bb815Sopenharmony_ci}; 232425bb815Sopenharmony_ci 233425bb815Sopenharmony_cistatic void 234425bb815Sopenharmony_cijerryx_module_resolve_local (const jerry_value_t name, /**< name of the module to load */ 235425bb815Sopenharmony_ci const jerryx_module_resolver_t **resolvers_p, /**< list of resolvers */ 236425bb815Sopenharmony_ci size_t resolver_count, /**< number of resolvers in @p resolvers */ 237425bb815Sopenharmony_ci jerry_value_t *result) /**< location to store the result, or NULL to remove the module */ 238425bb815Sopenharmony_ci{ 239425bb815Sopenharmony_ci size_t index; 240425bb815Sopenharmony_ci size_t canonical_names_used = 0; 241425bb815Sopenharmony_ci jerry_value_t instances; 242425bb815Sopenharmony_ci#if defined(JERRY_FOR_IAR_CONFIG) 243425bb815Sopenharmony_ci jerry_value_t* canonical_names; 244425bb815Sopenharmony_ci canonical_names = (jerry_value_t*) jerry_vla_malloc (sizeof(jerry_value_t) * resolver_count); 245425bb815Sopenharmony_ci if (!canonical_names) 246425bb815Sopenharmony_ci { 247425bb815Sopenharmony_ci JERRY_ERROR_MSG("malloc canonical_names fail\n"); 248425bb815Sopenharmony_ci return; 249425bb815Sopenharmony_ci } 250425bb815Sopenharmony_ci#else 251425bb815Sopenharmony_ci JERRY_VLA (jerry_value_t, canonical_names, resolver_count); 252425bb815Sopenharmony_ci#endif 253425bb815Sopenharmony_ci jerry_value_t (*get_canonical_name_p) (const jerry_value_t name); 254425bb815Sopenharmony_ci bool (*resolve_p) (const jerry_value_t canonical_name, 255425bb815Sopenharmony_ci jerry_value_t *result); 256425bb815Sopenharmony_ci 257425bb815Sopenharmony_ci if (!jerry_value_is_string (name)) 258425bb815Sopenharmony_ci { 259425bb815Sopenharmony_ci if (result != NULL) 260425bb815Sopenharmony_ci { 261425bb815Sopenharmony_ci *result = jerryx_module_create_error (JERRY_ERROR_COMMON, module_name_not_string, name); 262425bb815Sopenharmony_ci } 263425bb815Sopenharmony_ci goto done; 264425bb815Sopenharmony_ci } 265425bb815Sopenharmony_ci 266425bb815Sopenharmony_ci instances = *(jerry_value_t *) jerry_get_context_data (&jerryx_module_manager); 267425bb815Sopenharmony_ci 268425bb815Sopenharmony_ci /** 269425bb815Sopenharmony_ci * Establish the canonical name for the requested module. Each resolver presents its own canonical name. If one of 270425bb815Sopenharmony_ci * the canonical names matches a cached module, it is returned as the result. 271425bb815Sopenharmony_ci */ 272425bb815Sopenharmony_ci for (index = 0; index < resolver_count; index++) 273425bb815Sopenharmony_ci { 274425bb815Sopenharmony_ci get_canonical_name_p = (resolvers_p[index] == NULL ? NULL : resolvers_p[index]->get_canonical_name_p); 275425bb815Sopenharmony_ci canonical_names[index] = ((get_canonical_name_p == NULL) ? jerry_acquire_value (name) 276425bb815Sopenharmony_ci : get_canonical_name_p (name)); 277425bb815Sopenharmony_ci canonical_names_used++; 278425bb815Sopenharmony_ci if (jerryx_module_check_cache (instances, canonical_names[index], result)) 279425bb815Sopenharmony_ci { 280425bb815Sopenharmony_ci /* A NULL for result indicates that we are to delete the module from the cache if found. Let's do that here.*/ 281425bb815Sopenharmony_ci if (result == NULL) 282425bb815Sopenharmony_ci { 283425bb815Sopenharmony_ci jerry_delete_property (instances, canonical_names[index]); 284425bb815Sopenharmony_ci } 285425bb815Sopenharmony_ci goto done; 286425bb815Sopenharmony_ci } 287425bb815Sopenharmony_ci } 288425bb815Sopenharmony_ci 289425bb815Sopenharmony_ci if (result == NULL) 290425bb815Sopenharmony_ci { 291425bb815Sopenharmony_ci goto done; 292425bb815Sopenharmony_ci } 293425bb815Sopenharmony_ci 294425bb815Sopenharmony_ci /** 295425bb815Sopenharmony_ci * Past this point we assume a module is wanted, and therefore result is not NULL. So, we try each resolver until one 296425bb815Sopenharmony_ci * manages to resolve the module. 297425bb815Sopenharmony_ci */ 298425bb815Sopenharmony_ci for (index = 0; index < resolver_count; index++) 299425bb815Sopenharmony_ci { 300425bb815Sopenharmony_ci resolve_p = (resolvers_p[index] == NULL ? NULL : resolvers_p[index]->resolve_p); 301425bb815Sopenharmony_ci if (resolve_p != NULL && resolve_p (canonical_names[index], result)) 302425bb815Sopenharmony_ci { 303425bb815Sopenharmony_ci if (!jerry_value_is_error (*result)) 304425bb815Sopenharmony_ci { 305425bb815Sopenharmony_ci *result = jerryx_module_add_to_cache (instances, canonical_names[index], *result); 306425bb815Sopenharmony_ci } 307425bb815Sopenharmony_ci goto done; 308425bb815Sopenharmony_ci } 309425bb815Sopenharmony_ci } 310425bb815Sopenharmony_ci 311425bb815Sopenharmony_ci /* If none of the resolvers manage to find the module, complain with "Module not found" */ 312425bb815Sopenharmony_ci *result = jerryx_module_create_error (JERRY_ERROR_COMMON, module_not_found, name); 313425bb815Sopenharmony_ci 314425bb815Sopenharmony_cidone: 315425bb815Sopenharmony_ci /* Release the canonical names as returned by the various resolvers. */ 316425bb815Sopenharmony_ci for (index = 0; index < canonical_names_used; index++) 317425bb815Sopenharmony_ci { 318425bb815Sopenharmony_ci jerry_release_value (canonical_names[index]); 319425bb815Sopenharmony_ci } 320425bb815Sopenharmony_ci#if defined(JERRY_FOR_IAR_CONFIG) 321425bb815Sopenharmony_ci jerry_vla_free ((char*)canonical_names); 322425bb815Sopenharmony_ci#endif 323425bb815Sopenharmony_ci} /* jerryx_module_resolve_local */ 324425bb815Sopenharmony_ci 325425bb815Sopenharmony_ci/** 326425bb815Sopenharmony_ci * Resolve a single module using the module resolvers available in the section declared above and load it into the 327425bb815Sopenharmony_ci * current context. 328425bb815Sopenharmony_ci * 329425bb815Sopenharmony_ci * @p name - name of the module to resolve 330425bb815Sopenharmony_ci * @p resolvers - list of resolvers to invoke 331425bb815Sopenharmony_ci * @p count - number of resolvers in the list 332425bb815Sopenharmony_ci * 333425bb815Sopenharmony_ci * @return a jerry_value_t containing one of the followings: 334425bb815Sopenharmony_ci * - the result of having loaded the module named @p name, or 335425bb815Sopenharmony_ci * - the result of a previous successful load, or 336425bb815Sopenharmony_ci * - an error indicating that something went wrong during the attempt to load the module. 337425bb815Sopenharmony_ci */ 338425bb815Sopenharmony_cijerry_value_t 339425bb815Sopenharmony_cijerryx_module_resolve (const jerry_value_t name, /**< name of the module to load */ 340425bb815Sopenharmony_ci const jerryx_module_resolver_t **resolvers_p, /**< list of resolvers */ 341425bb815Sopenharmony_ci size_t resolver_count) /**< number of resolvers in @p resolvers */ 342425bb815Sopenharmony_ci{ 343425bb815Sopenharmony_ci /* Set to zero to circumvent fatal warning. */ 344425bb815Sopenharmony_ci jerry_value_t ret = 0; 345425bb815Sopenharmony_ci jerryx_module_resolve_local (name, resolvers_p, resolver_count, &ret); 346425bb815Sopenharmony_ci return ret; 347425bb815Sopenharmony_ci} /* jerryx_module_resolve */ 348425bb815Sopenharmony_ci 349425bb815Sopenharmony_civoid 350425bb815Sopenharmony_cijerryx_module_clear_cache (const jerry_value_t name, /**< name of the module to remove, or undefined */ 351425bb815Sopenharmony_ci const jerryx_module_resolver_t **resolvers_p, /**< list of resolvers */ 352425bb815Sopenharmony_ci size_t resolver_count) /**< number of resolvers in @p resolvers */ 353425bb815Sopenharmony_ci{ 354425bb815Sopenharmony_ci void *instances_p = jerry_get_context_data (&jerryx_module_manager); 355425bb815Sopenharmony_ci 356425bb815Sopenharmony_ci if (jerry_value_is_undefined (name)) 357425bb815Sopenharmony_ci { 358425bb815Sopenharmony_ci /* We were requested to clear the entire cache, so we bounce the context data in the most agnostic way possible. */ 359425bb815Sopenharmony_ci jerryx_module_manager.deinit_cb (instances_p); 360425bb815Sopenharmony_ci jerryx_module_manager.init_cb (instances_p); 361425bb815Sopenharmony_ci return; 362425bb815Sopenharmony_ci } 363425bb815Sopenharmony_ci 364425bb815Sopenharmony_ci /* Delete the requested module from the cache if it's there. */ 365425bb815Sopenharmony_ci jerryx_module_resolve_local (name, resolvers_p, resolver_count, NULL); 366425bb815Sopenharmony_ci} /* jerryx_module_clear_cache */ 367