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