diff --git a/jerry-core/parser/js/js-parser-internal.h b/jerry-core/parser/js/js-parser-internal.h index 09c50c69e..9e9202378 100644 --- a/jerry-core/parser/js/js-parser-internal.h +++ b/jerry-core/parser/js/js-parser-internal.h @@ -828,6 +828,7 @@ uint16_t scanner_decode_map_to (parser_scope_stack_t *stack_item_p); uint16_t scanner_save_literal (parser_context_t *context_p, uint16_t ident_index); bool scanner_literal_is_const_reg (parser_context_t *context_p, uint16_t literal_index); bool scanner_literal_is_created (parser_context_t *context_p, uint16_t literal_index); +bool scanner_literal_exists (parser_context_t *context_p, uint16_t literal_index); #endif /* ENABLED (JERRY_ESNEXT) */ void scanner_scan_all (parser_context_t *context_p, const uint8_t *arg_list_p, const uint8_t *arg_list_end_p, diff --git a/jerry-core/parser/js/js-parser-module.c b/jerry-core/parser/js/js-parser-module.c index 861ae4d71..26cba3fa8 100644 --- a/jerry-core/parser/js/js-parser-module.c +++ b/jerry-core/parser/js/js-parser-module.c @@ -353,6 +353,15 @@ parser_module_create_module_node (parser_context_t *context_p) /**< parser conte void parser_module_parse_export_clause (parser_context_t *context_p) /**< parser context */ { + bool has_module_specifier = false; + + if (context_p->source_p == context_p->next_scanner_info_p->source_p) + { + has_module_specifier = true; + JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_EXPORT_MODULE_SPECIFIER); + scanner_release_next (context_p, sizeof (scanner_info_t)); + } + JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE); lexer_next_token (context_p); @@ -377,6 +386,12 @@ parser_module_parse_export_clause (parser_context_t *context_p) /**< parser cont lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_NEW_IDENT_LITERAL); + if (!has_module_specifier + && !scanner_literal_exists (context_p, context_p->lit_object.index)) + { + parser_raise_error (context_p, PARSER_ERR_EXPORT_NOT_DEFINED); + } + uint16_t local_name_index = context_p->lit_object.index; uint16_t export_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS; diff --git a/jerry-core/parser/js/js-parser-util.c b/jerry-core/parser/js/js-parser-util.c index 1338b6587..de3639fb9 100644 --- a/jerry-core/parser/js/js-parser-util.c +++ b/jerry-core/parser/js/js-parser-util.c @@ -1418,6 +1418,10 @@ parser_error_to_string (parser_error_t error) /**< error code */ { return "Duplicated imported binding name."; } + case PARSER_ERR_EXPORT_NOT_DEFINED: + { + return "Export not defined in module."; + } #endif /* ENABLED (JERRY_MODULE_SYSTEM) */ default: diff --git a/jerry-core/parser/js/js-parser.h b/jerry-core/parser/js/js-parser.h index 155a985b2..1febf70e9 100644 --- a/jerry-core/parser/js/js-parser.h +++ b/jerry-core/parser/js/js-parser.h @@ -179,6 +179,7 @@ typedef enum PARSER_ERR_RIGHT_BRACE_COMMA_EXPECTED, /**< right brace or comma expected */ PARSER_ERR_DUPLICATED_EXPORT_IDENTIFIER, /**< duplicated export identifier name */ PARSER_ERR_DUPLICATED_IMPORT_BINDING, /**< duplicated import binding name */ + PARSER_ERR_EXPORT_NOT_DEFINED, /**< export is not defined in module */ #endif /* ENABLED (JERRY_MODULE_SYSTEM) */ PARSER_ERR_NON_STRICT_ARG_DEFINITION /**< non-strict argument definition */ diff --git a/jerry-core/parser/js/js-scanner-util.c b/jerry-core/parser/js/js-scanner-util.c index e28e1dfc7..0dd13274f 100644 --- a/jerry-core/parser/js/js-scanner-util.c +++ b/jerry-core/parser/js/js-scanner-util.c @@ -1764,7 +1764,8 @@ scanner_cleanup (parser_context_t *context_p) /**< context */ || scanner_info_p->type == SCANNER_TYPE_CLASS_CONSTRUCTOR || scanner_info_p->type == SCANNER_TYPE_OBJECT_LITERAL_WITH_SUPER || scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED - || scanner_info_p->type == SCANNER_TYPE_ERR_ASYNC_FUNCTION); + || scanner_info_p->type == SCANNER_TYPE_ERR_ASYNC_FUNCTION + || scanner_info_p->type == SCANNER_TYPE_EXPORT_MODULE_SPECIFIER); #else /* !ENABLED (JERRY_ESNEXT) */ JERRY_ASSERT (scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS); #endif /* ENABLED (JERRY_ESNEXT) */ @@ -2713,6 +2714,31 @@ scanner_literal_is_created (parser_context_t *context_p, /**< context */ return (scope_stack_p->map_to & PARSER_SCOPE_STACK_IS_LOCAL_CREATED) != 0; } /* scanner_literal_is_created */ +/** + * Checks whether the literal exists. + * + * @return true if the literal exists, false otherwise + */ +bool +scanner_literal_exists (parser_context_t *context_p, /**< context */ + uint16_t literal_index) /**< literal index */ +{ + JERRY_ASSERT (literal_index < PARSER_REGISTER_START); + + parser_scope_stack_t *scope_stack_p = context_p->scope_stack_p + context_p->scope_stack_top; + + while (scope_stack_p-- > context_p->scope_stack_p) + { + if (scope_stack_p->map_from != PARSER_SCOPE_STACK_FUNC + && scanner_decode_map_to (scope_stack_p) == literal_index) + { + return true; + } + } + + return false; +} /* scanner_literal_exists */ + #endif /* ENABLED (JERRY_ESNEXT) */ /** diff --git a/jerry-core/parser/js/js-scanner.c b/jerry-core/parser/js/js-scanner.c index 414dad995..41887b687 100644 --- a/jerry-core/parser/js/js-scanner.c +++ b/jerry-core/parser/js/js-scanner.c @@ -1879,6 +1879,9 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ return SCAN_NEXT_TOKEN; } + scanner_source_start_t source_start; + source_start.source_p = context_p->source_p; + if (context_p->token.type == LEXER_LEFT_BRACE) { lexer_next_token (context_p); @@ -1924,6 +1927,9 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ return SCAN_KEEP_TOKEN; } + scanner_info_t *info_p = scanner_insert_info (context_p, source_start.source_p, sizeof (scanner_info_t)); + info_p->type = SCANNER_TYPE_EXPORT_MODULE_SPECIFIER; + lexer_next_token (context_p); if (context_p->token.type != LEXER_LITERAL @@ -3737,6 +3743,13 @@ scan_completed: print_location = false; break; } + case SCANNER_TYPE_EXPORT_MODULE_SPECIFIER: + { + JERRY_DEBUG_MSG (" EXPORT_WITH_MODULE_SPECIFIER: source:%d\n", + (int) (info_p->source_p - source_start_p)); + print_location = false; + break; + } #endif /* ENABLED (JERRY_ESNEXT) */ } diff --git a/jerry-core/parser/js/js-scanner.h b/jerry-core/parser/js/js-scanner.h index 9608ba78f..57d070044 100644 --- a/jerry-core/parser/js/js-scanner.h +++ b/jerry-core/parser/js/js-scanner.h @@ -53,6 +53,7 @@ typedef enum SCANNER_TYPE_ERR_REDECLARED, /**< syntax error: a variable is redeclared */ SCANNER_TYPE_ERR_ASYNC_FUNCTION, /**< an invalid async function follows */ SCANNER_TYPE_OBJECT_LITERAL_WITH_SUPER, /**< object literal with inner super reference */ + SCANNER_TYPE_EXPORT_MODULE_SPECIFIER, /**< export with module specifier */ #endif /* ENABLED (JERRY_ESNEXT) */ } scanner_info_type_t; diff --git a/tests/test262-es6-excludelist.xml b/tests/test262-es6-excludelist.xml index f77fa1980..7d9bcc1ff 100644 --- a/tests/test262-es6-excludelist.xml +++ b/tests/test262-es6-excludelist.xml @@ -301,7 +301,6 @@ No longer a SyntaxError in ES11 No longer a SyntaxError in ES11 - ES2018 change: next method must be cached diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index da520a0b7..75f973793 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -742,8 +742,6 @@ - -