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