diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 6846e9849..98bd00ffd 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -105,6 +105,7 @@ typedef enum ECMA_PARSE_HAS_IMPL_SUPER = (1u << 4), /**< the current context has implicit parent class */ ECMA_PARSE_HAS_STATIC_SUPER = (1u << 5), /**< the current context is a static class method */ ECMA_PARSE_EVAL = (1u << 6), /**< eval is called */ + ECMA_PARSE_MODULE = (1u << 7), /**< module is parsed */ } ecma_parse_opts_t; /** diff --git a/jerry-core/ecma/base/ecma-module.c b/jerry-core/ecma/base/ecma-module.c index bd597543b..b2bbd591d 100644 --- a/jerry-core/ecma/base/ecma-module.c +++ b/jerry-core/ecma/base/ecma-module.c @@ -818,7 +818,7 @@ ecma_module_parse (ecma_module_t *module_p) /**< module */ 0, (jerry_char_t *) source_p, source_size, - JERRY_PARSE_STRICT_MODE, + ECMA_PARSE_STRICT_MODE | ECMA_PARSE_MODULE, &bytecode_data_p); JERRY_CONTEXT (module_top_context_p) = module_p->context_p->parent_p; diff --git a/jerry-core/parser/js/js-parser-expr.c b/jerry-core/parser/js/js-parser-expr.c index da64dbae5..3032037aa 100644 --- a/jerry-core/parser/js/js-parser-expr.c +++ b/jerry-core/parser/js/js-parser-expr.c @@ -607,11 +607,6 @@ parser_parse_class (parser_context_t *context_p, /**< context */ { JERRY_ASSERT (context_p->token.type == LEXER_KEYW_CLASS); -#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) - /* FIXME: Remove this hack after module classes are supported. */ - uint16_t assign_opcode = CBC_ASSIGN_LET_CONST; -#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ - uint16_t class_ident_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS; if (is_statement) @@ -632,8 +627,6 @@ parser_parse_class (parser_context_t *context_p, /**< context */ #if ENABLED (JERRY_ES2015_MODULE_SYSTEM) if (context_p->status_flags & PARSER_MODULE_STORE_IDENT) { - assign_opcode = CBC_ASSIGN_SET_IDENT; - context_p->module_identifier_lit_p = context_p->lit_object.literal_p; context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_STORE_IDENT); } @@ -693,7 +686,7 @@ parser_parse_class (parser_context_t *context_p, /**< context */ if (is_statement) { parser_emit_cbc_literal (context_p, - class_ident_index >= PARSER_REGISTER_START ? CBC_MOV_IDENT : assign_opcode, + class_ident_index >= PARSER_REGISTER_START ? CBC_MOV_IDENT : CBC_ASSIGN_LET_CONST, class_ident_index); } diff --git a/jerry-core/parser/js/js-parser-internal.h b/jerry-core/parser/js/js-parser-internal.h index 21f861e7c..2a2400ff0 100644 --- a/jerry-core/parser/js/js-parser-internal.h +++ b/jerry-core/parser/js/js-parser-internal.h @@ -78,8 +78,9 @@ typedef enum PARSER_IS_EVAL = (1u << 25), /**< eval code */ #endif /* ENABLED (JERRY_ES2015) */ #if ENABLED (JERRY_ES2015_MODULE_SYSTEM) - PARSER_MODULE_DEFAULT_CLASS_OR_FUNC = (1u << 26), /**< parsing a function or class default export */ - PARSER_MODULE_STORE_IDENT = (1u << 27), /**< store identifier of the current export statement */ + PARSER_IS_MODULE = (1u << 26), /**< an export / import keyword is encountered */ + PARSER_MODULE_DEFAULT_CLASS_OR_FUNC = (1u << 27), /**< parsing a function or class default export */ + PARSER_MODULE_STORE_IDENT = (1u << 28), /**< store identifier of the current export statement */ #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ #ifndef JERRY_NDEBUG PARSER_SCANNING_SUCCESSFUL = (1u << 30), /**< scanning process was successful */ diff --git a/jerry-core/parser/js/js-parser-module.c b/jerry-core/parser/js/js-parser-module.c index 812e8896d..74d296650 100644 --- a/jerry-core/parser/js/js-parser-module.c +++ b/jerry-core/parser/js/js-parser-module.c @@ -435,6 +435,14 @@ parser_module_parse_import_clause (parser_context_t *context_p) /**< parser cont parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); } +#if ENABLED (JERRY_ES2015) + if (context_p->next_scanner_info_p->source_p == context_p->source_p) + { + JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED); + parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED); + } +#endif /* ENABLED (JERRY_ES2015) */ + ecma_string_t *import_name_p = NULL; ecma_string_t *local_name_p = NULL; @@ -454,6 +462,14 @@ parser_module_parse_import_clause (parser_context_t *context_p) /**< parser cont parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); } +#if ENABLED (JERRY_ES2015) + if (context_p->next_scanner_info_p->source_p == context_p->source_p) + { + JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED); + parser_raise_error (context_p, PARSER_ERR_VARIABLE_REDECLARED); + } +#endif /* ENABLED (JERRY_ES2015) */ + lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_NEW_IDENT_LITERAL); local_name_index = context_p->lit_object.index; diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index 30cf207f8..769b9e4fd 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -1766,7 +1766,6 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */ context.status_flags = PARSER_IS_FUNCTION; } - #if ENABLED (JERRY_ES2015) context.status_flags |= PARSER_GET_CLASS_PARSER_OPTS (parse_opts); #endif /* ENABLED (JERRY_ES2015) */ @@ -1865,6 +1864,7 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */ context.u.allocated_buffer_p = NULL; context.line = 1; context.column = 1; + context.token.flags = 0; parser_stack_init (&context); @@ -1873,6 +1873,11 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */ #endif /* ENABLED (JERRY_DEBUGGER) */ #if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + if (context.status_flags & PARSER_IS_MODULE) + { + context.status_flags |= PARSER_IS_STRICT; + } + if (parse_opts & ECMA_PARSE_EVAL) { /* After this point this flag is set for non-direct evals as well. */ @@ -1906,6 +1911,12 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */ lexer_next_token (&context); } +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + else if (parse_opts & ECMA_PARSE_MODULE) + { + scanner_create_variables (&context, SCANNER_CREATE_VARS_NO_OPTS); + } +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ else { JERRY_ASSERT (context.next_scanner_info_p->source_p == source_p diff --git a/jerry-core/parser/js/js-scanner-internal.h b/jerry-core/parser/js/js-scanner-internal.h index 9055f12d6..c42292698 100644 --- a/jerry-core/parser/js/js-scanner-internal.h +++ b/jerry-core/parser/js/js-scanner-internal.h @@ -63,7 +63,7 @@ typedef enum * * SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_LET : function declared in this block, might be let or var * SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_CONST : function declared in this block, must be let - * SCANNER_LITERAL_IS_LET | SCANNER_LITERAL_IS_CONST : catch block variable + * SCANNER_LITERAL_IS_LET | SCANNER_LITERAL_IS_CONST : module import on global scope, catch block variable otherwise */ /** @@ -105,6 +105,9 @@ typedef enum #endif /* ENABLED (JERRY_ES2015) */ SCANNER_LITERAL_POOL_NO_ARGUMENTS = (1 << 4), /**< arguments object should not be constructed */ SCANNER_LITERAL_POOL_IN_WITH = (1 << 5), /**< literal pool is in a with statement */ +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + SCANNER_LITERAL_POOL_IN_EXPORT = (1 << 6), /**< the declared variables are exported by the module system */ +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ } scanner_literal_pool_flags_t; /** @@ -167,6 +170,7 @@ void scanner_append_argument (parser_context_t *context_p, scanner_context_t *sc bool scanner_scope_find_let_declaration (parser_context_t *context_p, lexer_lit_location_t *literal_p); void scanner_detect_invalid_var (parser_context_t *context_p, scanner_context_t *scanner_context_p, lexer_lit_location_t *var_literal_p); +void scanner_detect_invalid_let (parser_context_t *context_p, lexer_lit_location_t *let_literal_p); #endif /* ENABLED (JERRY_ES2015) */ void scanner_detect_eval_call (parser_context_t *context_p, scanner_context_t *scanner_context_p); diff --git a/jerry-core/parser/js/js-scanner-util.c b/jerry-core/parser/js/js-scanner-util.c index 6b1af3125..61c3d1002 100644 --- a/jerry-core/parser/js/js-scanner-util.c +++ b/jerry-core/parser/js/js-scanner-util.c @@ -120,6 +120,12 @@ scanner_get_stream_size (scanner_info_t *info_p, /**< scanner info block */ case SCANNER_STREAM_TYPE_ARG: case SCANNER_STREAM_TYPE_ARG_FUNC: case SCANNER_STREAM_TYPE_FUNC: +#if ENABLED (JERRY_ES2015) + case SCANNER_STREAM_TYPE_FUNC_LOCAL: +#endif /* ENABLED (JERRY_ES2015) */ +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + case SCANNER_STREAM_TYPE_IMPORT: +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ { break; } @@ -639,6 +645,12 @@ scanner_pop_literal_pool (parser_context_t *context_p, /**< context */ { type = SCANNER_STREAM_TYPE_LET; } +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + else if (prev_literal_pool_p == NULL) + { + type = SCANNER_STREAM_TYPE_IMPORT; + } +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ } else if (literal_p->type & SCANNER_LITERAL_IS_CONST) { @@ -1029,7 +1041,7 @@ scanner_scope_find_let_declaration (parser_context_t *context_p, /**< context */ void scanner_detect_invalid_var (parser_context_t *context_p, /**< context */ scanner_context_t *scanner_context_p, /**< scanner context */ - lexer_lit_location_t *var_literal_p) /**< literal */ + lexer_lit_location_t *var_literal_p) /**< var literal */ { if (var_literal_p->type & SCANNER_LITERAL_IS_LOCAL && !(var_literal_p->type & SCANNER_LITERAL_IS_FUNC) @@ -1097,6 +1109,26 @@ scanner_detect_invalid_var (parser_context_t *context_p, /**< context */ } } /* scanner_detect_invalid_var */ +/** + * Throws an error for invalid let statements. + */ +void +scanner_detect_invalid_let (parser_context_t *context_p, /**< context */ + lexer_lit_location_t *let_literal_p) /**< let literal */ +{ + if (let_literal_p->type & (SCANNER_LITERAL_IS_ARG + | SCANNER_LITERAL_IS_VAR + | SCANNER_LITERAL_IS_LOCAL)) + { + scanner_raise_redeclaration_error (context_p); + } + + if (let_literal_p->type & SCANNER_LITERAL_IS_FUNC) + { + let_literal_p->type &= (uint8_t) ~SCANNER_LITERAL_IS_FUNC; + } +} /* scanner_detect_invalid_let */ + #endif /* ENABLED (JERRY_ES2015) */ /** @@ -1374,11 +1406,14 @@ scanner_is_global_context_needed (parser_context_t *context_p) /**< context */ uint8_t data = data_p[0]; uint32_t type = data & SCANNER_STREAM_TYPE_MASK; + /* FIXME: a private declarative lexical environment should always be present + * for modules. Remove SCANNER_STREAM_TYPE_IMPORT after it is implemented. */ JERRY_ASSERT (type == SCANNER_STREAM_TYPE_VAR || type == SCANNER_STREAM_TYPE_LET || type == SCANNER_STREAM_TYPE_CONST || type == SCANNER_STREAM_TYPE_FUNC - || type == SCANNER_STREAM_TYPE_FUNC_LOCAL); + || type == SCANNER_STREAM_TYPE_FUNC_LOCAL + || type == SCANNER_STREAM_TYPE_IMPORT); /* Only let/const can be stored in registers */ JERRY_ASSERT ((data & SCANNER_STREAM_NO_REG) @@ -1401,7 +1436,9 @@ scanner_is_global_context_needed (parser_context_t *context_p) /**< context */ data_p += 2 + 2; } - if (type == SCANNER_STREAM_TYPE_VAR || type == SCANNER_STREAM_TYPE_FUNC) + if (type == SCANNER_STREAM_TYPE_VAR + || type == SCANNER_STREAM_TYPE_FUNC + || type == SCANNER_STREAM_TYPE_IMPORT) { continue; } @@ -1556,10 +1593,17 @@ scanner_create_variables (parser_context_t *context_p, /**< context */ uint16_t map_to; uint16_t func_init_opcode = CBC_INIT_LOCAL; +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + JERRY_ASSERT (type != SCANNER_STREAM_TYPE_IMPORT || (data_p[0] & SCANNER_STREAM_NO_REG)); +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ + #if ENABLED (JERRY_ES2015) if (info_type == SCANNER_TYPE_FUNCTION) { if (type != SCANNER_STREAM_TYPE_LET +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + && type != SCANNER_STREAM_TYPE_IMPORT +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ && type != SCANNER_STREAM_TYPE_CONST) { context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_GLOBAL; diff --git a/jerry-core/parser/js/js-scanner.c b/jerry-core/parser/js/js-scanner.c index 7f45160e4..5ba2d961c 100644 --- a/jerry-core/parser/js/js-scanner.c +++ b/jerry-core/parser/js/js-scanner.c @@ -681,6 +681,10 @@ scanner_scan_primary_expression_end (parser_context_t *context_p, /**< context * case SCAN_STACK_CONST: #endif /* ENABLED (JERRY_ES2015) */ { +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + scanner_context_p->active_literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_IN_EXPORT; +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ + parser_stack_pop_uint8 (context_p); return SCAN_KEEP_TOKEN; } @@ -1291,20 +1295,17 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ lexer_lit_location_t *literal_p = scanner_add_literal (context_p, scanner_context_p); - if (literal_p->type & (SCANNER_LITERAL_IS_ARG - | SCANNER_LITERAL_IS_VAR - | SCANNER_LITERAL_IS_LOCAL)) - { - scanner_raise_redeclaration_error (context_p); - } - - if (literal_p->type & SCANNER_LITERAL_IS_FUNC) - { - literal_p->type = (uint8_t) (literal_p->type & ~SCANNER_LITERAL_IS_FUNC); - } - + scanner_detect_invalid_let (context_p, literal_p); literal_p->type |= SCANNER_LITERAL_IS_LET; +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + if (scanner_context_p->active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_EXPORT) + { + literal_p->type |= SCANNER_LITERAL_NO_REG; + scanner_context_p->active_literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_IN_EXPORT; + } +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ + scanner_context_p->mode = SCAN_MODE_CLASS_DECLARATION; parser_stack_push_uint8 (context_p, SCAN_STACK_CLASS_STATEMENT); return SCAN_NEXT_TOKEN; @@ -1318,6 +1319,8 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ scanner_raise_error (context_p); } + context_p->status_flags |= PARSER_IS_MODULE; + scanner_context_p->mode = SCAN_MODE_STATEMENT_END; lexer_next_token (context_p); @@ -1332,8 +1335,14 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ if (context_p->token.type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL) { - lexer_lit_location_t *location_p = scanner_add_literal (context_p, scanner_context_p); - location_p->type |= SCANNER_LITERAL_IS_VAR; + lexer_lit_location_t *literal_p = scanner_add_literal (context_p, scanner_context_p); + +#if ENABLED (JERRY_ES2015) + scanner_detect_invalid_let (context_p, literal_p); + literal_p->type |= SCANNER_LITERAL_IS_LOCAL | SCANNER_LITERAL_NO_REG; +#else /* !ENABLED (JERRY_ES2015) */ + literal_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_NO_REG; +#endif /* ENABLED (JERRY_ES2015) */ lexer_next_token (context_p); @@ -1365,8 +1374,14 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ scanner_raise_error (context_p); } - lexer_lit_location_t *location_p = scanner_add_literal (context_p, scanner_context_p); - location_p->type |= SCANNER_LITERAL_IS_VAR; + lexer_lit_location_t *literal_p = scanner_add_literal (context_p, scanner_context_p); + +#if ENABLED (JERRY_ES2015) + scanner_detect_invalid_let (context_p, literal_p); + literal_p->type |= SCANNER_LITERAL_IS_LOCAL | SCANNER_LITERAL_NO_REG; +#else /* !ENABLED (JERRY_ES2015) */ + literal_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_NO_REG; +#endif /* ENABLED (JERRY_ES2015) */ lexer_next_token (context_p); } @@ -1382,6 +1397,10 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ scanner_raise_error (context_p); } +#if ENABLED (JERRY_ES2015) + const uint8_t *source_p = context_p->source_p; +#endif /* ENABLED (JERRY_ES2015) */ + if (lexer_check_next_character (context_p, LIT_CHAR_LOWERCASE_A)) { lexer_next_token (context_p); @@ -1398,10 +1417,32 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ { scanner_raise_error (context_p); } + +#if ENABLED (JERRY_ES2015) + source_p = context_p->source_p; +#endif /* ENABLED (JERRY_ES2015) */ } - lexer_lit_location_t *location_p = scanner_add_literal (context_p, scanner_context_p); - location_p->type |= SCANNER_LITERAL_IS_VAR; + lexer_lit_location_t *literal_p = scanner_add_literal (context_p, scanner_context_p); + +#if ENABLED (JERRY_ES2015) + if (literal_p->type & (SCANNER_LITERAL_IS_ARG + | SCANNER_LITERAL_IS_VAR + | SCANNER_LITERAL_IS_LOCAL)) + { + context_p->source_p = source_p; + scanner_raise_redeclaration_error (context_p); + } + + if (literal_p->type & SCANNER_LITERAL_IS_FUNC) + { + literal_p->type &= (uint8_t) ~SCANNER_LITERAL_IS_FUNC; + } + + literal_p->type |= SCANNER_LITERAL_IS_LOCAL | SCANNER_LITERAL_NO_REG; +#else /* !ENABLED (JERRY_ES2015) */ + literal_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_NO_REG; +#endif /* ENABLED (JERRY_ES2015) */ lexer_next_token (context_p); @@ -1446,6 +1487,8 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ scanner_raise_error (context_p); } + context_p->status_flags |= PARSER_IS_MODULE; + lexer_next_token (context_p); if (context_p->token.type == LEXER_KEYW_DEFAULT) @@ -1502,16 +1545,19 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ if (context_p->token.type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL) { - lexer_lit_location_t *location_p = scanner_add_literal (context_p, scanner_context_p); - location_p->type |= SCANNER_LITERAL_IS_VAR; + lexer_lit_location_t *literal_p = scanner_add_literal (context_p, scanner_context_p); + + scanner_detect_invalid_let (context_p, literal_p); + + literal_p->type |= SCANNER_LITERAL_IS_LET | SCANNER_LITERAL_NO_REG; return SCAN_NEXT_TOKEN; } - lexer_lit_location_t *location_p; - location_p = scanner_add_custom_literal (context_p, - scanner_context_p->active_literal_pool_p, - &lexer_default_literal); - location_p->type |= SCANNER_LITERAL_IS_VAR; + lexer_lit_location_t *literal_p; + literal_p = scanner_add_custom_literal (context_p, + scanner_context_p->active_literal_pool_p, + &lexer_default_literal); + literal_p->type |= SCANNER_LITERAL_IS_LET | SCANNER_LITERAL_NO_REG; return SCAN_KEEP_TOKEN; } #endif /* ENABLED (JERRY_ES2015) */ @@ -1612,25 +1658,19 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */ return SCAN_NEXT_TOKEN; } -#if ENABLED (JERRY_ES2015) - if (context_p->token.type == LEXER_KEYW_CLASS) + switch (context_p->token.type) { - /* FIXME: classes should be let declarations. */ - scanner_context_p->mode = SCAN_MODE_CLASS_DECLARATION; - parser_stack_push_uint8 (context_p, SCAN_STACK_CLASS_STATEMENT); - - lexer_next_token (context_p); - - if (context_p->token.type != LEXER_LITERAL || context_p->token.lit_location.type != LEXER_IDENT_LITERAL) - { - scanner_raise_error (context_p); - } - - lexer_lit_location_t *location_p = scanner_add_literal (context_p, scanner_context_p); - location_p->type |= SCANNER_LITERAL_IS_VAR; - return SCAN_NEXT_TOKEN; - } +#if ENABLED (JERRY_ES2015) + case LEXER_KEYW_CLASS: + case LEXER_KEYW_LET: + case LEXER_KEYW_CONST: #endif /* ENABLED (JERRY_ES2015) */ + case LEXER_KEYW_VAR: + { + scanner_context_p->active_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_IN_EXPORT; + break; + } + } scanner_context_p->mode = SCAN_MODE_STATEMENT; return SCAN_KEEP_TOKEN; @@ -2198,17 +2238,7 @@ scanner_scan_all (parser_context_t *context_p, /**< context */ #if ENABLED (JERRY_ES2015) if (stack_top == SCAN_STACK_LET || stack_top == SCAN_STACK_CONST) { - if (literal_p->type & (SCANNER_LITERAL_IS_ARG - | SCANNER_LITERAL_IS_VAR - | SCANNER_LITERAL_IS_LOCAL)) - { - scanner_raise_redeclaration_error (context_p); - } - - if (literal_p->type & SCANNER_LITERAL_IS_FUNC) - { - literal_p->type = (uint8_t) (literal_p->type & ~SCANNER_LITERAL_IS_FUNC); - } + scanner_detect_invalid_let (context_p, literal_p); if (stack_top == SCAN_STACK_LET) { @@ -2260,6 +2290,13 @@ scanner_scan_all (parser_context_t *context_p, /**< context */ lexer_next_token (context_p); #endif /* ENABLED (JERRY_ES2015) */ +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + if (scanner_context.active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_EXPORT) + { + literal_p->type |= SCANNER_LITERAL_NO_REG; + } +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ + switch (context_p->token.type) { case LEXER_ASSIGN: @@ -2276,6 +2313,10 @@ scanner_scan_all (parser_context_t *context_p, /**< context */ if (SCANNER_IS_FOR_START (stack_top)) { +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + JERRY_ASSERT (!(scanner_context.active_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_EXPORT)); +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ + if (context_p->token.type != LEXER_SEMICOLON && context_p->token.type != LEXER_KEYW_IN && !SCANNER_IDENTIFIER_IS_OF ()) @@ -2293,6 +2334,10 @@ scanner_scan_all (parser_context_t *context_p, /**< context */ JERRY_ASSERT (stack_top == SCAN_STACK_VAR); #endif /* ENABLED (JERRY_ES2015) */ +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + scanner_context.active_literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_IN_EXPORT; +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ + scanner_context.mode = SCAN_MODE_STATEMENT_END; parser_stack_pop_uint8 (context_p); continue; @@ -2646,6 +2691,13 @@ scan_completed: break; } #endif /* ENABLED (JERRY_ES2015) */ +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + case SCANNER_STREAM_TYPE_IMPORT: + { + JERRY_DEBUG_MSG (" IMPORT "); + break; + } +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ default: { JERRY_ASSERT ((data_p[0] & SCANNER_STREAM_TYPE_MASK) == SCANNER_STREAM_TYPE_HOLE); diff --git a/jerry-core/parser/js/js-scanner.h b/jerry-core/parser/js/js-scanner.h index 17a782fd4..5cb7368d4 100644 --- a/jerry-core/parser/js/js-scanner.h +++ b/jerry-core/parser/js/js-scanner.h @@ -145,6 +145,9 @@ typedef enum SCANNER_STREAM_TYPE_LET, /**< let declaration */ SCANNER_STREAM_TYPE_CONST, /**< const declaration */ #endif /* ENABLED (JERRY_ES2015) */ +#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) + SCANNER_STREAM_TYPE_IMPORT, /**< module import */ +#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ SCANNER_STREAM_TYPE_ARG, /**< argument declaration */ /* Function types should be at the end. See the SCANNER_STREAM_TYPE_IS_FUNCTION macro. */ SCANNER_STREAM_TYPE_ARG_FUNC, /**< argument declaration which is later initialized with a function */ diff --git a/tests/jerry/es2015/module-export-fail-test.js b/tests/jerry/es2015/module-export-fail-test.js new file mode 100644 index 000000000..860528295 --- /dev/null +++ b/tests/jerry/es2015/module-export-fail-test.js @@ -0,0 +1,17 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This module is imported by failing tests. */ +export let a; diff --git a/tests/jerry/fail/module-032.js b/tests/jerry/fail/module-032.js new file mode 100644 index 000000000..c4256330b --- /dev/null +++ b/tests/jerry/fail/module-032.js @@ -0,0 +1,17 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let a; +import { a } from "../es2015/module-export-fail-test.js"; diff --git a/tests/jerry/fail/module-033.js b/tests/jerry/fail/module-033.js new file mode 100644 index 000000000..467b5640d --- /dev/null +++ b/tests/jerry/fail/module-033.js @@ -0,0 +1,17 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var a; +import { a } from "../es2015/module-export-fail-test.js"; diff --git a/tests/jerry/fail/module-034.js b/tests/jerry/fail/module-034.js new file mode 100644 index 000000000..a0298c1c0 --- /dev/null +++ b/tests/jerry/fail/module-034.js @@ -0,0 +1,17 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { a } from "../es2015/module-export-fail-test.js"; +class a {}; diff --git a/tests/jerry/fail/module-035.js b/tests/jerry/fail/module-035.js new file mode 100644 index 000000000..411b6c629 --- /dev/null +++ b/tests/jerry/fail/module-035.js @@ -0,0 +1,17 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { a } from "../es2015/module-export-fail-test.js"; +function a() {}