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 "js-parser-internal.h" 17425bb815Sopenharmony_ci 18425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 19425bb815Sopenharmony_ci#include "jcontext.h" 20425bb815Sopenharmony_ci#include "jerryscript-port.h" 21425bb815Sopenharmony_ci 22425bb815Sopenharmony_ci#include "ecma-function-object.h" 23425bb815Sopenharmony_ci#include "ecma-gc.h" 24425bb815Sopenharmony_ci#include "ecma-globals.h" 25425bb815Sopenharmony_ci#include "ecma-helpers.h" 26425bb815Sopenharmony_ci#include "ecma-lex-env.h" 27425bb815Sopenharmony_ci#include "ecma-module.h" 28425bb815Sopenharmony_ci 29425bb815Sopenharmony_ci/** 30425bb815Sopenharmony_ci * Description of "*default*" literal string. 31425bb815Sopenharmony_ci */ 32425bb815Sopenharmony_ciconst lexer_lit_location_t lexer_default_literal = 33425bb815Sopenharmony_ci{ 34425bb815Sopenharmony_ci (const uint8_t *) "*default*", 9, LEXER_IDENT_LITERAL, false 35425bb815Sopenharmony_ci}; 36425bb815Sopenharmony_ci 37425bb815Sopenharmony_ci/** 38425bb815Sopenharmony_ci * Check for duplicated imported binding names. 39425bb815Sopenharmony_ci * 40425bb815Sopenharmony_ci * @return true - if the given name is a duplicate 41425bb815Sopenharmony_ci * false - otherwise 42425bb815Sopenharmony_ci */ 43425bb815Sopenharmony_cibool 44425bb815Sopenharmony_ciparser_module_check_duplicate_import (parser_context_t *context_p, /**< parser context */ 45425bb815Sopenharmony_ci ecma_string_t *local_name_p) /**< newly imported name */ 46425bb815Sopenharmony_ci{ 47425bb815Sopenharmony_ci ecma_module_names_t *module_names_p = context_p->module_current_node_p->module_names_p; 48425bb815Sopenharmony_ci while (module_names_p != NULL) 49425bb815Sopenharmony_ci { 50425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (module_names_p->local_name_p, local_name_p)) 51425bb815Sopenharmony_ci { 52425bb815Sopenharmony_ci return true; 53425bb815Sopenharmony_ci } 54425bb815Sopenharmony_ci 55425bb815Sopenharmony_ci module_names_p = module_names_p->next_p; 56425bb815Sopenharmony_ci } 57425bb815Sopenharmony_ci 58425bb815Sopenharmony_ci ecma_module_node_t *module_node_p = JERRY_CONTEXT (module_top_context_p)->imports_p; 59425bb815Sopenharmony_ci while (module_node_p != NULL) 60425bb815Sopenharmony_ci { 61425bb815Sopenharmony_ci module_names_p = module_node_p->module_names_p; 62425bb815Sopenharmony_ci 63425bb815Sopenharmony_ci while (module_names_p != NULL) 64425bb815Sopenharmony_ci { 65425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (module_names_p->local_name_p, local_name_p)) 66425bb815Sopenharmony_ci { 67425bb815Sopenharmony_ci return true; 68425bb815Sopenharmony_ci } 69425bb815Sopenharmony_ci 70425bb815Sopenharmony_ci module_names_p = module_names_p->next_p; 71425bb815Sopenharmony_ci } 72425bb815Sopenharmony_ci 73425bb815Sopenharmony_ci module_node_p = module_node_p->next_p; 74425bb815Sopenharmony_ci } 75425bb815Sopenharmony_ci 76425bb815Sopenharmony_ci return false; 77425bb815Sopenharmony_ci} /* parser_module_check_duplicate_import */ 78425bb815Sopenharmony_ci 79425bb815Sopenharmony_ci/** 80425bb815Sopenharmony_ci * Append an identifier to the exported bindings. 81425bb815Sopenharmony_ci */ 82425bb815Sopenharmony_civoid 83425bb815Sopenharmony_ciparser_module_append_export_name (parser_context_t *context_p) /**< parser context */ 84425bb815Sopenharmony_ci{ 85425bb815Sopenharmony_ci if (!(context_p->status_flags & PARSER_MODULE_STORE_IDENT)) 86425bb815Sopenharmony_ci { 87425bb815Sopenharmony_ci return; 88425bb815Sopenharmony_ci } 89425bb815Sopenharmony_ci 90425bb815Sopenharmony_ci context_p->module_identifier_lit_p = context_p->lit_object.literal_p; 91425bb815Sopenharmony_ci 92425bb815Sopenharmony_ci ecma_string_t *name_p = ecma_new_ecma_string_from_utf8 (context_p->lit_object.literal_p->u.char_p, 93425bb815Sopenharmony_ci context_p->lit_object.literal_p->prop.length); 94425bb815Sopenharmony_ci 95425bb815Sopenharmony_ci if (parser_module_check_duplicate_export (context_p, name_p)) 96425bb815Sopenharmony_ci { 97425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 98425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_DUPLICATED_EXPORT_IDENTIFIER); 99425bb815Sopenharmony_ci } 100425bb815Sopenharmony_ci 101425bb815Sopenharmony_ci parser_module_add_names_to_node (context_p, 102425bb815Sopenharmony_ci name_p, 103425bb815Sopenharmony_ci name_p); 104425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 105425bb815Sopenharmony_ci} /* parser_module_append_export_name */ 106425bb815Sopenharmony_ci 107425bb815Sopenharmony_ci/** 108425bb815Sopenharmony_ci * Check for duplicated exported bindings. 109425bb815Sopenharmony_ci * @return - true - if the exported name is a duplicate 110425bb815Sopenharmony_ci * false - otherwise 111425bb815Sopenharmony_ci */ 112425bb815Sopenharmony_cibool 113425bb815Sopenharmony_ciparser_module_check_duplicate_export (parser_context_t *context_p, /**< parser context */ 114425bb815Sopenharmony_ci ecma_string_t *export_name_p) /**< exported identifier */ 115425bb815Sopenharmony_ci{ 116425bb815Sopenharmony_ci /* We have to check in the currently constructed node, as well as all of the already added nodes. */ 117425bb815Sopenharmony_ci ecma_module_names_t *current_names_p = context_p->module_current_node_p->module_names_p; 118425bb815Sopenharmony_ci while (current_names_p != NULL) 119425bb815Sopenharmony_ci { 120425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (current_names_p->imex_name_p, export_name_p)) 121425bb815Sopenharmony_ci { 122425bb815Sopenharmony_ci return true; 123425bb815Sopenharmony_ci } 124425bb815Sopenharmony_ci current_names_p = current_names_p->next_p; 125425bb815Sopenharmony_ci } 126425bb815Sopenharmony_ci 127425bb815Sopenharmony_ci ecma_module_node_t *export_node_p = JERRY_CONTEXT (module_top_context_p)->local_exports_p; 128425bb815Sopenharmony_ci if (export_node_p != NULL) 129425bb815Sopenharmony_ci { 130425bb815Sopenharmony_ci JERRY_ASSERT (export_node_p->next_p == NULL); 131425bb815Sopenharmony_ci ecma_module_names_t *name_p = export_node_p->module_names_p; 132425bb815Sopenharmony_ci 133425bb815Sopenharmony_ci while (name_p != NULL) 134425bb815Sopenharmony_ci { 135425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (name_p->imex_name_p, export_name_p)) 136425bb815Sopenharmony_ci { 137425bb815Sopenharmony_ci return true; 138425bb815Sopenharmony_ci } 139425bb815Sopenharmony_ci 140425bb815Sopenharmony_ci name_p = name_p->next_p; 141425bb815Sopenharmony_ci } 142425bb815Sopenharmony_ci } 143425bb815Sopenharmony_ci 144425bb815Sopenharmony_ci export_node_p = JERRY_CONTEXT (module_top_context_p)->indirect_exports_p; 145425bb815Sopenharmony_ci while (export_node_p != NULL) 146425bb815Sopenharmony_ci { 147425bb815Sopenharmony_ci ecma_module_names_t *name_p = export_node_p->module_names_p; 148425bb815Sopenharmony_ci 149425bb815Sopenharmony_ci while (name_p != NULL) 150425bb815Sopenharmony_ci { 151425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (name_p->imex_name_p, export_name_p)) 152425bb815Sopenharmony_ci { 153425bb815Sopenharmony_ci return true; 154425bb815Sopenharmony_ci } 155425bb815Sopenharmony_ci 156425bb815Sopenharmony_ci name_p = name_p->next_p; 157425bb815Sopenharmony_ci } 158425bb815Sopenharmony_ci 159425bb815Sopenharmony_ci export_node_p = export_node_p->next_p; 160425bb815Sopenharmony_ci } 161425bb815Sopenharmony_ci 162425bb815Sopenharmony_ci /* Star exports don't have any names associated with them, so no need to check those. */ 163425bb815Sopenharmony_ci return false; 164425bb815Sopenharmony_ci} /* parser_module_check_duplicate_export */ 165425bb815Sopenharmony_ci 166425bb815Sopenharmony_ci/** 167425bb815Sopenharmony_ci * Add export node to parser context. 168425bb815Sopenharmony_ci */ 169425bb815Sopenharmony_civoid 170425bb815Sopenharmony_ciparser_module_add_export_node_to_context (parser_context_t *context_p) /**< parser context */ 171425bb815Sopenharmony_ci{ 172425bb815Sopenharmony_ci ecma_module_node_t *module_node_p = context_p->module_current_node_p; 173425bb815Sopenharmony_ci context_p->module_current_node_p = NULL; 174425bb815Sopenharmony_ci ecma_module_node_t **export_list_p; 175425bb815Sopenharmony_ci 176425bb815Sopenharmony_ci /* Check which list we should add it to. */ 177425bb815Sopenharmony_ci if (module_node_p->module_request_p) 178425bb815Sopenharmony_ci { 179425bb815Sopenharmony_ci /* If the export node has a module request, that means it's either an indirect export, or a star export. */ 180425bb815Sopenharmony_ci if (!module_node_p->module_names_p) 181425bb815Sopenharmony_ci { 182425bb815Sopenharmony_ci /* If there are no names in the node, then it's a star export. */ 183425bb815Sopenharmony_ci export_list_p = &(JERRY_CONTEXT (module_top_context_p)->star_exports_p); 184425bb815Sopenharmony_ci } 185425bb815Sopenharmony_ci else 186425bb815Sopenharmony_ci { 187425bb815Sopenharmony_ci export_list_p = &(JERRY_CONTEXT (module_top_context_p)->indirect_exports_p); 188425bb815Sopenharmony_ci } 189425bb815Sopenharmony_ci } 190425bb815Sopenharmony_ci else 191425bb815Sopenharmony_ci { 192425bb815Sopenharmony_ci /* If there is no module request, then it's a local export. */ 193425bb815Sopenharmony_ci export_list_p = &(JERRY_CONTEXT (module_top_context_p)->local_exports_p); 194425bb815Sopenharmony_ci } 195425bb815Sopenharmony_ci 196425bb815Sopenharmony_ci /* Check if we have a node with the same module request, append to it if we do. */ 197425bb815Sopenharmony_ci ecma_module_node_t *stored_exports_p = *export_list_p; 198425bb815Sopenharmony_ci while (stored_exports_p != NULL) 199425bb815Sopenharmony_ci { 200425bb815Sopenharmony_ci if (stored_exports_p->module_request_p == module_node_p->module_request_p) 201425bb815Sopenharmony_ci { 202425bb815Sopenharmony_ci ecma_module_names_t *module_names_p = module_node_p->module_names_p; 203425bb815Sopenharmony_ci 204425bb815Sopenharmony_ci if (module_names_p != NULL) 205425bb815Sopenharmony_ci { 206425bb815Sopenharmony_ci while (module_names_p->next_p != NULL) 207425bb815Sopenharmony_ci { 208425bb815Sopenharmony_ci module_names_p = module_names_p->next_p; 209425bb815Sopenharmony_ci } 210425bb815Sopenharmony_ci 211425bb815Sopenharmony_ci module_names_p->next_p = stored_exports_p->module_names_p; 212425bb815Sopenharmony_ci stored_exports_p->module_names_p = module_node_p->module_names_p; 213425bb815Sopenharmony_ci module_node_p->module_names_p = NULL; 214425bb815Sopenharmony_ci } 215425bb815Sopenharmony_ci 216425bb815Sopenharmony_ci ecma_module_release_module_nodes (module_node_p); 217425bb815Sopenharmony_ci return; 218425bb815Sopenharmony_ci } 219425bb815Sopenharmony_ci 220425bb815Sopenharmony_ci stored_exports_p = stored_exports_p->next_p; 221425bb815Sopenharmony_ci } 222425bb815Sopenharmony_ci 223425bb815Sopenharmony_ci module_node_p->next_p = *export_list_p; 224425bb815Sopenharmony_ci *export_list_p = module_node_p; 225425bb815Sopenharmony_ci} /* parser_module_add_export_node_to_context */ 226425bb815Sopenharmony_ci 227425bb815Sopenharmony_ci/** 228425bb815Sopenharmony_ci * Add import node to parser context. 229425bb815Sopenharmony_ci */ 230425bb815Sopenharmony_civoid 231425bb815Sopenharmony_ciparser_module_add_import_node_to_context (parser_context_t *context_p) /**< parser context */ 232425bb815Sopenharmony_ci{ 233425bb815Sopenharmony_ci ecma_module_node_t *module_node_p = context_p->module_current_node_p; 234425bb815Sopenharmony_ci context_p->module_current_node_p = NULL; 235425bb815Sopenharmony_ci ecma_module_node_t *stored_imports = JERRY_CONTEXT (module_top_context_p)->imports_p; 236425bb815Sopenharmony_ci 237425bb815Sopenharmony_ci /* Check if we have a node with the same module request, append to it if we do. */ 238425bb815Sopenharmony_ci while (stored_imports != NULL) 239425bb815Sopenharmony_ci { 240425bb815Sopenharmony_ci if (stored_imports->module_request_p == module_node_p->module_request_p) 241425bb815Sopenharmony_ci { 242425bb815Sopenharmony_ci ecma_module_names_t *module_names_p = module_node_p->module_names_p; 243425bb815Sopenharmony_ci 244425bb815Sopenharmony_ci if (module_names_p != NULL) 245425bb815Sopenharmony_ci { 246425bb815Sopenharmony_ci while (module_names_p->next_p != NULL) 247425bb815Sopenharmony_ci { 248425bb815Sopenharmony_ci module_names_p = module_names_p->next_p; 249425bb815Sopenharmony_ci } 250425bb815Sopenharmony_ci 251425bb815Sopenharmony_ci module_names_p->next_p = stored_imports->module_names_p; 252425bb815Sopenharmony_ci stored_imports->module_names_p = module_node_p->module_names_p; 253425bb815Sopenharmony_ci module_node_p->module_names_p = NULL; 254425bb815Sopenharmony_ci } 255425bb815Sopenharmony_ci 256425bb815Sopenharmony_ci ecma_module_release_module_nodes (module_node_p); 257425bb815Sopenharmony_ci return; 258425bb815Sopenharmony_ci } 259425bb815Sopenharmony_ci 260425bb815Sopenharmony_ci stored_imports = stored_imports->next_p; 261425bb815Sopenharmony_ci } 262425bb815Sopenharmony_ci 263425bb815Sopenharmony_ci module_node_p->next_p = JERRY_CONTEXT (module_top_context_p)->imports_p; 264425bb815Sopenharmony_ci JERRY_CONTEXT (module_top_context_p)->imports_p = module_node_p; 265425bb815Sopenharmony_ci} /* parser_module_add_import_node_to_context */ 266425bb815Sopenharmony_ci 267425bb815Sopenharmony_ci/** 268425bb815Sopenharmony_ci * Add module names to current module node. 269425bb815Sopenharmony_ci */ 270425bb815Sopenharmony_civoid 271425bb815Sopenharmony_ciparser_module_add_names_to_node (parser_context_t *context_p, /**< parser context */ 272425bb815Sopenharmony_ci ecma_string_t *imex_name_p, /**< import/export name */ 273425bb815Sopenharmony_ci ecma_string_t *local_name_p) /**< local name */ 274425bb815Sopenharmony_ci{ 275425bb815Sopenharmony_ci ecma_module_names_t *new_names_p = (ecma_module_names_t *) parser_malloc (context_p, 276425bb815Sopenharmony_ci sizeof (ecma_module_names_t)); 277425bb815Sopenharmony_ci memset (new_names_p, 0, sizeof (ecma_module_names_t)); 278425bb815Sopenharmony_ci 279425bb815Sopenharmony_ci ecma_module_node_t *module_node_p = context_p->module_current_node_p; 280425bb815Sopenharmony_ci new_names_p->next_p = module_node_p->module_names_p; 281425bb815Sopenharmony_ci module_node_p->module_names_p = new_names_p; 282425bb815Sopenharmony_ci 283425bb815Sopenharmony_ci JERRY_ASSERT (imex_name_p != NULL); 284425bb815Sopenharmony_ci ecma_ref_ecma_string (imex_name_p); 285425bb815Sopenharmony_ci new_names_p->imex_name_p = imex_name_p; 286425bb815Sopenharmony_ci 287425bb815Sopenharmony_ci JERRY_ASSERT (local_name_p != NULL); 288425bb815Sopenharmony_ci ecma_ref_ecma_string (local_name_p); 289425bb815Sopenharmony_ci new_names_p->local_name_p = local_name_p; 290425bb815Sopenharmony_ci} /* parser_module_add_names_to_node */ 291425bb815Sopenharmony_ci 292425bb815Sopenharmony_ci/** 293425bb815Sopenharmony_ci * Create module context if needed. 294425bb815Sopenharmony_ci */ 295425bb815Sopenharmony_civoid 296425bb815Sopenharmony_ciparser_module_context_init (void) 297425bb815Sopenharmony_ci{ 298425bb815Sopenharmony_ci if (JERRY_CONTEXT (module_top_context_p) == NULL) 299425bb815Sopenharmony_ci { 300425bb815Sopenharmony_ci ecma_module_context_t *module_context_p; 301425bb815Sopenharmony_ci module_context_p = (ecma_module_context_t *) jmem_heap_alloc_block (sizeof (ecma_module_context_t)); 302425bb815Sopenharmony_ci memset (module_context_p, 0, sizeof (ecma_module_context_t)); 303425bb815Sopenharmony_ci JERRY_CONTEXT (module_top_context_p) = module_context_p; 304425bb815Sopenharmony_ci 305425bb815Sopenharmony_ci ecma_string_t *path_str_p = ecma_get_string_from_value (JERRY_CONTEXT (resource_name)); 306425bb815Sopenharmony_ci 307425bb815Sopenharmony_ci lit_utf8_size_t path_str_size; 308425bb815Sopenharmony_ci uint8_t flags = ECMA_STRING_FLAG_EMPTY; 309425bb815Sopenharmony_ci 310425bb815Sopenharmony_ci const lit_utf8_byte_t *path_str_chars_p = ecma_string_get_chars (path_str_p, 311425bb815Sopenharmony_ci &path_str_size, 312425bb815Sopenharmony_ci NULL, 313425bb815Sopenharmony_ci NULL, 314425bb815Sopenharmony_ci &flags); 315425bb815Sopenharmony_ci 316425bb815Sopenharmony_ci ecma_string_t *path_p = ecma_module_create_normalized_path (path_str_chars_p, 317425bb815Sopenharmony_ci (prop_length_t) path_str_size); 318425bb815Sopenharmony_ci 319425bb815Sopenharmony_ci if (path_p == NULL) 320425bb815Sopenharmony_ci { 321425bb815Sopenharmony_ci ecma_ref_ecma_string (path_str_p); 322425bb815Sopenharmony_ci path_p = path_str_p; 323425bb815Sopenharmony_ci } 324425bb815Sopenharmony_ci 325425bb815Sopenharmony_ci ecma_module_t *module_p = ecma_module_find_or_create_module (path_p); 326425bb815Sopenharmony_ci 327425bb815Sopenharmony_ci module_p->state = ECMA_MODULE_STATE_EVALUATED; 328425bb815Sopenharmony_ci /* The lexical scope of the root module does not exist yet. */ 329425bb815Sopenharmony_ci module_p->scope_p = NULL; 330425bb815Sopenharmony_ci 331425bb815Sopenharmony_ci module_p->context_p = module_context_p; 332425bb815Sopenharmony_ci module_context_p->module_p = module_p; 333425bb815Sopenharmony_ci } 334425bb815Sopenharmony_ci} /* parser_module_context_init */ 335425bb815Sopenharmony_ci 336425bb815Sopenharmony_ci/** 337425bb815Sopenharmony_ci * Create a permanent import/export node from a template node. 338425bb815Sopenharmony_ci * @return - the copy of the template if the second parameter is not NULL. 339425bb815Sopenharmony_ci * - otherwise: an empty node. 340425bb815Sopenharmony_ci */ 341425bb815Sopenharmony_ciecma_module_node_t * 342425bb815Sopenharmony_ciparser_module_create_module_node (parser_context_t *context_p) /**< parser context */ 343425bb815Sopenharmony_ci{ 344425bb815Sopenharmony_ci ecma_module_node_t *node_p = (ecma_module_node_t *) parser_malloc (context_p, sizeof (ecma_module_node_t)); 345425bb815Sopenharmony_ci memset (node_p, 0, sizeof (ecma_module_node_t)); 346425bb815Sopenharmony_ci 347425bb815Sopenharmony_ci return node_p; 348425bb815Sopenharmony_ci} /* parser_module_create_module_node */ 349425bb815Sopenharmony_ci 350425bb815Sopenharmony_ci/** 351425bb815Sopenharmony_ci * Parse an ExportClause. 352425bb815Sopenharmony_ci */ 353425bb815Sopenharmony_civoid 354425bb815Sopenharmony_ciparser_module_parse_export_clause (parser_context_t *context_p) /**< parser context */ 355425bb815Sopenharmony_ci{ 356425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE); 357425bb815Sopenharmony_ci lexer_next_token (context_p); 358425bb815Sopenharmony_ci 359425bb815Sopenharmony_ci while (true) 360425bb815Sopenharmony_ci { 361425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_BRACE) 362425bb815Sopenharmony_ci { 363425bb815Sopenharmony_ci lexer_next_token (context_p); 364425bb815Sopenharmony_ci break; 365425bb815Sopenharmony_ci } 366425bb815Sopenharmony_ci 367425bb815Sopenharmony_ci /* 15.2.3.1 The referenced binding cannot be a reserved word. */ 368425bb815Sopenharmony_ci if (context_p->token.type != LEXER_LITERAL 369425bb815Sopenharmony_ci || context_p->token.lit_location.type != LEXER_IDENT_LITERAL 370425bb815Sopenharmony_ci || context_p->token.keyword_type >= LEXER_FIRST_FUTURE_STRICT_RESERVED_WORD) 371425bb815Sopenharmony_ci { 372425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); 373425bb815Sopenharmony_ci } 374425bb815Sopenharmony_ci 375425bb815Sopenharmony_ci ecma_string_t *export_name_p = NULL; 376425bb815Sopenharmony_ci ecma_string_t *local_name_p = NULL; 377425bb815Sopenharmony_ci 378425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_NEW_IDENT_LITERAL); 379425bb815Sopenharmony_ci 380425bb815Sopenharmony_ci uint16_t local_name_index = context_p->lit_object.index; 381425bb815Sopenharmony_ci uint16_t export_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS; 382425bb815Sopenharmony_ci 383425bb815Sopenharmony_ci lexer_next_token (context_p); 384425bb815Sopenharmony_ci if (lexer_token_is_identifier (context_p, "as", 2)) 385425bb815Sopenharmony_ci { 386425bb815Sopenharmony_ci lexer_next_token (context_p); 387425bb815Sopenharmony_ci 388425bb815Sopenharmony_ci if (context_p->token.type != LEXER_LITERAL 389425bb815Sopenharmony_ci || context_p->token.lit_location.type != LEXER_IDENT_LITERAL) 390425bb815Sopenharmony_ci { 391425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); 392425bb815Sopenharmony_ci } 393425bb815Sopenharmony_ci 394425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_NEW_IDENT_LITERAL); 395425bb815Sopenharmony_ci 396425bb815Sopenharmony_ci export_name_index = context_p->lit_object.index; 397425bb815Sopenharmony_ci 398425bb815Sopenharmony_ci lexer_next_token (context_p); 399425bb815Sopenharmony_ci } 400425bb815Sopenharmony_ci 401425bb815Sopenharmony_ci lexer_literal_t *literal_p = PARSER_GET_LITERAL (local_name_index); 402425bb815Sopenharmony_ci local_name_p = ecma_new_ecma_string_from_utf8 (literal_p->u.char_p, literal_p->prop.length); 403425bb815Sopenharmony_ci 404425bb815Sopenharmony_ci if (export_name_index != PARSER_MAXIMUM_NUMBER_OF_LITERALS) 405425bb815Sopenharmony_ci { 406425bb815Sopenharmony_ci lexer_literal_t *as_literal_p = PARSER_GET_LITERAL (export_name_index); 407425bb815Sopenharmony_ci export_name_p = ecma_new_ecma_string_from_utf8 (as_literal_p->u.char_p, as_literal_p->prop.length); 408425bb815Sopenharmony_ci } 409425bb815Sopenharmony_ci else 410425bb815Sopenharmony_ci { 411425bb815Sopenharmony_ci export_name_p = local_name_p; 412425bb815Sopenharmony_ci ecma_ref_ecma_string (local_name_p); 413425bb815Sopenharmony_ci } 414425bb815Sopenharmony_ci 415425bb815Sopenharmony_ci if (parser_module_check_duplicate_export (context_p, export_name_p)) 416425bb815Sopenharmony_ci { 417425bb815Sopenharmony_ci ecma_deref_ecma_string (local_name_p); 418425bb815Sopenharmony_ci ecma_deref_ecma_string (export_name_p); 419425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_DUPLICATED_EXPORT_IDENTIFIER); 420425bb815Sopenharmony_ci } 421425bb815Sopenharmony_ci 422425bb815Sopenharmony_ci parser_module_add_names_to_node (context_p, export_name_p, local_name_p); 423425bb815Sopenharmony_ci ecma_deref_ecma_string (local_name_p); 424425bb815Sopenharmony_ci ecma_deref_ecma_string (export_name_p); 425425bb815Sopenharmony_ci 426425bb815Sopenharmony_ci if (context_p->token.type != LEXER_COMMA 427425bb815Sopenharmony_ci && context_p->token.type != LEXER_RIGHT_BRACE) 428425bb815Sopenharmony_ci { 429425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_COMMA_EXPECTED); 430425bb815Sopenharmony_ci } 431425bb815Sopenharmony_ci else if (context_p->token.type == LEXER_COMMA) 432425bb815Sopenharmony_ci { 433425bb815Sopenharmony_ci lexer_next_token (context_p); 434425bb815Sopenharmony_ci } 435425bb815Sopenharmony_ci 436425bb815Sopenharmony_ci if (lexer_token_is_identifier (context_p, "from", 4)) 437425bb815Sopenharmony_ci { 438425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED); 439425bb815Sopenharmony_ci } 440425bb815Sopenharmony_ci } 441425bb815Sopenharmony_ci} /* parser_module_parse_export_clause */ 442425bb815Sopenharmony_ci 443425bb815Sopenharmony_ci/** 444425bb815Sopenharmony_ci * Parse an ImportClause 445425bb815Sopenharmony_ci */ 446425bb815Sopenharmony_civoid 447425bb815Sopenharmony_ciparser_module_parse_import_clause (parser_context_t *context_p) /**< parser context */ 448425bb815Sopenharmony_ci{ 449425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE); 450425bb815Sopenharmony_ci lexer_next_token (context_p); 451425bb815Sopenharmony_ci 452425bb815Sopenharmony_ci while (true) 453425bb815Sopenharmony_ci { 454425bb815Sopenharmony_ci if (context_p->token.type == LEXER_RIGHT_BRACE) 455425bb815Sopenharmony_ci { 456425bb815Sopenharmony_ci lexer_next_token (context_p); 457425bb815Sopenharmony_ci break; 458425bb815Sopenharmony_ci } 459425bb815Sopenharmony_ci 460425bb815Sopenharmony_ci if (context_p->token.type != LEXER_LITERAL 461425bb815Sopenharmony_ci || context_p->token.lit_location.type != LEXER_IDENT_LITERAL) 462425bb815Sopenharmony_ci { 463425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); 464425bb815Sopenharmony_ci } 465425bb815Sopenharmony_ci 466425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 467425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->source_p == context_p->source_p) 468425bb815Sopenharmony_ci { 469425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED); 470425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED); 471425bb815Sopenharmony_ci } 472425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 473425bb815Sopenharmony_ci 474425bb815Sopenharmony_ci ecma_string_t *import_name_p = NULL; 475425bb815Sopenharmony_ci ecma_string_t *local_name_p = NULL; 476425bb815Sopenharmony_ci 477425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_NEW_IDENT_LITERAL); 478425bb815Sopenharmony_ci 479425bb815Sopenharmony_ci uint16_t import_name_index = context_p->lit_object.index; 480425bb815Sopenharmony_ci uint16_t local_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS; 481425bb815Sopenharmony_ci 482425bb815Sopenharmony_ci lexer_next_token (context_p); 483425bb815Sopenharmony_ci if (lexer_token_is_identifier (context_p, "as", 2)) 484425bb815Sopenharmony_ci { 485425bb815Sopenharmony_ci lexer_next_token (context_p); 486425bb815Sopenharmony_ci 487425bb815Sopenharmony_ci if (context_p->token.type != LEXER_LITERAL 488425bb815Sopenharmony_ci || context_p->token.lit_location.type != LEXER_IDENT_LITERAL) 489425bb815Sopenharmony_ci { 490425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); 491425bb815Sopenharmony_ci } 492425bb815Sopenharmony_ci 493425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 494425bb815Sopenharmony_ci if (context_p->next_scanner_info_p->source_p == context_p->source_p) 495425bb815Sopenharmony_ci { 496425bb815Sopenharmony_ci JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED); 497425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED); 498425bb815Sopenharmony_ci } 499425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 500425bb815Sopenharmony_ci 501425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_NEW_IDENT_LITERAL); 502425bb815Sopenharmony_ci 503425bb815Sopenharmony_ci local_name_index = context_p->lit_object.index; 504425bb815Sopenharmony_ci 505425bb815Sopenharmony_ci lexer_next_token (context_p); 506425bb815Sopenharmony_ci } 507425bb815Sopenharmony_ci 508425bb815Sopenharmony_ci lexer_literal_t *literal_p = PARSER_GET_LITERAL (import_name_index); 509425bb815Sopenharmony_ci import_name_p = ecma_new_ecma_string_from_utf8 (literal_p->u.char_p, literal_p->prop.length); 510425bb815Sopenharmony_ci 511425bb815Sopenharmony_ci if (local_name_index != PARSER_MAXIMUM_NUMBER_OF_LITERALS) 512425bb815Sopenharmony_ci { 513425bb815Sopenharmony_ci lexer_literal_t *as_literal_p = PARSER_GET_LITERAL (local_name_index); 514425bb815Sopenharmony_ci local_name_p = ecma_new_ecma_string_from_utf8 (as_literal_p->u.char_p, as_literal_p->prop.length); 515425bb815Sopenharmony_ci } 516425bb815Sopenharmony_ci else 517425bb815Sopenharmony_ci { 518425bb815Sopenharmony_ci local_name_p = import_name_p; 519425bb815Sopenharmony_ci ecma_ref_ecma_string (local_name_p); 520425bb815Sopenharmony_ci } 521425bb815Sopenharmony_ci 522425bb815Sopenharmony_ci if (parser_module_check_duplicate_import (context_p, local_name_p)) 523425bb815Sopenharmony_ci { 524425bb815Sopenharmony_ci ecma_deref_ecma_string (local_name_p); 525425bb815Sopenharmony_ci ecma_deref_ecma_string (import_name_p); 526425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_DUPLICATED_IMPORT_BINDING); 527425bb815Sopenharmony_ci } 528425bb815Sopenharmony_ci 529425bb815Sopenharmony_ci parser_module_add_names_to_node (context_p, import_name_p, local_name_p); 530425bb815Sopenharmony_ci ecma_deref_ecma_string (local_name_p); 531425bb815Sopenharmony_ci ecma_deref_ecma_string (import_name_p); 532425bb815Sopenharmony_ci 533425bb815Sopenharmony_ci if (context_p->token.type != LEXER_COMMA 534425bb815Sopenharmony_ci && (context_p->token.type != LEXER_RIGHT_BRACE)) 535425bb815Sopenharmony_ci { 536425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_COMMA_EXPECTED); 537425bb815Sopenharmony_ci } 538425bb815Sopenharmony_ci else if (context_p->token.type == LEXER_COMMA) 539425bb815Sopenharmony_ci { 540425bb815Sopenharmony_ci lexer_next_token (context_p); 541425bb815Sopenharmony_ci } 542425bb815Sopenharmony_ci 543425bb815Sopenharmony_ci if (lexer_token_is_identifier (context_p, "from", 4)) 544425bb815Sopenharmony_ci { 545425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED); 546425bb815Sopenharmony_ci } 547425bb815Sopenharmony_ci } 548425bb815Sopenharmony_ci} /* parser_module_parse_import_clause */ 549425bb815Sopenharmony_ci 550425bb815Sopenharmony_ci/** 551425bb815Sopenharmony_ci * Raises parser error if the import or export statement is not in the global scope. 552425bb815Sopenharmony_ci */ 553425bb815Sopenharmony_civoid 554425bb815Sopenharmony_ciparser_module_check_request_place (parser_context_t *context_p) /**< parser context */ 555425bb815Sopenharmony_ci{ 556425bb815Sopenharmony_ci if (context_p->last_context_p != NULL 557425bb815Sopenharmony_ci || context_p->stack_top_uint8 != 0 558425bb815Sopenharmony_ci || (context_p->status_flags & PARSER_IS_FUNCTION) 559425bb815Sopenharmony_ci || (context_p->global_status_flags & ECMA_PARSE_EVAL)) 560425bb815Sopenharmony_ci { 561425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_MODULE_UNEXPECTED); 562425bb815Sopenharmony_ci } 563425bb815Sopenharmony_ci} /* parser_module_check_request_place */ 564425bb815Sopenharmony_ci 565425bb815Sopenharmony_ci/** 566425bb815Sopenharmony_ci * Handle module specifier at the end of the import / export statement. 567425bb815Sopenharmony_ci */ 568425bb815Sopenharmony_civoid 569425bb815Sopenharmony_ciparser_module_handle_module_specifier (parser_context_t *context_p) /**< parser context */ 570425bb815Sopenharmony_ci{ 571425bb815Sopenharmony_ci ecma_module_node_t *module_node_p = context_p->module_current_node_p; 572425bb815Sopenharmony_ci if (context_p->token.type != LEXER_LITERAL 573425bb815Sopenharmony_ci || context_p->token.lit_location.type != LEXER_STRING_LITERAL 574425bb815Sopenharmony_ci || context_p->token.lit_location.length == 0) 575425bb815Sopenharmony_ci { 576425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_STRING_EXPECTED); 577425bb815Sopenharmony_ci } 578425bb815Sopenharmony_ci 579425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL); 580425bb815Sopenharmony_ci 581425bb815Sopenharmony_ci ecma_string_t *name_p = ecma_new_ecma_string_from_utf8 (context_p->lit_object.literal_p->u.char_p, 582425bb815Sopenharmony_ci context_p->lit_object.literal_p->prop.length); 583425bb815Sopenharmony_ci 584425bb815Sopenharmony_ci ecma_module_t *module_p = ecma_module_find_module (name_p); 585425bb815Sopenharmony_ci if (module_p) 586425bb815Sopenharmony_ci { 587425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 588425bb815Sopenharmony_ci goto module_found; 589425bb815Sopenharmony_ci } 590425bb815Sopenharmony_ci 591425bb815Sopenharmony_ci ecma_value_t native = jerry_port_get_native_module (ecma_make_string_value (name_p)); 592425bb815Sopenharmony_ci 593425bb815Sopenharmony_ci if (!ecma_is_value_undefined (native)) 594425bb815Sopenharmony_ci { 595425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_object (native)); 596425bb815Sopenharmony_ci ecma_object_t *module_object_p = ecma_get_object_from_value (native); 597425bb815Sopenharmony_ci 598425bb815Sopenharmony_ci module_p = ecma_module_create_native_module (name_p, module_object_p); 599425bb815Sopenharmony_ci goto module_found; 600425bb815Sopenharmony_ci } 601425bb815Sopenharmony_ci 602425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 603425bb815Sopenharmony_ci ecma_string_t *path_p = ecma_module_create_normalized_path (context_p->lit_object.literal_p->u.char_p, 604425bb815Sopenharmony_ci context_p->lit_object.literal_p->prop.length); 605425bb815Sopenharmony_ci 606425bb815Sopenharmony_ci if (path_p == NULL) 607425bb815Sopenharmony_ci { 608425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_FILE_NOT_FOUND); 609425bb815Sopenharmony_ci } 610425bb815Sopenharmony_ci 611425bb815Sopenharmony_ci module_p = ecma_module_find_or_create_module (path_p); 612425bb815Sopenharmony_ci 613425bb815Sopenharmony_cimodule_found: 614425bb815Sopenharmony_ci module_node_p->module_request_p = module_p; 615425bb815Sopenharmony_ci lexer_next_token (context_p); 616425bb815Sopenharmony_ci} /* parser_module_handle_module_specifier */ 617425bb815Sopenharmony_ci 618425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 619