diff --git a/jerry-core/parser/js/js-lexer.c b/jerry-core/parser/js/js-lexer.c index 755b476fa7..4f0d0e18d6 100644 --- a/jerry-core/parser/js/js-lexer.c +++ b/jerry-core/parser/js/js-lexer.c @@ -319,7 +319,7 @@ static const keyword_string_t keywords_with_length_2[] = { LEXER_KEYWORD ("do", LEXER_KEYW_DO), LEXER_KEYWORD ("if", LEXER_KEYW_IF), - LEXER_KEYWORD ("in", LEXER_KEYW_IN), + LEXER_KEYWORD ("in", LEXER_KEYW_IN) }; /** @@ -331,7 +331,7 @@ static const keyword_string_t keywords_with_length_3[] = LEXER_KEYWORD ("let", LEXER_KEYW_LET), LEXER_KEYWORD ("new", LEXER_KEYW_NEW), LEXER_KEYWORD ("try", LEXER_KEYW_TRY), - LEXER_KEYWORD ("var", LEXER_KEYW_VAR), + LEXER_KEYWORD ("var", LEXER_KEYW_VAR) }; /** @@ -346,7 +346,7 @@ static const keyword_string_t keywords_with_length_4[] = LEXER_KEYWORD ("this", LEXER_KEYW_THIS), LEXER_KEYWORD ("true", LEXER_LIT_TRUE), LEXER_KEYWORD ("void", LEXER_KEYW_VOID), - LEXER_KEYWORD ("with", LEXER_KEYW_WITH), + LEXER_KEYWORD ("with", LEXER_KEYW_WITH) }; /** @@ -365,7 +365,7 @@ static const keyword_string_t keywords_with_length_5[] = LEXER_KEYWORD ("super", LEXER_KEYW_SUPER), LEXER_KEYWORD ("throw", LEXER_KEYW_THROW), LEXER_KEYWORD ("while", LEXER_KEYW_WHILE), - LEXER_KEYWORD ("yield", LEXER_KEYW_YIELD), + LEXER_KEYWORD ("yield", LEXER_KEYW_YIELD) }; /** @@ -380,7 +380,7 @@ static const keyword_string_t keywords_with_length_6[] = LEXER_KEYWORD ("return", LEXER_KEYW_RETURN), LEXER_KEYWORD ("static", LEXER_KEYW_STATIC), LEXER_KEYWORD ("switch", LEXER_KEYW_SWITCH), - LEXER_KEYWORD ("typeof", LEXER_KEYW_TYPEOF), + LEXER_KEYWORD ("typeof", LEXER_KEYW_TYPEOF) }; /** @@ -392,7 +392,7 @@ static const keyword_string_t keywords_with_length_7[] = LEXER_KEYWORD ("extends", LEXER_KEYW_EXTENDS), LEXER_KEYWORD ("finally", LEXER_KEYW_FINALLY), LEXER_KEYWORD ("package", LEXER_KEYW_PACKAGE), - LEXER_KEYWORD ("private", LEXER_KEYW_PRIVATE), + LEXER_KEYWORD ("private", LEXER_KEYW_PRIVATE) }; /** @@ -402,7 +402,7 @@ static const keyword_string_t keywords_with_length_8[] = { LEXER_KEYWORD ("continue", LEXER_KEYW_CONTINUE), LEXER_KEYWORD ("debugger", LEXER_KEYW_DEBUGGER), - LEXER_KEYWORD ("function", LEXER_KEYW_FUNCTION), + LEXER_KEYWORD ("function", LEXER_KEYW_FUNCTION) }; /** @@ -411,7 +411,7 @@ static const keyword_string_t keywords_with_length_8[] = static const keyword_string_t keywords_with_length_9[] = { LEXER_KEYWORD ("interface", LEXER_KEYW_INTERFACE), - LEXER_KEYWORD ("protected", LEXER_KEYW_PROTECTED), + LEXER_KEYWORD ("protected", LEXER_KEYW_PROTECTED) }; /** @@ -420,7 +420,7 @@ static const keyword_string_t keywords_with_length_9[] = static const keyword_string_t keywords_with_length_10[] = { LEXER_KEYWORD ("implements", LEXER_KEYW_IMPLEMENTS), - LEXER_KEYWORD ("instanceof", LEXER_KEYW_INSTANCEOF), + LEXER_KEYWORD ("instanceof", LEXER_KEYW_INSTANCEOF) }; /** diff --git a/jerry-core/parser/js/js-lexer.h b/jerry-core/parser/js/js-lexer.h index 7fe392567c..f2c5239dd4 100644 --- a/jerry-core/parser/js/js-lexer.h +++ b/jerry-core/parser/js/js-lexer.h @@ -151,26 +151,14 @@ typedef enum LEXER_SCAN_SWITCH, /**< special value for switch pre-scan */ LEXER_CLASS_CONSTRUCTOR, /**< special value for class constructor method */ -#ifdef CONFIG_DISABLE_ES2015 - /* Future reserved words: these keywords - * must form a group after all other keywords. */ -#define LEXER_FIRST_FUTURE_RESERVED_WORD LEXER_KEYW_CLASS -#endif /* CONFIG_DISABLE_ES2015 */ + /* Keywords which may be reserved. */ LEXER_KEYW_CLASS, /**< class */ + LEXER_KEYW_ENUM, /**< enum */ LEXER_KEYW_EXTENDS, /**< extends */ LEXER_KEYW_SUPER, /**< super */ LEXER_KEYW_CONST, /**< const */ LEXER_KEYW_EXPORT, /**< export */ LEXER_KEYW_IMPORT, /**< import */ -#ifndef CONFIG_DISABLE_ES2015 - /* Future reserved words: these keywords - * must form a group after all other keywords. - * Note: - * Tokens from LEXER_KEYW_CLASS to LEXER_KEYW_IMPORT - * are no longer future reserved words in ES2015. */ -#define LEXER_FIRST_FUTURE_RESERVED_WORD LEXER_KEYW_ENUM -#endif /* !CONFIG_DISABLE_ES2015 */ - LEXER_KEYW_ENUM, /**< enum */ #ifndef CONFIG_DISABLE_ES2015 LEXER_KEYW_AWAIT, /**< await */ #endif /* !CONFIG_DISABLE_ES2015 */ @@ -179,31 +167,14 @@ typedef enum * must form a group after future reserved words. */ #define LEXER_FIRST_FUTURE_STRICT_RESERVED_WORD LEXER_KEYW_IMPLEMENTS LEXER_KEYW_IMPLEMENTS, /**< implements */ + LEXER_KEYW_LET, /**< let */ LEXER_KEYW_PRIVATE, /**< private */ LEXER_KEYW_PUBLIC, /**< public */ + LEXER_KEYW_YIELD, /**< yield */ LEXER_KEYW_INTERFACE, /**< interface */ LEXER_KEYW_PACKAGE, /**< package */ LEXER_KEYW_PROTECTED, /**< protected */ - -#ifndef CONFIG_DISABLE_ES2015 - /* Context dependent strict reserved words: - * See also: ECMA-262 v6, 11.6.2.1 */ -#define LEXER_FIRST_CONTEXT_DEPENDENT_RESERVED_WORD LEXER_KEYW_STATIC - LEXER_KEYW_STATIC, /**< static */ -#else /* CONFIG_DISABLE_ES2015 */ - /* Context dependent strict reserved words: - * See also: ECMA-262 v6, 11.6.2.1 */ -#define LEXER_FIRST_CONTEXT_DEPENDENT_RESERVED_WORD -#endif /* !CONFIG_DISABLE_ES2015 */ - - /* Context dependent future strict reserved words: - * See also: ECMA-262 v6, 11.6.2.1 */ -#define LEXER_FIRST_CONTEXT_DEPENDENT_FUTURE_RESERVED_WORD LEXER_KEYW_LET - LEXER_KEYW_LET, /**< let */ - LEXER_KEYW_YIELD, /**< yield */ -#ifdef CONFIG_DISABLE_ES2015 LEXER_KEYW_STATIC, /**< static */ -#endif /* CONFIG_DISABLE_ES2015 */ } lexer_token_type_t; #define LEXER_NEWLINE_LS_PS_BYTE_1 0xe2 diff --git a/jerry-core/parser/js/js-parser-expr.c b/jerry-core/parser/js/js-parser-expr.c index 5f61d86263..de62ac4d4e 100644 --- a/jerry-core/parser/js/js-parser-expr.c +++ b/jerry-core/parser/js/js-parser-expr.c @@ -1286,14 +1286,10 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */ if (PARSER_IS_CLASS_CONSTRUCTOR_SUPER (context_p->status_flags)) { parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_CONSTRUCTOR_THIS); - } - else - { -#endif /* !CONFIG_DISABLE_ES2015_CLASS */ - parser_emit_cbc (context_p, CBC_PUSH_THIS); -#ifndef CONFIG_DISABLE_ES2015_CLASS + break; } #endif /* !CONFIG_DISABLE_ES2015_CLASS */ + parser_emit_cbc (context_p, CBC_PUSH_THIS); break; } case LEXER_LIT_TRUE: @@ -1320,7 +1316,7 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */ case LEXER_KEYW_SUPER: { if ((lexer_check_next_character (context_p, LIT_CHAR_DOT) - || lexer_check_next_character (context_p, LIT_CHAR_LEFT_SQUARE)) + || lexer_check_next_character (context_p, LIT_CHAR_LEFT_SQUARE)) && context_p->status_flags & (PARSER_CLASS_HAS_SUPER | PARSER_IS_ARROW_FUNCTION)) { if (!LEXER_IS_BINARY_OP_TOKEN (context_p->stack_top_uint8)) @@ -1375,6 +1371,24 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */ lexer_next_token (context_p); } /* parser_parse_unary_expression */ +/** + * Push an eval opcode. + */ +static inline void +parser_emit_eval (parser_context_t *context_p) /**< context */ +{ +#ifndef CONFIG_DISABLE_ES2015_CLASS + if (context_p->status_flags & PARSER_CLASS_HAS_SUPER) + { + uint8_t data_byte = (uint8_t) PARSER_GET_CLASS_ECMA_PARSE_OPTS (context_p->status_flags); + parser_emit_cbc_ext_byte (context_p, CBC_EXT_CLASS_EVAL, data_byte); + return; + } +#endif /* !CONFIG_DISABLE_ES2015_CLASS */ + + parser_emit_cbc (context_p, CBC_EVAL); +} /* parser_emit_eval */ + /** * Parse the postfix part of unary operators, and * generate byte code for the whole expression. @@ -1557,20 +1571,7 @@ parser_process_unary_expression (parser_context_t *context_p) /**< context */ if (is_eval) { -#ifndef CONFIG_DISABLE_ES2015_CLASS - if (context_p->status_flags & PARSER_CLASS_HAS_SUPER) - { - parser_flush_cbc (context_p); - context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_CLASS_EVAL); - context_p->last_cbc.value = PARSER_GET_CLASS_ECMA_PARSE_OPTS (context_p->status_flags); - } - else - { -#endif /* !CONFIG_DISABLE_ES2015_CLASS */ - parser_emit_cbc (context_p, CBC_EVAL); -#ifndef CONFIG_DISABLE_ES2015_CLASS - } -#endif /* !CONFIG_DISABLE_ES2015_CLASS */ + parser_emit_eval (context_p); } #ifndef CONFIG_DISABLE_ES2015_CLASS @@ -1813,13 +1814,14 @@ parser_append_binary_token (parser_context_t *context_p) /**< context */ parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index); parser_stack_push_uint8 (context_p, CBC_ASSIGN_PROP_LITERAL); context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE; + #ifndef CONFIG_DISABLE_ES2015_CLASS if (context_p->status_flags & PARSER_CLASS_SUPER_PROP_REFERENCE) { + context_p->status_flags &= (uint32_t) ~PARSER_CLASS_SUPER_PROP_REFERENCE; parser_emit_cbc_ext (context_p, CBC_EXT_SUPER_PROP_ASSIGN); parser_flush_cbc (context_p); } - context_p->status_flags &= (uint32_t) ~PARSER_CLASS_SUPER_PROP_REFERENCE; #endif /* !CONFIG_DISABLE_ES2015_CLASS */ } else diff --git a/jerry-core/parser/js/js-parser-internal.h b/jerry-core/parser/js/js-parser-internal.h index d9a9aa7f31..0bb9a9a6da 100644 --- a/jerry-core/parser/js/js-parser-internal.h +++ b/jerry-core/parser/js/js-parser-internal.h @@ -39,41 +39,41 @@ */ typedef enum { - PARSER_IS_STRICT = (1u << 0), /**< strict mode code */ - PARSER_IS_FUNCTION = (1u << 1), /**< function body is parsed */ - PARSER_IS_CLOSURE = (1u << 2), /**< function body is encapsulated in {} block */ - PARSER_IS_FUNC_EXPRESSION = (1u << 3), /**< a function expression is parsed */ - PARSER_IS_PROPERTY_GETTER = (1u << 4), /**< a property getter function is parsed */ - PARSER_IS_PROPERTY_SETTER = (1u << 5), /**< a property setter function is parsed */ - PARSER_NAMED_FUNCTION_EXP = (1u << 6), /**< a function expression has a name binding */ - PARSER_HAS_NON_STRICT_ARG = (1u << 7), /**< the function has arguments which - * are not supported in strict mode */ - PARSER_ARGUMENTS_NEEDED = (1u << 8), /**< arguments object must be created */ - PARSER_ARGUMENTS_NOT_NEEDED = (1u << 9), /**< arguments object must NOT be created */ - PARSER_LEXICAL_ENV_NEEDED = (1u << 10), /**< lexical environment object must be created */ - PARSER_NO_REG_STORE = (1u << 11), /**< all local variables must be stored - * in the lexical environment object */ - PARSER_INSIDE_WITH = (1u << 12), /**< code block is inside a with statement */ - PARSER_RESOLVE_BASE_FOR_CALLS = (1u << 13), /**< the this object must be resolved when - * a function without a base object is called */ - PARSER_HAS_INITIALIZED_VARS = (1u << 14), /**< a CBC_INITIALIZE_VARS instruction must be emitted */ - PARSER_HAS_LATE_LIT_INIT = (1u << 15), /**< allocate memory for this string after - * the local parser data is freed */ - PARSER_NO_END_LABEL = (1u << 16), /**< return instruction must be inserted - * after the last byte code */ - PARSER_DEBUGGER_BREAKPOINT_APPENDED = (1u << 17), /**< pending (unsent) breakpoint - * info is available */ + PARSER_IS_STRICT = (1u << 0), /**< strict mode code */ + PARSER_IS_FUNCTION = (1u << 1), /**< function body is parsed */ + PARSER_IS_CLOSURE = (1u << 2), /**< function body is encapsulated in {} block */ + PARSER_IS_FUNC_EXPRESSION = (1u << 3), /**< a function expression is parsed */ + PARSER_IS_PROPERTY_GETTER = (1u << 4), /**< a property getter function is parsed */ + PARSER_IS_PROPERTY_SETTER = (1u << 5), /**< a property setter function is parsed */ + PARSER_NAMED_FUNCTION_EXP = (1u << 6), /**< a function expression has a name binding */ + PARSER_HAS_NON_STRICT_ARG = (1u << 7), /**< the function has arguments which + * are not supported in strict mode */ + PARSER_ARGUMENTS_NEEDED = (1u << 8), /**< arguments object must be created */ + PARSER_ARGUMENTS_NOT_NEEDED = (1u << 9), /**< arguments object must NOT be created */ + PARSER_LEXICAL_ENV_NEEDED = (1u << 10), /**< lexical environment object must be created */ + PARSER_NO_REG_STORE = (1u << 11), /**< all local variables must be stored + * in the lexical environment object */ + PARSER_INSIDE_WITH = (1u << 12), /**< code block is inside a with statement */ + PARSER_RESOLVE_BASE_FOR_CALLS = (1u << 13), /**< the this object must be resolved when + * a function without a base object is called */ + PARSER_HAS_INITIALIZED_VARS = (1u << 14), /**< a CBC_INITIALIZE_VARS instruction must be emitted */ + PARSER_HAS_LATE_LIT_INIT = (1u << 15), /**< allocate memory for this string after + * the local parser data is freed */ + PARSER_NO_END_LABEL = (1u << 16), /**< return instruction must be inserted + * after the last byte code */ + PARSER_DEBUGGER_BREAKPOINT_APPENDED = (1u << 17), /**< pending (unsent) breakpoint + * info is available */ #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION - PARSER_IS_ARROW_FUNCTION = (1u << 18), /**< an arrow function is parsed */ - PARSER_ARROW_PARSE_ARGS = (1u << 19), /**< parse the argument list of an arrow function */ + PARSER_IS_ARROW_FUNCTION = (1u << 18), /**< an arrow function is parsed */ + PARSER_ARROW_PARSE_ARGS = (1u << 19), /**< parse the argument list of an arrow function */ #endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */ #ifndef CONFIG_DISABLE_ES2015_CLASS /* These three status flags must be in this order. See PARSER_CLASS_PARSE_OPTS_OFFSET. */ - PARSER_CLASS_CONSTRUCTOR = (1u << 20), /**< a class constructor is parsed (this value must be kept in - * in sync with ECMA_PARSE_CLASS_CONSTRUCTOR) */ - PARSER_CLASS_HAS_SUPER = (1u << 21), /**< class has super reference */ - PARSER_CLASS_STATIC_FUNCTION = (1u << 22), /**< this function is a static class method */ - PARSER_CLASS_SUPER_PROP_REFERENCE = (1u << 23), /**< super property call or assignment */ + PARSER_CLASS_CONSTRUCTOR = (1u << 20), /**< a class constructor is parsed (this value must be + * kept in in sync with ECMA_PARSE_CLASS_CONSTRUCTOR) */ + PARSER_CLASS_HAS_SUPER = (1u << 21), /**< class has super reference */ + PARSER_CLASS_STATIC_FUNCTION = (1u << 22), /**< this function is a static class method */ + PARSER_CLASS_SUPER_PROP_REFERENCE = (1u << 23), /**< super property call or assignment */ #endif /* !CONFIG_DISABLE_ES2015_CLASS */ } parser_general_flags_t; @@ -455,6 +455,7 @@ void parser_flush_cbc (parser_context_t *context_p); void parser_emit_cbc (parser_context_t *context_p, uint16_t opcode); void parser_emit_cbc_literal (parser_context_t *context_p, uint16_t opcode, uint16_t literal_index); void parser_emit_cbc_literal_from_token (parser_context_t *context_p, uint16_t opcode); +void parser_emit_cbc_byte (parser_context_t *context_p, uint16_t opcode, uint8_t data_byte); void parser_emit_cbc_call (parser_context_t *context_p, uint16_t opcode, size_t call_arguments); void parser_emit_cbc_push_number (parser_context_t *context_p, bool is_negative_number); void parser_emit_cbc_forward_branch (parser_context_t *context_p, uint16_t opcode, parser_branch_t *branch_p); @@ -470,6 +471,8 @@ void parser_set_continues_to_current_position (parser_context_t *context_p, pars parser_emit_cbc ((context_p), PARSER_TO_EXT_OPCODE (opcode)) #define parser_emit_cbc_ext_literal(context_p, opcode, literal_index) \ parser_emit_cbc_literal ((context_p), PARSER_TO_EXT_OPCODE (opcode), (literal_index)) +#define parser_emit_cbc_ext_byte(context_p, opcode, data) \ + parser_emit_cbc_byte ((context_p), PARSER_TO_EXT_OPCODE (opcode), (data)) #define parser_emit_cbc_ext_call(context_p, opcode, call_arguments) \ parser_emit_cbc_call ((context_p), PARSER_TO_EXT_OPCODE (opcode), (call_arguments)) #define parser_emit_cbc_ext_forward_branch(context_p, opcode, branch_p) \ diff --git a/jerry-core/parser/js/js-parser-statm.c b/jerry-core/parser/js/js-parser-statm.c index 4330ef4c77..2ef447c67c 100644 --- a/jerry-core/parser/js/js-parser-statm.c +++ b/jerry-core/parser/js/js-parser-statm.c @@ -2024,14 +2024,10 @@ parser_parse_statements (parser_context_t *context_p) /**< context */ { parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_CONSTRUCTOR_THIS); parser_emit_cbc (context_p, CBC_RETURN); - } - else - { -#endif /* !CONFIG_DISABLE_ES2015_CLASS */ - parser_emit_cbc (context_p, CBC_RETURN_WITH_BLOCK); -#ifndef CONFIG_DISABLE_ES2015_CLASS + break; } #endif /* !CONFIG_DISABLE_ES2015_CLASS */ + parser_emit_cbc (context_p, CBC_RETURN_WITH_BLOCK); break; } diff --git a/jerry-core/parser/js/js-parser-util.c b/jerry-core/parser/js/js-parser-util.c index ae31aad1a0..05f08958a3 100644 --- a/jerry-core/parser/js/js-parser-util.c +++ b/jerry-core/parser/js/js-parser-util.c @@ -297,15 +297,14 @@ parser_emit_cbc_literal_from_token (parser_context_t *context_p, /**< context */ } /* parser_emit_cbc_literal_from_token */ /** - * Append a byte code with a call argument + * Append a byte code with a byte argument */ void -parser_emit_cbc_call (parser_context_t *context_p, /**< context */ +parser_emit_cbc_byte (parser_context_t *context_p, /**< context */ uint16_t opcode, /**< opcode */ - size_t call_arguments) /**< number of arguments */ + uint8_t data_byte) /**< data byte */ { JERRY_ASSERT (PARSER_ARGS_EQ (opcode, CBC_HAS_BYTE_ARG)); - JERRY_ASSERT (call_arguments <= CBC_MAXIMUM_BYTE_VALUE); if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE) { @@ -313,7 +312,20 @@ parser_emit_cbc_call (parser_context_t *context_p, /**< context */ } context_p->last_cbc_opcode = opcode; - context_p->last_cbc.value = (uint16_t) call_arguments; + context_p->last_cbc.value = data_byte; +} /* parser_emit_cbc_byte */ + +/** + * Append a byte code with a call argument + */ +void +parser_emit_cbc_call (parser_context_t *context_p, /**< context */ + uint16_t opcode, /**< opcode */ + size_t call_arguments) /**< number of arguments */ +{ + JERRY_ASSERT (call_arguments <= CBC_MAXIMUM_BYTE_VALUE); + + parser_emit_cbc_byte (context_p, opcode, (uint8_t) call_arguments); } /* parser_emit_cbc_call */ /**