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 "jcontext.h"
17425bb815Sopenharmony_ci#include "jerryscript.h"
18425bb815Sopenharmony_ci
19425bb815Sopenharmony_ci#include "ecma-exceptions.h"
20425bb815Sopenharmony_ci#include "ecma-function-object.h"
21425bb815Sopenharmony_ci#include "ecma-gc.h"
22425bb815Sopenharmony_ci#include "ecma-globals.h"
23425bb815Sopenharmony_ci#include "ecma-helpers.h"
24425bb815Sopenharmony_ci#include "ecma-lex-env.h"
25425bb815Sopenharmony_ci#include "ecma-module.h"
26425bb815Sopenharmony_ci#include "ecma-objects.h"
27425bb815Sopenharmony_ci#include "lit-char-helpers.h"
28425bb815Sopenharmony_ci#include "vm.h"
29425bb815Sopenharmony_ci
30425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
31425bb815Sopenharmony_ci
32425bb815Sopenharmony_ci/**
33425bb815Sopenharmony_ci * Takes a ModuleSpecifier and applies path normalization to it.
34425bb815Sopenharmony_ci * It's not checked if the ModuleSpecifier is a valid path or not.
35425bb815Sopenharmony_ci * Note: See 15.2.1.17
36425bb815Sopenharmony_ci *
37425bb815Sopenharmony_ci * @return pointer to ecma_string_t containing the normalized and zero terminated path
38425bb815Sopenharmony_ci */
39425bb815Sopenharmony_ciecma_string_t *
40425bb815Sopenharmony_ciecma_module_create_normalized_path (const uint8_t *char_p, /**< module specifier */
41425bb815Sopenharmony_ci                                    prop_length_t size) /**< size of module specifier */
42425bb815Sopenharmony_ci{
43425bb815Sopenharmony_ci  JERRY_ASSERT (size > 0);
44425bb815Sopenharmony_ci  ecma_string_t *ret_p = NULL;
45425bb815Sopenharmony_ci
46425bb815Sopenharmony_ci  /* The module specifier is cesu8 encoded, we need to convert is to utf8, and zero terminate it,
47425bb815Sopenharmony_ci   * so that OS level functions can handle it. */
48425bb815Sopenharmony_ci  lit_utf8_byte_t *path_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (size + 1u);
49425bb815Sopenharmony_ci
50425bb815Sopenharmony_ci  lit_utf8_size_t utf8_size;
51425bb815Sopenharmony_ci  utf8_size = lit_convert_cesu8_string_to_utf8_string (char_p,
52425bb815Sopenharmony_ci                                                       size,
53425bb815Sopenharmony_ci                                                       path_p,
54425bb815Sopenharmony_ci                                                       size);
55425bb815Sopenharmony_ci  path_p[utf8_size] = LIT_CHAR_NULL;
56425bb815Sopenharmony_ci
57425bb815Sopenharmony_ci  lit_utf8_byte_t *module_path_p = NULL;
58425bb815Sopenharmony_ci  lit_utf8_size_t module_path_size = 0;
59425bb815Sopenharmony_ci
60425bb815Sopenharmony_ci  /* Check if we have a current module, and use its path as the base path. */
61425bb815Sopenharmony_ci  JERRY_ASSERT (JERRY_CONTEXT (module_top_context_p) != NULL);
62425bb815Sopenharmony_ci  if (JERRY_CONTEXT (module_top_context_p)->module_p != NULL)
63425bb815Sopenharmony_ci  {
64425bb815Sopenharmony_ci    JERRY_ASSERT (JERRY_CONTEXT (module_top_context_p)->module_p->path_p != NULL);
65425bb815Sopenharmony_ci    module_path_size = ecma_string_get_size (JERRY_CONTEXT (module_top_context_p)->module_p->path_p);
66425bb815Sopenharmony_ci    module_path_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (module_path_size + 1);
67425bb815Sopenharmony_ci
68425bb815Sopenharmony_ci    lit_utf8_size_t module_utf8_size;
69425bb815Sopenharmony_ci    module_utf8_size = ecma_string_copy_to_utf8_buffer (JERRY_CONTEXT (module_top_context_p)->module_p->path_p,
70425bb815Sopenharmony_ci                                                        module_path_p,
71425bb815Sopenharmony_ci                                                        module_path_size);
72425bb815Sopenharmony_ci
73425bb815Sopenharmony_ci    module_path_p[module_utf8_size] = LIT_CHAR_NULL;
74425bb815Sopenharmony_ci  }
75425bb815Sopenharmony_ci
76425bb815Sopenharmony_ci  lit_utf8_byte_t *normalized_out_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (ECMA_MODULE_MAX_PATH);
77425bb815Sopenharmony_ci  size_t normalized_size = jerry_port_normalize_path ((const char *) path_p,
78425bb815Sopenharmony_ci                                                      (char *) normalized_out_p,
79425bb815Sopenharmony_ci                                                      ECMA_MODULE_MAX_PATH,
80425bb815Sopenharmony_ci                                                      (char *) module_path_p);
81425bb815Sopenharmony_ci
82425bb815Sopenharmony_ci  if (normalized_size > 0)
83425bb815Sopenharmony_ci  {
84425bb815Sopenharmony_ci    /* Convert the normalized path to cesu8. */
85425bb815Sopenharmony_ci    ret_p = ecma_new_ecma_string_from_utf8_converted_to_cesu8 (normalized_out_p, (lit_utf8_size_t) (normalized_size));
86425bb815Sopenharmony_ci  }
87425bb815Sopenharmony_ci
88425bb815Sopenharmony_ci  jmem_heap_free_block (path_p, size + 1u);
89425bb815Sopenharmony_ci  jmem_heap_free_block (normalized_out_p, ECMA_MODULE_MAX_PATH);
90425bb815Sopenharmony_ci  if (module_path_p != NULL)
91425bb815Sopenharmony_ci  {
92425bb815Sopenharmony_ci    jmem_heap_free_block (module_path_p, module_path_size + 1);
93425bb815Sopenharmony_ci  }
94425bb815Sopenharmony_ci
95425bb815Sopenharmony_ci  return ret_p;
96425bb815Sopenharmony_ci} /* ecma_module_create_normalized_path */
97425bb815Sopenharmony_ci
98425bb815Sopenharmony_ci/**
99425bb815Sopenharmony_ci * Find a module with a specific identifier
100425bb815Sopenharmony_ci *
101425bb815Sopenharmony_ci * @return pointer to ecma_module_t, if found
102425bb815Sopenharmony_ci *         NULL, otherwise
103425bb815Sopenharmony_ci */
104425bb815Sopenharmony_ciecma_module_t *
105425bb815Sopenharmony_ciecma_module_find_module (ecma_string_t *const path_p) /**< module identifier */
106425bb815Sopenharmony_ci{
107425bb815Sopenharmony_ci  ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
108425bb815Sopenharmony_ci  while (current_p != NULL)
109425bb815Sopenharmony_ci  {
110425bb815Sopenharmony_ci    if (ecma_compare_ecma_strings (path_p, current_p->path_p))
111425bb815Sopenharmony_ci    {
112425bb815Sopenharmony_ci      return current_p;
113425bb815Sopenharmony_ci    }
114425bb815Sopenharmony_ci    current_p = current_p->next_p;
115425bb815Sopenharmony_ci  }
116425bb815Sopenharmony_ci
117425bb815Sopenharmony_ci  return current_p;
118425bb815Sopenharmony_ci} /* ecma_module_find_module */
119425bb815Sopenharmony_ci
120425bb815Sopenharmony_ci/**
121425bb815Sopenharmony_ci * Create a new module
122425bb815Sopenharmony_ci *
123425bb815Sopenharmony_ci * @return pointer to created module
124425bb815Sopenharmony_ci */
125425bb815Sopenharmony_cistatic ecma_module_t *
126425bb815Sopenharmony_ciecma_module_create_module (ecma_string_t *const path_p) /**< module identifier */
127425bb815Sopenharmony_ci{
128425bb815Sopenharmony_ci  ecma_module_t *module_p = (ecma_module_t *) jmem_heap_alloc_block (sizeof (ecma_module_t));
129425bb815Sopenharmony_ci  memset (module_p, 0, sizeof (ecma_module_t));
130425bb815Sopenharmony_ci
131425bb815Sopenharmony_ci  module_p->path_p = path_p;
132425bb815Sopenharmony_ci  module_p->next_p = JERRY_CONTEXT (ecma_modules_p);
133425bb815Sopenharmony_ci  JERRY_CONTEXT (ecma_modules_p) = module_p;
134425bb815Sopenharmony_ci  return module_p;
135425bb815Sopenharmony_ci} /* ecma_module_create_module */
136425bb815Sopenharmony_ci
137425bb815Sopenharmony_ci/**
138425bb815Sopenharmony_ci * Checks if we already have a module request in the module list.
139425bb815Sopenharmony_ci *
140425bb815Sopenharmony_ci * @return pointer to found or newly created module structure
141425bb815Sopenharmony_ci */
142425bb815Sopenharmony_ciecma_module_t *
143425bb815Sopenharmony_ciecma_module_find_or_create_module (ecma_string_t *const path_p) /**< module path */
144425bb815Sopenharmony_ci{
145425bb815Sopenharmony_ci  ecma_module_t *module_p = ecma_module_find_module (path_p);
146425bb815Sopenharmony_ci  if (module_p)
147425bb815Sopenharmony_ci  {
148425bb815Sopenharmony_ci    ecma_deref_ecma_string (path_p);
149425bb815Sopenharmony_ci    return module_p;
150425bb815Sopenharmony_ci  }
151425bb815Sopenharmony_ci
152425bb815Sopenharmony_ci  return ecma_module_create_module (path_p);
153425bb815Sopenharmony_ci} /* ecma_module_find_or_create_module */
154425bb815Sopenharmony_ci
155425bb815Sopenharmony_ci/**
156425bb815Sopenharmony_ci * Create a new native module
157425bb815Sopenharmony_ci *
158425bb815Sopenharmony_ci * @return pointer to created module
159425bb815Sopenharmony_ci */
160425bb815Sopenharmony_ciecma_module_t *
161425bb815Sopenharmony_ciecma_module_create_native_module (ecma_string_t *const path_p, /**< module identifier */
162425bb815Sopenharmony_ci                                  ecma_object_t *const namespace_p) /**< module namespace */
163425bb815Sopenharmony_ci{
164425bb815Sopenharmony_ci  ecma_module_t *module_p = ecma_module_create_module (path_p);
165425bb815Sopenharmony_ci  module_p->state = ECMA_MODULE_STATE_NATIVE;
166425bb815Sopenharmony_ci  module_p->namespace_object_p = namespace_p;
167425bb815Sopenharmony_ci  return module_p;
168425bb815Sopenharmony_ci} /* ecma_module_create_native_module */
169425bb815Sopenharmony_ci
170425bb815Sopenharmony_ci/**
171425bb815Sopenharmony_ci * Creates a module context.
172425bb815Sopenharmony_ci *
173425bb815Sopenharmony_ci * @return pointer to created module context
174425bb815Sopenharmony_ci */
175425bb815Sopenharmony_cistatic ecma_module_context_t *
176425bb815Sopenharmony_ciecma_module_create_module_context (void)
177425bb815Sopenharmony_ci{
178425bb815Sopenharmony_ci  ecma_module_context_t *context_p = (ecma_module_context_t *) jmem_heap_alloc_block (sizeof (ecma_module_context_t));
179425bb815Sopenharmony_ci  memset (context_p, 0, sizeof (ecma_module_context_t));
180425bb815Sopenharmony_ci
181425bb815Sopenharmony_ci  return context_p;
182425bb815Sopenharmony_ci} /* ecma_module_create_module_context */
183425bb815Sopenharmony_ci
184425bb815Sopenharmony_ci/**
185425bb815Sopenharmony_ci *  Inserts a {module, export_name} record into a resolve set.
186425bb815Sopenharmony_ci *  Note: See 15.2.1.16.3 - resolveSet and exportStarSet
187425bb815Sopenharmony_ci *
188425bb815Sopenharmony_ci *  @return true - if the set already contains the record
189425bb815Sopenharmony_ci *          false - otherwise
190425bb815Sopenharmony_ci */
191425bb815Sopenharmony_cibool
192425bb815Sopenharmony_ciecma_module_resolve_set_insert (ecma_module_resolve_set_t **set_p, /**< [in, out] resolve set */
193425bb815Sopenharmony_ci                                ecma_module_t * const module_p, /**< module */
194425bb815Sopenharmony_ci                                ecma_string_t * const export_name_p) /**< export name */
195425bb815Sopenharmony_ci{
196425bb815Sopenharmony_ci  JERRY_ASSERT (set_p != NULL);
197425bb815Sopenharmony_ci  ecma_module_resolve_set_t *current_p = *set_p;
198425bb815Sopenharmony_ci
199425bb815Sopenharmony_ci  while (current_p != NULL)
200425bb815Sopenharmony_ci  {
201425bb815Sopenharmony_ci    if (current_p->record.module_p == module_p
202425bb815Sopenharmony_ci        && ecma_compare_ecma_strings (current_p->record.name_p, export_name_p))
203425bb815Sopenharmony_ci    {
204425bb815Sopenharmony_ci      return false;
205425bb815Sopenharmony_ci    }
206425bb815Sopenharmony_ci
207425bb815Sopenharmony_ci    current_p = current_p->next_p;
208425bb815Sopenharmony_ci  }
209425bb815Sopenharmony_ci
210425bb815Sopenharmony_ci  ecma_module_resolve_set_t *new_p;
211425bb815Sopenharmony_ci  new_p = (ecma_module_resolve_set_t *) jmem_heap_alloc_block (sizeof (ecma_module_resolve_set_t));
212425bb815Sopenharmony_ci
213425bb815Sopenharmony_ci  new_p->next_p = *set_p;
214425bb815Sopenharmony_ci  new_p->record.module_p = module_p;
215425bb815Sopenharmony_ci  ecma_ref_ecma_string (export_name_p);
216425bb815Sopenharmony_ci  new_p->record.name_p = export_name_p;
217425bb815Sopenharmony_ci
218425bb815Sopenharmony_ci  *set_p = new_p;
219425bb815Sopenharmony_ci  return true;
220425bb815Sopenharmony_ci} /* ecma_module_resolve_set_insert */
221425bb815Sopenharmony_ci
222425bb815Sopenharmony_ci/**
223425bb815Sopenharmony_ci * Cleans up contents of a resolve set.
224425bb815Sopenharmony_ci */
225425bb815Sopenharmony_civoid
226425bb815Sopenharmony_ciecma_module_resolve_set_cleanup (ecma_module_resolve_set_t *set_p) /**< resolve set */
227425bb815Sopenharmony_ci{
228425bb815Sopenharmony_ci  while (set_p != NULL)
229425bb815Sopenharmony_ci  {
230425bb815Sopenharmony_ci    ecma_module_resolve_set_t *next_p = set_p->next_p;
231425bb815Sopenharmony_ci    ecma_deref_ecma_string (set_p->record.name_p);
232425bb815Sopenharmony_ci    jmem_heap_free_block (set_p, sizeof (ecma_module_resolve_set_t));
233425bb815Sopenharmony_ci    set_p = next_p;
234425bb815Sopenharmony_ci  }
235425bb815Sopenharmony_ci} /* ecma_module_resolve_set_cleanup */
236425bb815Sopenharmony_ci
237425bb815Sopenharmony_ci/**
238425bb815Sopenharmony_ci * Pushes a new resolve frame on top of a resolve stack and initializes it
239425bb815Sopenharmony_ci * to begin resolving the specified exported name in the base module.
240425bb815Sopenharmony_ci */
241425bb815Sopenharmony_civoid
242425bb815Sopenharmony_ciecma_module_resolve_stack_push (ecma_module_resolve_stack_t **stack_p, /**< [in, out] resolve stack */
243425bb815Sopenharmony_ci                                ecma_module_t * const module_p, /**< base module */
244425bb815Sopenharmony_ci                                ecma_string_t * const export_name_p) /**< exported name */
245425bb815Sopenharmony_ci{
246425bb815Sopenharmony_ci  JERRY_ASSERT (stack_p != NULL);
247425bb815Sopenharmony_ci  ecma_module_resolve_stack_t *new_frame_p;
248425bb815Sopenharmony_ci  new_frame_p = (ecma_module_resolve_stack_t *) jmem_heap_alloc_block (sizeof (ecma_module_resolve_stack_t));
249425bb815Sopenharmony_ci
250425bb815Sopenharmony_ci  ecma_ref_ecma_string (export_name_p);
251425bb815Sopenharmony_ci  new_frame_p->export_name_p = export_name_p;
252425bb815Sopenharmony_ci  new_frame_p->module_p = module_p;
253425bb815Sopenharmony_ci  new_frame_p->resolving = false;
254425bb815Sopenharmony_ci
255425bb815Sopenharmony_ci  new_frame_p->next_p = *stack_p;
256425bb815Sopenharmony_ci  *stack_p = new_frame_p;
257425bb815Sopenharmony_ci} /* ecma_module_resolve_stack_push */
258425bb815Sopenharmony_ci
259425bb815Sopenharmony_ci/**
260425bb815Sopenharmony_ci * Pops the topmost frame from a resolve stack.
261425bb815Sopenharmony_ci */
262425bb815Sopenharmony_civoid
263425bb815Sopenharmony_ciecma_module_resolve_stack_pop (ecma_module_resolve_stack_t **stack_p) /**< [in, out] resolve stack */
264425bb815Sopenharmony_ci{
265425bb815Sopenharmony_ci  JERRY_ASSERT (stack_p != NULL);
266425bb815Sopenharmony_ci  ecma_module_resolve_stack_t *current_p = *stack_p;
267425bb815Sopenharmony_ci
268425bb815Sopenharmony_ci  if (current_p != NULL)
269425bb815Sopenharmony_ci  {
270425bb815Sopenharmony_ci    *stack_p = current_p->next_p;
271425bb815Sopenharmony_ci    ecma_deref_ecma_string (current_p->export_name_p);
272425bb815Sopenharmony_ci    jmem_heap_free_block (current_p, sizeof (ecma_module_resolve_stack_t));
273425bb815Sopenharmony_ci  }
274425bb815Sopenharmony_ci} /* ecma_module_resolve_stack_pop */
275425bb815Sopenharmony_ci
276425bb815Sopenharmony_ci/**
277425bb815Sopenharmony_ci * Resolves which module satisfies an export based from a specific module in the import tree.
278425bb815Sopenharmony_ci * If no error occurs, out_record_p will contain a {module, local_name} record, which satisfies
279425bb815Sopenharmony_ci * the export, or {NULL, NULL} if the export is ambiguous.
280425bb815Sopenharmony_ci * Note: See 15.2.1.16.3
281425bb815Sopenharmony_ci *
282425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if an error occured
283425bb815Sopenharmony_ci *         ECMA_VALUE_EMPTY - otherwise
284425bb815Sopenharmony_ci */
285425bb815Sopenharmony_cistatic ecma_value_t
286425bb815Sopenharmony_ciecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
287425bb815Sopenharmony_ci                            ecma_string_t * const export_name_p, /**< export name */
288425bb815Sopenharmony_ci                            ecma_module_record_t *out_record_p) /**< [out] found module record */
289425bb815Sopenharmony_ci{
290425bb815Sopenharmony_ci  ecma_module_resolve_set_t *resolve_set_p = NULL;
291425bb815Sopenharmony_ci  ecma_module_resolve_stack_t *stack_p = NULL;
292425bb815Sopenharmony_ci
293425bb815Sopenharmony_ci  bool found = false;
294425bb815Sopenharmony_ci  ecma_module_record_t found_record = { NULL, NULL };
295425bb815Sopenharmony_ci  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
296425bb815Sopenharmony_ci
297425bb815Sopenharmony_ci  ecma_module_resolve_stack_push (&stack_p, module_p, export_name_p);
298425bb815Sopenharmony_ci
299425bb815Sopenharmony_ci  while (stack_p != NULL)
300425bb815Sopenharmony_ci  {
301425bb815Sopenharmony_ci    ecma_module_resolve_stack_t *current_frame_p = stack_p;
302425bb815Sopenharmony_ci
303425bb815Sopenharmony_ci    ecma_module_t *current_module_p = current_frame_p->module_p;
304425bb815Sopenharmony_ci    JERRY_ASSERT (current_module_p->state >= ECMA_MODULE_STATE_PARSED);
305425bb815Sopenharmony_ci    ecma_module_context_t *context_p = current_module_p->context_p;
306425bb815Sopenharmony_ci    ecma_string_t *current_export_name_p = current_frame_p->export_name_p;
307425bb815Sopenharmony_ci
308425bb815Sopenharmony_ci    if (!current_frame_p->resolving)
309425bb815Sopenharmony_ci    {
310425bb815Sopenharmony_ci      current_frame_p->resolving = true;
311425bb815Sopenharmony_ci
312425bb815Sopenharmony_ci      /* 15.2.1.16.3 / 2-3 */
313425bb815Sopenharmony_ci      if (!ecma_module_resolve_set_insert (&resolve_set_p, current_module_p, current_export_name_p))
314425bb815Sopenharmony_ci      {
315425bb815Sopenharmony_ci        /* This is a circular import request. */
316425bb815Sopenharmony_ci        ecma_module_resolve_stack_pop (&stack_p);
317425bb815Sopenharmony_ci        continue;
318425bb815Sopenharmony_ci      }
319425bb815Sopenharmony_ci
320425bb815Sopenharmony_ci      if (current_module_p->state == ECMA_MODULE_STATE_NATIVE)
321425bb815Sopenharmony_ci      {
322425bb815Sopenharmony_ci        ecma_object_t *object_p = current_module_p->namespace_object_p;
323425bb815Sopenharmony_ci        ecma_value_t prop_value = ecma_op_object_find_own (ecma_make_object_value (object_p),
324425bb815Sopenharmony_ci                                                           object_p,
325425bb815Sopenharmony_ci                                                           current_export_name_p);
326425bb815Sopenharmony_ci        if (ecma_is_value_found (prop_value))
327425bb815Sopenharmony_ci        {
328425bb815Sopenharmony_ci          found = true;
329425bb815Sopenharmony_ci          found_record.module_p = current_module_p;
330425bb815Sopenharmony_ci          found_record.name_p = current_export_name_p;
331425bb815Sopenharmony_ci          ecma_free_value (prop_value);
332425bb815Sopenharmony_ci        }
333425bb815Sopenharmony_ci
334425bb815Sopenharmony_ci        if (ecma_compare_ecma_string_to_magic_id (current_export_name_p, LIT_MAGIC_STRING_DEFAULT))
335425bb815Sopenharmony_ci        {
336425bb815Sopenharmony_ci          ret_value = ecma_raise_syntax_error (ECMA_ERR_MSG ("No default export in native module."));
337425bb815Sopenharmony_ci          break;
338425bb815Sopenharmony_ci        }
339425bb815Sopenharmony_ci
340425bb815Sopenharmony_ci        ecma_module_resolve_stack_pop (&stack_p);
341425bb815Sopenharmony_ci        continue;
342425bb815Sopenharmony_ci      }
343425bb815Sopenharmony_ci
344425bb815Sopenharmony_ci      if (context_p->local_exports_p != NULL)
345425bb815Sopenharmony_ci      {
346425bb815Sopenharmony_ci        /* 15.2.1.16.3 / 4 */
347425bb815Sopenharmony_ci        JERRY_ASSERT (context_p->local_exports_p->next_p == NULL);
348425bb815Sopenharmony_ci        ecma_module_names_t *export_names_p = context_p->local_exports_p->module_names_p;
349425bb815Sopenharmony_ci        while (export_names_p != NULL)
350425bb815Sopenharmony_ci        {
351425bb815Sopenharmony_ci          if (ecma_compare_ecma_strings (current_export_name_p, export_names_p->imex_name_p))
352425bb815Sopenharmony_ci          {
353425bb815Sopenharmony_ci            if (found)
354425bb815Sopenharmony_ci            {
355425bb815Sopenharmony_ci              /* This is an ambigous export. */
356425bb815Sopenharmony_ci              found_record.module_p = NULL;
357425bb815Sopenharmony_ci              found_record.name_p = NULL;
358425bb815Sopenharmony_ci              break;
359425bb815Sopenharmony_ci            }
360425bb815Sopenharmony_ci
361425bb815Sopenharmony_ci            /* The current module provides a direct binding for this export. */
362425bb815Sopenharmony_ci            found = true;
363425bb815Sopenharmony_ci            found_record.module_p = current_module_p;
364425bb815Sopenharmony_ci            found_record.name_p = export_names_p->local_name_p;
365425bb815Sopenharmony_ci            break;
366425bb815Sopenharmony_ci          }
367425bb815Sopenharmony_ci
368425bb815Sopenharmony_ci          export_names_p = export_names_p->next_p;
369425bb815Sopenharmony_ci        }
370425bb815Sopenharmony_ci      }
371425bb815Sopenharmony_ci
372425bb815Sopenharmony_ci      if (found)
373425bb815Sopenharmony_ci      {
374425bb815Sopenharmony_ci        /* We found a resolution for the current frame, return to the previous. */
375425bb815Sopenharmony_ci        ecma_module_resolve_stack_pop (&stack_p);
376425bb815Sopenharmony_ci        continue;
377425bb815Sopenharmony_ci      }
378425bb815Sopenharmony_ci
379425bb815Sopenharmony_ci      /* 15.2.1.16.3 / 5 */
380425bb815Sopenharmony_ci      ecma_module_node_t *indirect_export_p = context_p->indirect_exports_p;
381425bb815Sopenharmony_ci      while (indirect_export_p != NULL)
382425bb815Sopenharmony_ci      {
383425bb815Sopenharmony_ci        ecma_module_names_t *export_names_p = indirect_export_p->module_names_p;
384425bb815Sopenharmony_ci        while (export_names_p != NULL)
385425bb815Sopenharmony_ci        {
386425bb815Sopenharmony_ci          if (ecma_compare_ecma_strings (current_export_name_p, export_names_p->imex_name_p))
387425bb815Sopenharmony_ci          {
388425bb815Sopenharmony_ci            /* 5.2.1.16.3 / 5.a.iv */
389425bb815Sopenharmony_ci            ecma_module_resolve_stack_push (&stack_p,
390425bb815Sopenharmony_ci                                            indirect_export_p->module_request_p,
391425bb815Sopenharmony_ci                                            export_names_p->local_name_p);
392425bb815Sopenharmony_ci          }
393425bb815Sopenharmony_ci
394425bb815Sopenharmony_ci          export_names_p = export_names_p->next_p;
395425bb815Sopenharmony_ci        }
396425bb815Sopenharmony_ci
397425bb815Sopenharmony_ci        indirect_export_p = indirect_export_p->next_p;
398425bb815Sopenharmony_ci      }
399425bb815Sopenharmony_ci
400425bb815Sopenharmony_ci      /* We need to check whether the newly pushed indirect exports resolve to anything.
401425bb815Sopenharmony_ci       * Keep current frame in the stack, and continue from the topmost frame. */
402425bb815Sopenharmony_ci      continue;
403425bb815Sopenharmony_ci    } /* if (!current_frame_p->resolving) */
404425bb815Sopenharmony_ci
405425bb815Sopenharmony_ci    /* By the time we return to the current frame, the indirect exports will have finished resolving. */
406425bb815Sopenharmony_ci    if (found)
407425bb815Sopenharmony_ci    {
408425bb815Sopenharmony_ci      /* We found at least one export that satisfies the current request.
409425bb815Sopenharmony_ci       * Pop current frame, and return to the previous. */
410425bb815Sopenharmony_ci      ecma_module_resolve_stack_pop (&stack_p);
411425bb815Sopenharmony_ci      continue;
412425bb815Sopenharmony_ci    }
413425bb815Sopenharmony_ci
414425bb815Sopenharmony_ci    /* 15.2.1.16.3 / 6 */
415425bb815Sopenharmony_ci    if (ecma_compare_ecma_string_to_magic_id (current_export_name_p, LIT_MAGIC_STRING_DEFAULT))
416425bb815Sopenharmony_ci    {
417425bb815Sopenharmony_ci      ret_value = ecma_raise_syntax_error (ECMA_ERR_MSG ("No explicitly defined default export in module."));
418425bb815Sopenharmony_ci      break;
419425bb815Sopenharmony_ci    }
420425bb815Sopenharmony_ci
421425bb815Sopenharmony_ci    /* 15.2.1.16.3 / 7-8 */
422425bb815Sopenharmony_ci    if (!ecma_module_resolve_set_insert (&resolve_set_p,
423425bb815Sopenharmony_ci                                         current_module_p,
424425bb815Sopenharmony_ci                                         ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR)))
425425bb815Sopenharmony_ci    {
426425bb815Sopenharmony_ci      /* This is a circular import request. */
427425bb815Sopenharmony_ci      ecma_module_resolve_stack_pop (&stack_p);
428425bb815Sopenharmony_ci      continue;
429425bb815Sopenharmony_ci    }
430425bb815Sopenharmony_ci
431425bb815Sopenharmony_ci    /* Pop the current frame, we have nothing else to do here after the star export resolutions are queued. */
432425bb815Sopenharmony_ci    ecma_module_resolve_stack_pop (&stack_p);
433425bb815Sopenharmony_ci
434425bb815Sopenharmony_ci    /* 15.2.1.16.3 / 10 */
435425bb815Sopenharmony_ci    ecma_module_node_t *star_export_p = context_p->star_exports_p;
436425bb815Sopenharmony_ci    while (star_export_p != NULL)
437425bb815Sopenharmony_ci    {
438425bb815Sopenharmony_ci      JERRY_ASSERT (star_export_p->module_names_p == NULL);
439425bb815Sopenharmony_ci
440425bb815Sopenharmony_ci      /* 15.2.1.16.3 / 10.c */
441425bb815Sopenharmony_ci      ecma_module_resolve_stack_push (&stack_p, star_export_p->module_request_p, export_name_p);
442425bb815Sopenharmony_ci
443425bb815Sopenharmony_ci      star_export_p = star_export_p->next_p;
444425bb815Sopenharmony_ci    }
445425bb815Sopenharmony_ci  }
446425bb815Sopenharmony_ci
447425bb815Sopenharmony_ci  /* Clean up. */
448425bb815Sopenharmony_ci  ecma_module_resolve_set_cleanup (resolve_set_p);
449425bb815Sopenharmony_ci  while (stack_p)
450425bb815Sopenharmony_ci  {
451425bb815Sopenharmony_ci    ecma_module_resolve_stack_pop (&stack_p);
452425bb815Sopenharmony_ci  }
453425bb815Sopenharmony_ci
454425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (ret_value))
455425bb815Sopenharmony_ci  {
456425bb815Sopenharmony_ci    /* No default export was found */
457425bb815Sopenharmony_ci    return ret_value;
458425bb815Sopenharmony_ci  }
459425bb815Sopenharmony_ci
460425bb815Sopenharmony_ci  if (found)
461425bb815Sopenharmony_ci  {
462425bb815Sopenharmony_ci    *out_record_p = found_record;
463425bb815Sopenharmony_ci  }
464425bb815Sopenharmony_ci  else
465425bb815Sopenharmony_ci  {
466425bb815Sopenharmony_ci    ret_value = ecma_raise_syntax_error (ECMA_ERR_MSG ("Unexported or circular import request."));
467425bb815Sopenharmony_ci  }
468425bb815Sopenharmony_ci
469425bb815Sopenharmony_ci  return ret_value;
470425bb815Sopenharmony_ci} /* ecma_module_resolve_export */
471425bb815Sopenharmony_ci
472425bb815Sopenharmony_ci/**
473425bb815Sopenharmony_ci * Evaluates an EcmaScript module.
474425bb815Sopenharmony_ci *
475425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if an error occured
476425bb815Sopenharmony_ci *         ECMA_VALUE_EMPTY - otherwise
477425bb815Sopenharmony_ci */
478425bb815Sopenharmony_cistatic ecma_value_t
479425bb815Sopenharmony_ciecma_module_evaluate (ecma_module_t *module_p) /**< module */
480425bb815Sopenharmony_ci{
481425bb815Sopenharmony_ci  JERRY_ASSERT (module_p->state >= ECMA_MODULE_STATE_PARSED);
482425bb815Sopenharmony_ci
483425bb815Sopenharmony_ci  if (module_p->state >= ECMA_MODULE_STATE_EVALUATING)
484425bb815Sopenharmony_ci  {
485425bb815Sopenharmony_ci    return ECMA_VALUE_EMPTY;
486425bb815Sopenharmony_ci  }
487425bb815Sopenharmony_ci
488425bb815Sopenharmony_ci  module_p->state = ECMA_MODULE_STATE_EVALUATING;
489425bb815Sopenharmony_ci  module_p->scope_p = ecma_create_decl_lex_env (ecma_get_global_environment ());
490425bb815Sopenharmony_ci  module_p->context_p->parent_p = JERRY_CONTEXT (module_top_context_p);
491425bb815Sopenharmony_ci  JERRY_CONTEXT (module_top_context_p) = module_p->context_p;
492425bb815Sopenharmony_ci
493425bb815Sopenharmony_ci  ecma_value_t ret_value;
494425bb815Sopenharmony_ci  ret_value = vm_run_module (module_p->compiled_code_p,
495425bb815Sopenharmony_ci                             module_p->scope_p);
496425bb815Sopenharmony_ci
497425bb815Sopenharmony_ci  if (!ECMA_IS_VALUE_ERROR (ret_value))
498425bb815Sopenharmony_ci  {
499425bb815Sopenharmony_ci    ecma_free_value (ret_value);
500425bb815Sopenharmony_ci    ret_value = ECMA_VALUE_EMPTY;
501425bb815Sopenharmony_ci  }
502425bb815Sopenharmony_ci
503425bb815Sopenharmony_ci  JERRY_CONTEXT (module_top_context_p) = module_p->context_p->parent_p;
504425bb815Sopenharmony_ci
505425bb815Sopenharmony_ci  ecma_bytecode_deref (module_p->compiled_code_p);
506425bb815Sopenharmony_ci  module_p->state = ECMA_MODULE_STATE_EVALUATED;
507425bb815Sopenharmony_ci
508425bb815Sopenharmony_ci  return ret_value;
509425bb815Sopenharmony_ci} /* ecma_module_evaluate */
510425bb815Sopenharmony_ci
511425bb815Sopenharmony_ci/**
512425bb815Sopenharmony_ci * Resolves an export and adds it to the modules namespace object, if the export name is not yet handled.
513425bb815Sopenharmony_ci * Note: See 15.2.1.16.2 and 15.2.1.18
514425bb815Sopenharmony_ci *
515425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if an error occured
516425bb815Sopenharmony_ci *         ECMA_VALUE_EMPTY - otherwise
517425bb815Sopenharmony_ci */
518425bb815Sopenharmony_cistatic ecma_value_t
519425bb815Sopenharmony_ciecma_module_namespace_object_add_export_if_needed (ecma_module_t *module_p, /**< module */
520425bb815Sopenharmony_ci                                                   ecma_string_t *export_name_p) /**< export name */
521425bb815Sopenharmony_ci{
522425bb815Sopenharmony_ci  JERRY_ASSERT (module_p->namespace_object_p != NULL);
523425bb815Sopenharmony_ci  ecma_value_t result = ECMA_VALUE_EMPTY;
524425bb815Sopenharmony_ci
525425bb815Sopenharmony_ci  /* Default exports should not be added to the namespace object. */
526425bb815Sopenharmony_ci  if (ecma_compare_ecma_string_to_magic_id (export_name_p, LIT_MAGIC_STRING_DEFAULT)
527425bb815Sopenharmony_ci      || ecma_find_named_property (module_p->namespace_object_p, export_name_p) != NULL)
528425bb815Sopenharmony_ci  {
529425bb815Sopenharmony_ci    /* This export name has already been handled. */
530425bb815Sopenharmony_ci    return result;
531425bb815Sopenharmony_ci  }
532425bb815Sopenharmony_ci
533425bb815Sopenharmony_ci  ecma_module_record_t record;
534425bb815Sopenharmony_ci  result = ecma_module_resolve_export (module_p, export_name_p, &record);
535425bb815Sopenharmony_ci
536425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (result))
537425bb815Sopenharmony_ci  {
538425bb815Sopenharmony_ci    return result;
539425bb815Sopenharmony_ci  }
540425bb815Sopenharmony_ci
541425bb815Sopenharmony_ci  if (record.module_p == NULL)
542425bb815Sopenharmony_ci  {
543425bb815Sopenharmony_ci    /* 15.2.1.18 / 3.d.iv Skip ambiguous names. */
544425bb815Sopenharmony_ci    return result;
545425bb815Sopenharmony_ci  }
546425bb815Sopenharmony_ci
547425bb815Sopenharmony_ci  ecma_object_t *ref_base_lex_env_p;
548425bb815Sopenharmony_ci  ecma_value_t prop_value = ecma_op_get_value_lex_env_base (record.module_p->scope_p,
549425bb815Sopenharmony_ci                                                            &ref_base_lex_env_p,
550425bb815Sopenharmony_ci                                                            record.name_p);
551425bb815Sopenharmony_ci  ecma_property_t *new_property_p;
552425bb815Sopenharmony_ci  ecma_create_named_data_property (module_p->namespace_object_p,
553425bb815Sopenharmony_ci                                   export_name_p,
554425bb815Sopenharmony_ci                                   ECMA_PROPERTY_FIXED,
555425bb815Sopenharmony_ci                                   &new_property_p);
556425bb815Sopenharmony_ci
557425bb815Sopenharmony_ci  ecma_named_data_property_assign_value (module_p->namespace_object_p,
558425bb815Sopenharmony_ci                                         ECMA_PROPERTY_VALUE_PTR (new_property_p),
559425bb815Sopenharmony_ci                                         prop_value);
560425bb815Sopenharmony_ci
561425bb815Sopenharmony_ci  ecma_free_value (prop_value);
562425bb815Sopenharmony_ci  return result;
563425bb815Sopenharmony_ci} /* ecma_module_namespace_object_add_export_if_needed */
564425bb815Sopenharmony_ci
565425bb815Sopenharmony_ci/**
566425bb815Sopenharmony_ci * Creates a namespace object for a module.
567425bb815Sopenharmony_ci * Note: See 15.2.1.18
568425bb815Sopenharmony_ci *
569425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if an error occured
570425bb815Sopenharmony_ci *         ECMA_VALUE_EMPTY - otherwise
571425bb815Sopenharmony_ci */
572425bb815Sopenharmony_cistatic ecma_value_t
573425bb815Sopenharmony_ciecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
574425bb815Sopenharmony_ci{
575425bb815Sopenharmony_ci  ecma_value_t result = ECMA_VALUE_EMPTY;
576425bb815Sopenharmony_ci  if (module_p->namespace_object_p != NULL)
577425bb815Sopenharmony_ci  {
578425bb815Sopenharmony_ci    return result;
579425bb815Sopenharmony_ci  }
580425bb815Sopenharmony_ci
581425bb815Sopenharmony_ci  JERRY_ASSERT (module_p->state == ECMA_MODULE_STATE_EVALUATED);
582425bb815Sopenharmony_ci  ecma_module_resolve_set_t *resolve_set_p = NULL;
583425bb815Sopenharmony_ci  ecma_module_resolve_stack_t *stack_p = NULL;
584425bb815Sopenharmony_ci
585425bb815Sopenharmony_ci  module_p->namespace_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE),
586425bb815Sopenharmony_ci                                                     0,
587425bb815Sopenharmony_ci                                                     ECMA_OBJECT_TYPE_GENERAL);
588425bb815Sopenharmony_ci
589425bb815Sopenharmony_ci  ecma_module_resolve_stack_push (&stack_p, module_p, ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR));
590425bb815Sopenharmony_ci  while (stack_p != NULL)
591425bb815Sopenharmony_ci  {
592425bb815Sopenharmony_ci    ecma_module_resolve_stack_t *current_frame_p = stack_p;
593425bb815Sopenharmony_ci    ecma_module_t *current_module_p = current_frame_p->module_p;
594425bb815Sopenharmony_ci    ecma_module_context_t *context_p = current_module_p->context_p;
595425bb815Sopenharmony_ci
596425bb815Sopenharmony_ci    ecma_module_resolve_stack_pop (&stack_p);
597425bb815Sopenharmony_ci
598425bb815Sopenharmony_ci    /* 15.2.1.16.2 / 2-3 */
599425bb815Sopenharmony_ci    if (!ecma_module_resolve_set_insert (&resolve_set_p,
600425bb815Sopenharmony_ci                                         current_module_p,
601425bb815Sopenharmony_ci                                         ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR)))
602425bb815Sopenharmony_ci    {
603425bb815Sopenharmony_ci      /* Circular import. */
604425bb815Sopenharmony_ci      continue;
605425bb815Sopenharmony_ci    }
606425bb815Sopenharmony_ci
607425bb815Sopenharmony_ci    result = ecma_module_evaluate (current_module_p);
608425bb815Sopenharmony_ci
609425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (result))
610425bb815Sopenharmony_ci    {
611425bb815Sopenharmony_ci      break;
612425bb815Sopenharmony_ci    }
613425bb815Sopenharmony_ci
614425bb815Sopenharmony_ci    if (context_p->local_exports_p != NULL)
615425bb815Sopenharmony_ci    {
616425bb815Sopenharmony_ci      /* 15.2.1.16.2 / 5 */
617425bb815Sopenharmony_ci      JERRY_ASSERT (context_p->local_exports_p->next_p == NULL);
618425bb815Sopenharmony_ci      ecma_module_names_t *export_names_p = context_p->local_exports_p->module_names_p;
619425bb815Sopenharmony_ci      while (export_names_p != NULL && ecma_is_value_empty (result))
620425bb815Sopenharmony_ci      {
621425bb815Sopenharmony_ci        result = ecma_module_namespace_object_add_export_if_needed (module_p,
622425bb815Sopenharmony_ci                                                                    export_names_p->imex_name_p);
623425bb815Sopenharmony_ci        export_names_p = export_names_p->next_p;
624425bb815Sopenharmony_ci      }
625425bb815Sopenharmony_ci    }
626425bb815Sopenharmony_ci
627425bb815Sopenharmony_ci    /* 15.2.1.16.2 / 6 */
628425bb815Sopenharmony_ci    ecma_module_node_t *indirect_export_p = context_p->indirect_exports_p;
629425bb815Sopenharmony_ci    while (indirect_export_p != NULL && ecma_is_value_empty (result))
630425bb815Sopenharmony_ci    {
631425bb815Sopenharmony_ci      ecma_module_names_t *export_names_p = indirect_export_p->module_names_p;
632425bb815Sopenharmony_ci      while (export_names_p != NULL && ecma_is_value_empty (result))
633425bb815Sopenharmony_ci      {
634425bb815Sopenharmony_ci        result = ecma_module_namespace_object_add_export_if_needed (module_p,
635425bb815Sopenharmony_ci                                                                    export_names_p->imex_name_p);
636425bb815Sopenharmony_ci        export_names_p = export_names_p->next_p;
637425bb815Sopenharmony_ci      }
638425bb815Sopenharmony_ci      indirect_export_p = indirect_export_p->next_p;
639425bb815Sopenharmony_ci    }
640425bb815Sopenharmony_ci
641425bb815Sopenharmony_ci    /* 15.2.1.16.2 / 7 */
642425bb815Sopenharmony_ci    ecma_module_node_t *star_export_p = context_p->star_exports_p;
643425bb815Sopenharmony_ci    while (star_export_p != NULL && ecma_is_value_empty (result))
644425bb815Sopenharmony_ci    {
645425bb815Sopenharmony_ci      JERRY_ASSERT (star_export_p->module_names_p == NULL);
646425bb815Sopenharmony_ci
647425bb815Sopenharmony_ci      /* 15.2.1.16.3/10.c */
648425bb815Sopenharmony_ci      ecma_module_resolve_stack_push (&stack_p,
649425bb815Sopenharmony_ci                                      star_export_p->module_request_p,
650425bb815Sopenharmony_ci                                      ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR));
651425bb815Sopenharmony_ci
652425bb815Sopenharmony_ci      star_export_p = star_export_p->next_p;
653425bb815Sopenharmony_ci    }
654425bb815Sopenharmony_ci  }
655425bb815Sopenharmony_ci
656425bb815Sopenharmony_ci  /* Clean up. */
657425bb815Sopenharmony_ci  ecma_module_resolve_set_cleanup (resolve_set_p);
658425bb815Sopenharmony_ci  while (stack_p)
659425bb815Sopenharmony_ci  {
660425bb815Sopenharmony_ci    ecma_module_resolve_stack_pop (&stack_p);
661425bb815Sopenharmony_ci  }
662425bb815Sopenharmony_ci
663425bb815Sopenharmony_ci  return result;
664425bb815Sopenharmony_ci} /* ecma_module_create_namespace_object */
665425bb815Sopenharmony_ci
666425bb815Sopenharmony_ci/**
667425bb815Sopenharmony_ci * Connects imported values to the current context.
668425bb815Sopenharmony_ci *
669425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if an error occured
670425bb815Sopenharmony_ci *         ECMA_VALUE_EMPTY - otherwise
671425bb815Sopenharmony_ci */
672425bb815Sopenharmony_cistatic ecma_value_t
673425bb815Sopenharmony_ciecma_module_connect_imports (void)
674425bb815Sopenharmony_ci{
675425bb815Sopenharmony_ci  ecma_module_context_t *current_context_p = JERRY_CONTEXT (module_top_context_p);
676425bb815Sopenharmony_ci
677425bb815Sopenharmony_ci  ecma_object_t *local_env_p = current_context_p->module_p->scope_p;
678425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_is_lexical_environment (local_env_p));
679425bb815Sopenharmony_ci
680425bb815Sopenharmony_ci  ecma_module_node_t *import_node_p = current_context_p->imports_p;
681425bb815Sopenharmony_ci
682425bb815Sopenharmony_ci  /* Check that the imported bindings don't exist yet. */
683425bb815Sopenharmony_ci  while (import_node_p != NULL)
684425bb815Sopenharmony_ci  {
685425bb815Sopenharmony_ci    ecma_module_names_t *import_names_p = import_node_p->module_names_p;
686425bb815Sopenharmony_ci
687425bb815Sopenharmony_ci    while (import_names_p != NULL)
688425bb815Sopenharmony_ci    {
689425bb815Sopenharmony_ci      ecma_object_t *lex_env_p = local_env_p;
690425bb815Sopenharmony_ci      ecma_property_t *binding_p = NULL;
691425bb815Sopenharmony_ci
692425bb815Sopenharmony_ci      if (lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK)
693425bb815Sopenharmony_ci      {
694425bb815Sopenharmony_ci        binding_p = ecma_find_named_property (lex_env_p, import_names_p->local_name_p);
695425bb815Sopenharmony_ci
696425bb815Sopenharmony_ci        JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL);
697425bb815Sopenharmony_ci        lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
698425bb815Sopenharmony_ci      }
699425bb815Sopenharmony_ci
700425bb815Sopenharmony_ci      if (binding_p != NULL)
701425bb815Sopenharmony_ci      {
702425bb815Sopenharmony_ci        return ecma_raise_syntax_error (ECMA_ERR_MSG ("Imported binding shadows local variable."));
703425bb815Sopenharmony_ci      }
704425bb815Sopenharmony_ci
705425bb815Sopenharmony_ci      ecma_value_t status = ecma_op_has_binding (lex_env_p, import_names_p->local_name_p);
706425bb815Sopenharmony_ci
707425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
708425bb815Sopenharmony_ci      if (ECMA_IS_VALUE_ERROR (status))
709425bb815Sopenharmony_ci      {
710425bb815Sopenharmony_ci        return status;
711425bb815Sopenharmony_ci      }
712425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
713425bb815Sopenharmony_ci
714425bb815Sopenharmony_ci      if (ecma_is_value_true (status))
715425bb815Sopenharmony_ci      {
716425bb815Sopenharmony_ci        return ecma_raise_syntax_error (ECMA_ERR_MSG ("Imported binding shadows local variable."));
717425bb815Sopenharmony_ci      }
718425bb815Sopenharmony_ci
719425bb815Sopenharmony_ci      import_names_p = import_names_p->next_p;
720425bb815Sopenharmony_ci    }
721425bb815Sopenharmony_ci
722425bb815Sopenharmony_ci    import_node_p = import_node_p->next_p;
723425bb815Sopenharmony_ci  }
724425bb815Sopenharmony_ci
725425bb815Sopenharmony_ci  import_node_p = current_context_p->imports_p;
726425bb815Sopenharmony_ci
727425bb815Sopenharmony_ci  /* Resolve imports and create local bindings. */
728425bb815Sopenharmony_ci  while (import_node_p != NULL)
729425bb815Sopenharmony_ci  {
730425bb815Sopenharmony_ci    ecma_value_t result = ecma_module_evaluate (import_node_p->module_request_p);
731425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (result))
732425bb815Sopenharmony_ci    {
733425bb815Sopenharmony_ci      return result;
734425bb815Sopenharmony_ci    }
735425bb815Sopenharmony_ci
736425bb815Sopenharmony_ci    ecma_module_names_t *import_names_p = import_node_p->module_names_p;
737425bb815Sopenharmony_ci    while (import_names_p != NULL)
738425bb815Sopenharmony_ci    {
739425bb815Sopenharmony_ci      const bool is_namespace_import = ecma_compare_ecma_string_to_magic_id (import_names_p->imex_name_p,
740425bb815Sopenharmony_ci                                                                             LIT_MAGIC_STRING_ASTERIX_CHAR);
741425bb815Sopenharmony_ci
742425bb815Sopenharmony_ci      if (is_namespace_import)
743425bb815Sopenharmony_ci      {
744425bb815Sopenharmony_ci        result = ecma_module_create_namespace_object (import_node_p->module_request_p);
745425bb815Sopenharmony_ci        if (ECMA_IS_VALUE_ERROR (result))
746425bb815Sopenharmony_ci        {
747425bb815Sopenharmony_ci          return result;
748425bb815Sopenharmony_ci        }
749425bb815Sopenharmony_ci
750425bb815Sopenharmony_ci        ecma_op_create_mutable_binding (local_env_p, import_names_p->local_name_p, true /* is_deletable */);
751425bb815Sopenharmony_ci        ecma_op_set_mutable_binding (local_env_p,
752425bb815Sopenharmony_ci                                     import_names_p->local_name_p,
753425bb815Sopenharmony_ci                                     ecma_make_object_value (import_node_p->module_request_p->namespace_object_p),
754425bb815Sopenharmony_ci                                     false /* is_strict */);
755425bb815Sopenharmony_ci      }
756425bb815Sopenharmony_ci      else /* !is_namespace_import */
757425bb815Sopenharmony_ci      {
758425bb815Sopenharmony_ci        ecma_module_record_t record;
759425bb815Sopenharmony_ci        result = ecma_module_resolve_export (import_node_p->module_request_p, import_names_p->imex_name_p, &record);
760425bb815Sopenharmony_ci
761425bb815Sopenharmony_ci        if (ECMA_IS_VALUE_ERROR (result))
762425bb815Sopenharmony_ci        {
763425bb815Sopenharmony_ci          return result;
764425bb815Sopenharmony_ci        }
765425bb815Sopenharmony_ci
766425bb815Sopenharmony_ci        if (record.module_p == NULL)
767425bb815Sopenharmony_ci        {
768425bb815Sopenharmony_ci          return ecma_raise_syntax_error (ECMA_ERR_MSG ("Ambiguous import request."));
769425bb815Sopenharmony_ci        }
770425bb815Sopenharmony_ci
771425bb815Sopenharmony_ci        if (record.module_p->state == ECMA_MODULE_STATE_NATIVE)
772425bb815Sopenharmony_ci        {
773425bb815Sopenharmony_ci          ecma_object_t *object_p = record.module_p->namespace_object_p;
774425bb815Sopenharmony_ci          ecma_value_t prop_value = ecma_op_object_find_own (ecma_make_object_value (object_p),
775425bb815Sopenharmony_ci                                                             object_p,
776425bb815Sopenharmony_ci                                                             record.name_p);
777425bb815Sopenharmony_ci          JERRY_ASSERT (ecma_is_value_found (prop_value));
778425bb815Sopenharmony_ci
779425bb815Sopenharmony_ci          ecma_op_create_mutable_binding (local_env_p, import_names_p->local_name_p, true /* is_deletable */);
780425bb815Sopenharmony_ci          ecma_op_set_mutable_binding (local_env_p,
781425bb815Sopenharmony_ci                                       import_names_p->local_name_p,
782425bb815Sopenharmony_ci                                       prop_value,
783425bb815Sopenharmony_ci                                       false /* is_strict */);
784425bb815Sopenharmony_ci
785425bb815Sopenharmony_ci          ecma_free_value (prop_value);
786425bb815Sopenharmony_ci        }
787425bb815Sopenharmony_ci        else
788425bb815Sopenharmony_ci        {
789425bb815Sopenharmony_ci          result = ecma_module_evaluate (record.module_p);
790425bb815Sopenharmony_ci
791425bb815Sopenharmony_ci          if (ECMA_IS_VALUE_ERROR (result))
792425bb815Sopenharmony_ci          {
793425bb815Sopenharmony_ci            return result;
794425bb815Sopenharmony_ci          }
795425bb815Sopenharmony_ci
796425bb815Sopenharmony_ci          ecma_object_t *ref_base_lex_env_p;
797425bb815Sopenharmony_ci          ecma_value_t prop_value = ecma_op_get_value_lex_env_base (record.module_p->scope_p,
798425bb815Sopenharmony_ci                                                                    &ref_base_lex_env_p,
799425bb815Sopenharmony_ci                                                                    record.name_p);
800425bb815Sopenharmony_ci
801425bb815Sopenharmony_ci          ecma_op_create_mutable_binding (local_env_p, import_names_p->local_name_p, true /* is_deletable */);
802425bb815Sopenharmony_ci          ecma_op_set_mutable_binding (local_env_p,
803425bb815Sopenharmony_ci                                       import_names_p->local_name_p,
804425bb815Sopenharmony_ci                                       prop_value,
805425bb815Sopenharmony_ci                                       false /* is_strict */);
806425bb815Sopenharmony_ci
807425bb815Sopenharmony_ci          ecma_free_value (prop_value);
808425bb815Sopenharmony_ci        }
809425bb815Sopenharmony_ci      }
810425bb815Sopenharmony_ci
811425bb815Sopenharmony_ci      import_names_p = import_names_p->next_p;
812425bb815Sopenharmony_ci    }
813425bb815Sopenharmony_ci
814425bb815Sopenharmony_ci    import_node_p = import_node_p->next_p;
815425bb815Sopenharmony_ci  }
816425bb815Sopenharmony_ci
817425bb815Sopenharmony_ci  return ECMA_VALUE_EMPTY;
818425bb815Sopenharmony_ci} /* ecma_module_connect_imports */
819425bb815Sopenharmony_ci
820425bb815Sopenharmony_ci/**
821425bb815Sopenharmony_ci * Initialize the current module by creating the local binding for the imported variables
822425bb815Sopenharmony_ci * and verifying indirect exports.
823425bb815Sopenharmony_ci *
824425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if an error occured
825425bb815Sopenharmony_ci *         ECMA_VALUE_EMPTY - otherwise
826425bb815Sopenharmony_ci */
827425bb815Sopenharmony_ciecma_value_t
828425bb815Sopenharmony_ciecma_module_initialize_current (void)
829425bb815Sopenharmony_ci{
830425bb815Sopenharmony_ci  ecma_value_t ret_value = ecma_module_connect_imports ();
831425bb815Sopenharmony_ci
832425bb815Sopenharmony_ci  if (ecma_is_value_empty (ret_value))
833425bb815Sopenharmony_ci  {
834425bb815Sopenharmony_ci    ret_value = ecma_module_check_indirect_exports ();
835425bb815Sopenharmony_ci  }
836425bb815Sopenharmony_ci
837425bb815Sopenharmony_ci  return ret_value;
838425bb815Sopenharmony_ci} /* ecma_module_initialize_current */
839425bb815Sopenharmony_ci
840425bb815Sopenharmony_ci/**
841425bb815Sopenharmony_ci * Parses an EcmaScript module.
842425bb815Sopenharmony_ci *
843425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if an error occured
844425bb815Sopenharmony_ci *         ECMA_VALUE_EMPTY - otherwise
845425bb815Sopenharmony_ci */
846425bb815Sopenharmony_cistatic jerry_value_t
847425bb815Sopenharmony_ciecma_module_parse (ecma_module_t *module_p) /**< module */
848425bb815Sopenharmony_ci{
849425bb815Sopenharmony_ci  if (module_p->state >= ECMA_MODULE_STATE_PARSING)
850425bb815Sopenharmony_ci  {
851425bb815Sopenharmony_ci    return ECMA_VALUE_EMPTY;
852425bb815Sopenharmony_ci  }
853425bb815Sopenharmony_ci
854425bb815Sopenharmony_ci  module_p->state = ECMA_MODULE_STATE_PARSING;
855425bb815Sopenharmony_ci  module_p->context_p = ecma_module_create_module_context ();
856425bb815Sopenharmony_ci
857425bb815Sopenharmony_ci  lit_utf8_size_t module_path_size = ecma_string_get_size (module_p->path_p);
858425bb815Sopenharmony_ci  lit_utf8_byte_t *module_path_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (module_path_size + 1);
859425bb815Sopenharmony_ci
860425bb815Sopenharmony_ci  lit_utf8_size_t module_path_utf8_size;
861425bb815Sopenharmony_ci  module_path_utf8_size = ecma_string_copy_to_utf8_buffer (module_p->path_p,
862425bb815Sopenharmony_ci                                                           module_path_p,
863425bb815Sopenharmony_ci                                                           module_path_size);
864425bb815Sopenharmony_ci  module_path_p[module_path_utf8_size] = LIT_CHAR_NULL;
865425bb815Sopenharmony_ci
866425bb815Sopenharmony_ci  size_t source_size = 0;
867425bb815Sopenharmony_ci  uint8_t *source_p = jerry_port_read_source ((const char *) module_path_p, &source_size);
868425bb815Sopenharmony_ci  jmem_heap_free_block (module_path_p, module_path_size + 1);
869425bb815Sopenharmony_ci
870425bb815Sopenharmony_ci  if (source_p == NULL)
871425bb815Sopenharmony_ci  {
872425bb815Sopenharmony_ci    return ecma_raise_syntax_error (ECMA_ERR_MSG ("File not found."));
873425bb815Sopenharmony_ci  }
874425bb815Sopenharmony_ci
875425bb815Sopenharmony_ci  module_p->context_p->module_p = module_p;
876425bb815Sopenharmony_ci  module_p->context_p->parent_p = JERRY_CONTEXT (module_top_context_p);
877425bb815Sopenharmony_ci  JERRY_CONTEXT (module_top_context_p) = module_p->context_p;
878425bb815Sopenharmony_ci
879425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER)
880425bb815Sopenharmony_ci  if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
881425bb815Sopenharmony_ci  {
882425bb815Sopenharmony_ci    jerry_debugger_send_string (JERRY_DEBUGGER_SOURCE_CODE_NAME,
883425bb815Sopenharmony_ci                                JERRY_DEBUGGER_NO_SUBTYPE,
884425bb815Sopenharmony_ci                                module_path_p,
885425bb815Sopenharmony_ci                                module_path_size - 1);
886425bb815Sopenharmony_ci  }
887425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER) */
888425bb815Sopenharmony_ci
889425bb815Sopenharmony_ci  JERRY_CONTEXT (resource_name) = ecma_make_string_value (module_p->path_p);
890425bb815Sopenharmony_ci
891425bb815Sopenharmony_ci  ecma_compiled_code_t *bytecode_data_p;
892425bb815Sopenharmony_ci  ecma_value_t ret_value = parser_parse_script (NULL,
893425bb815Sopenharmony_ci                                                0,
894425bb815Sopenharmony_ci                                                (jerry_char_t *) source_p,
895425bb815Sopenharmony_ci                                                source_size,
896425bb815Sopenharmony_ci                                                ECMA_PARSE_STRICT_MODE | ECMA_PARSE_MODULE,
897425bb815Sopenharmony_ci                                                &bytecode_data_p);
898425bb815Sopenharmony_ci
899425bb815Sopenharmony_ci  JERRY_CONTEXT (module_top_context_p) = module_p->context_p->parent_p;
900425bb815Sopenharmony_ci
901425bb815Sopenharmony_ci  jerry_port_release_source (source_p);
902425bb815Sopenharmony_ci
903425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (ret_value))
904425bb815Sopenharmony_ci  {
905425bb815Sopenharmony_ci    return ret_value;
906425bb815Sopenharmony_ci  }
907425bb815Sopenharmony_ci
908425bb815Sopenharmony_ci  ecma_free_value (ret_value);
909425bb815Sopenharmony_ci
910425bb815Sopenharmony_ci  module_p->compiled_code_p = bytecode_data_p;
911425bb815Sopenharmony_ci  module_p->state = ECMA_MODULE_STATE_PARSED;
912425bb815Sopenharmony_ci
913425bb815Sopenharmony_ci  return ECMA_VALUE_EMPTY;
914425bb815Sopenharmony_ci} /* ecma_module_parse */
915425bb815Sopenharmony_ci
916425bb815Sopenharmony_ci/**
917425bb815Sopenharmony_ci * Parses all referenced modules.
918425bb815Sopenharmony_ci *
919425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if an error occured
920425bb815Sopenharmony_ci *         ECMA_VALUE_EMPTY - otherwise
921425bb815Sopenharmony_ci */
922425bb815Sopenharmony_ciecma_value_t
923425bb815Sopenharmony_ciecma_module_parse_modules (void)
924425bb815Sopenharmony_ci{
925425bb815Sopenharmony_ci  ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
926425bb815Sopenharmony_ci
927425bb815Sopenharmony_ci  while (current_p != NULL)
928425bb815Sopenharmony_ci  {
929425bb815Sopenharmony_ci    ecma_value_t ret_value = ecma_module_parse (current_p);
930425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (ret_value))
931425bb815Sopenharmony_ci    {
932425bb815Sopenharmony_ci      return ret_value;
933425bb815Sopenharmony_ci    }
934425bb815Sopenharmony_ci
935425bb815Sopenharmony_ci    JERRY_ASSERT (ecma_is_value_empty (ret_value));
936425bb815Sopenharmony_ci    current_p = current_p->next_p;
937425bb815Sopenharmony_ci  }
938425bb815Sopenharmony_ci
939425bb815Sopenharmony_ci  return ECMA_VALUE_EMPTY;
940425bb815Sopenharmony_ci} /* ecma_module_parse_modules */
941425bb815Sopenharmony_ci
942425bb815Sopenharmony_ci/**
943425bb815Sopenharmony_ci * Checks if indirect exports in the current context are resolvable.
944425bb815Sopenharmony_ci * Note: See 15.2.1.16.4 / 9.
945425bb815Sopenharmony_ci *
946425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if an error occured
947425bb815Sopenharmony_ci *         ECMA_VALUE_EMPTY - otherwise
948425bb815Sopenharmony_ci */
949425bb815Sopenharmony_ciecma_value_t
950425bb815Sopenharmony_ciecma_module_check_indirect_exports (void)
951425bb815Sopenharmony_ci{
952425bb815Sopenharmony_ci  ecma_module_node_t *indirect_export_p = JERRY_CONTEXT (module_top_context_p)->indirect_exports_p;
953425bb815Sopenharmony_ci  while (indirect_export_p != NULL)
954425bb815Sopenharmony_ci  {
955425bb815Sopenharmony_ci    ecma_module_names_t *name_p = indirect_export_p->module_names_p;
956425bb815Sopenharmony_ci    while (name_p != NULL)
957425bb815Sopenharmony_ci    {
958425bb815Sopenharmony_ci      ecma_module_record_t record;
959425bb815Sopenharmony_ci      ecma_value_t result = ecma_module_resolve_export (indirect_export_p->module_request_p,
960425bb815Sopenharmony_ci                                                        name_p->local_name_p,
961425bb815Sopenharmony_ci                                                        &record);
962425bb815Sopenharmony_ci
963425bb815Sopenharmony_ci      if (ECMA_IS_VALUE_ERROR (result))
964425bb815Sopenharmony_ci      {
965425bb815Sopenharmony_ci        return result;
966425bb815Sopenharmony_ci      }
967425bb815Sopenharmony_ci
968425bb815Sopenharmony_ci      if (record.module_p == NULL)
969425bb815Sopenharmony_ci      {
970425bb815Sopenharmony_ci        return ecma_raise_syntax_error (ECMA_ERR_MSG ("Ambiguous indirect export request."));
971425bb815Sopenharmony_ci      }
972425bb815Sopenharmony_ci
973425bb815Sopenharmony_ci      name_p = name_p->next_p;
974425bb815Sopenharmony_ci    }
975425bb815Sopenharmony_ci
976425bb815Sopenharmony_ci    indirect_export_p = indirect_export_p->next_p;
977425bb815Sopenharmony_ci  }
978425bb815Sopenharmony_ci
979425bb815Sopenharmony_ci  return ECMA_VALUE_EMPTY;
980425bb815Sopenharmony_ci} /* ecma_module_check_indirect_exports */
981425bb815Sopenharmony_ci
982425bb815Sopenharmony_ci/**
983425bb815Sopenharmony_ci * Cleans up a list of module names.
984425bb815Sopenharmony_ci */
985425bb815Sopenharmony_cistatic void
986425bb815Sopenharmony_ciecma_module_release_module_names (ecma_module_names_t *module_name_p) /**< first module name */
987425bb815Sopenharmony_ci{
988425bb815Sopenharmony_ci  while (module_name_p != NULL)
989425bb815Sopenharmony_ci  {
990425bb815Sopenharmony_ci    ecma_module_names_t *next_p = module_name_p->next_p;
991425bb815Sopenharmony_ci
992425bb815Sopenharmony_ci    ecma_deref_ecma_string (module_name_p->imex_name_p);
993425bb815Sopenharmony_ci    ecma_deref_ecma_string (module_name_p->local_name_p);
994425bb815Sopenharmony_ci    jmem_heap_free_block (module_name_p, sizeof (ecma_module_names_t));
995425bb815Sopenharmony_ci
996425bb815Sopenharmony_ci    module_name_p = next_p;
997425bb815Sopenharmony_ci  }
998425bb815Sopenharmony_ci} /* ecma_module_release_module_names */
999425bb815Sopenharmony_ci
1000425bb815Sopenharmony_ci/**
1001425bb815Sopenharmony_ci * Cleans up a list of module nodes.
1002425bb815Sopenharmony_ci */
1003425bb815Sopenharmony_civoid
1004425bb815Sopenharmony_ciecma_module_release_module_nodes (ecma_module_node_t *module_node_p) /**< first module node */
1005425bb815Sopenharmony_ci{
1006425bb815Sopenharmony_ci  while (module_node_p != NULL)
1007425bb815Sopenharmony_ci  {
1008425bb815Sopenharmony_ci    ecma_module_node_t *next_p = module_node_p->next_p;
1009425bb815Sopenharmony_ci
1010425bb815Sopenharmony_ci    ecma_module_release_module_names (module_node_p->module_names_p);
1011425bb815Sopenharmony_ci    jmem_heap_free_block (module_node_p, sizeof (ecma_module_node_t));
1012425bb815Sopenharmony_ci
1013425bb815Sopenharmony_ci    module_node_p = next_p;
1014425bb815Sopenharmony_ci  }
1015425bb815Sopenharmony_ci} /* ecma_module_release_module_nodes */
1016425bb815Sopenharmony_ci
1017425bb815Sopenharmony_ci/**
1018425bb815Sopenharmony_ci * Cleans up a module context.
1019425bb815Sopenharmony_ci */
1020425bb815Sopenharmony_cistatic void
1021425bb815Sopenharmony_ciecma_module_release_module_context (ecma_module_context_t *module_context_p) /**< modle context */
1022425bb815Sopenharmony_ci{
1023425bb815Sopenharmony_ci  ecma_module_release_module_nodes (module_context_p->imports_p);
1024425bb815Sopenharmony_ci  ecma_module_release_module_nodes (module_context_p->local_exports_p);
1025425bb815Sopenharmony_ci  ecma_module_release_module_nodes (module_context_p->indirect_exports_p);
1026425bb815Sopenharmony_ci  ecma_module_release_module_nodes (module_context_p->star_exports_p);
1027425bb815Sopenharmony_ci
1028425bb815Sopenharmony_ci  jmem_heap_free_block (module_context_p, sizeof (ecma_module_context_t));
1029425bb815Sopenharmony_ci} /* ecma_module_release_module_context */
1030425bb815Sopenharmony_ci
1031425bb815Sopenharmony_ci/**
1032425bb815Sopenharmony_ci * Cleans up a module structure.
1033425bb815Sopenharmony_ci */
1034425bb815Sopenharmony_cistatic void
1035425bb815Sopenharmony_ciecma_module_release_module (ecma_module_t *module_p) /**< module */
1036425bb815Sopenharmony_ci{
1037425bb815Sopenharmony_ci  ecma_deref_ecma_string (module_p->path_p);
1038425bb815Sopenharmony_ci
1039425bb815Sopenharmony_ci  if (module_p->namespace_object_p != NULL)
1040425bb815Sopenharmony_ci  {
1041425bb815Sopenharmony_ci    ecma_deref_object (module_p->namespace_object_p);
1042425bb815Sopenharmony_ci  }
1043425bb815Sopenharmony_ci
1044425bb815Sopenharmony_ci  if (module_p->state == ECMA_MODULE_STATE_NATIVE)
1045425bb815Sopenharmony_ci  {
1046425bb815Sopenharmony_ci    goto finished;
1047425bb815Sopenharmony_ci  }
1048425bb815Sopenharmony_ci
1049425bb815Sopenharmony_ci  if (module_p->state >= ECMA_MODULE_STATE_PARSING)
1050425bb815Sopenharmony_ci  {
1051425bb815Sopenharmony_ci    ecma_module_release_module_context (module_p->context_p);
1052425bb815Sopenharmony_ci  }
1053425bb815Sopenharmony_ci
1054425bb815Sopenharmony_ci  if (module_p->state >= ECMA_MODULE_STATE_EVALUATING
1055425bb815Sopenharmony_ci      && module_p->scope_p != NULL)
1056425bb815Sopenharmony_ci  {
1057425bb815Sopenharmony_ci    ecma_deref_object (module_p->scope_p);
1058425bb815Sopenharmony_ci  }
1059425bb815Sopenharmony_ci
1060425bb815Sopenharmony_ci  if (module_p->state >= ECMA_MODULE_STATE_PARSED
1061425bb815Sopenharmony_ci      && module_p->state < ECMA_MODULE_STATE_EVALUATED)
1062425bb815Sopenharmony_ci  {
1063425bb815Sopenharmony_ci    ecma_bytecode_deref (module_p->compiled_code_p);
1064425bb815Sopenharmony_ci  }
1065425bb815Sopenharmony_ci
1066425bb815Sopenharmony_cifinished:
1067425bb815Sopenharmony_ci  jmem_heap_free_block (module_p, sizeof (ecma_module_t));
1068425bb815Sopenharmony_ci} /* ecma_module_release_module */
1069425bb815Sopenharmony_ci
1070425bb815Sopenharmony_ci/**
1071425bb815Sopenharmony_ci * Cleans up all modules if the current context is the root context.
1072425bb815Sopenharmony_ci */
1073425bb815Sopenharmony_civoid
1074425bb815Sopenharmony_ciecma_module_cleanup (void)
1075425bb815Sopenharmony_ci{
1076425bb815Sopenharmony_ci  ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
1077425bb815Sopenharmony_ci  while (current_p != NULL)
1078425bb815Sopenharmony_ci  {
1079425bb815Sopenharmony_ci    ecma_module_t *next_p = current_p->next_p;
1080425bb815Sopenharmony_ci    ecma_module_release_module (current_p);
1081425bb815Sopenharmony_ci    current_p = next_p;
1082425bb815Sopenharmony_ci  }
1083425bb815Sopenharmony_ci
1084425bb815Sopenharmony_ci  JERRY_CONTEXT (ecma_modules_p) = NULL;
1085425bb815Sopenharmony_ci  JERRY_CONTEXT (module_top_context_p) = NULL;
1086425bb815Sopenharmony_ci} /* ecma_module_cleanup */
1087425bb815Sopenharmony_ci
1088425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
1089