From 045f476c26f4dc5531995dd48f501876acc9b624 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Fri, 13 Jul 2018 02:48:23 -0700 Subject: [PATCH] Fixes for ES2015 classes. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-core/parser/js/js-lexer.c | 43 +++++++++++------------ jerry-core/parser/js/js-parser-expr.c | 18 +++++----- jerry-core/parser/js/js-parser-internal.h | 8 ++--- jerry-core/parser/js/js-parser-scanner.c | 30 ++++++++-------- jerry-core/parser/js/js-parser-util.c | 28 +++++++-------- jerry-core/parser/js/js-parser.c | 5 ++- jerry-core/parser/js/js-parser.h | 10 +++--- 7 files changed, 70 insertions(+), 72 deletions(-) diff --git a/jerry-core/parser/js/js-lexer.c b/jerry-core/parser/js/js-lexer.c index 8e03979752..d436e2289f 100644 --- a/jerry-core/parser/js/js-lexer.c +++ b/jerry-core/parser/js/js-lexer.c @@ -286,9 +286,10 @@ lexer_skip_empty_statements (parser_context_t *context_p) /**< context */ { lexer_skip_spaces (context_p); - while (*context_p->source_p == LIT_CHAR_SEMICOLON) + while (context_p->source_p < context_p->source_end_p + && *context_p->source_p == LIT_CHAR_SEMICOLON) { - lexer_next_token (context_p); + context_p->source_p++; lexer_skip_spaces (context_p); } } /* lexer_skip_empty_statements */ @@ -2268,7 +2269,9 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */ lexer_skip_spaces (context_p); #ifndef CONFIG_DISABLE_ES2015_CLASS - bool is_static_method = (context_p->token.type == LEXER_KEYW_STATIC); + int is_class_method = ((context_p->status_flags & PARSER_IS_CLASS) + && !must_be_identifier + && (context_p->token.type != LEXER_KEYW_STATIC)); #endif /* !CONFIG_DISABLE_ES2015_CLASS */ context_p->token.line = context_p->line; @@ -2302,11 +2305,9 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */ } } } + #ifndef CONFIG_DISABLE_ES2015_CLASS - if ((context_p->status_flags & PARSER_IS_CLASS) - && !must_be_identifier - && !is_static_method - && context_p->token.lit_location.length == 6 + if (is_class_method && lexer_compare_raw_identifier_to_current (context_p, "static", 6)) { context_p->token.type = LEXER_KEYW_STATIC; @@ -2349,9 +2350,7 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */ } #ifndef CONFIG_DISABLE_ES2015_CLASS - if ((context_p->status_flags & PARSER_IS_CLASS) - && !must_be_identifier - && !is_static_method + if (is_class_method && lexer_compare_raw_identifier_to_current (context_p, "constructor", 11)) { context_p->token.type = LEXER_CLASS_CONSTRUCTOR; @@ -2431,28 +2430,28 @@ lexer_scan_identifier (parser_context_t *context_p, /**< context */ */ bool lexer_compare_identifier_to_current (parser_context_t *context_p, /**< context */ - const lexer_lit_location_t *right) /**< identifier */ + const lexer_lit_location_t *right_ident_p) /**< identifier */ { - lexer_lit_location_t *left = &context_p->token.lit_location; + lexer_lit_location_t *left_ident_p = &context_p->token.lit_location; const uint8_t *left_p; const uint8_t *right_p; size_t count; - JERRY_ASSERT (left->length > 0 && right->length > 0); + JERRY_ASSERT (left_ident_p->length > 0 && right_ident_p->length > 0); - if (left->length != right->length) + if (left_ident_p->length != right_ident_p->length) { return 0; } - if (!left->has_escape && !right->has_escape) + if (!left_ident_p->has_escape && !right_ident_p->has_escape) { - return memcmp (left->char_p, right->char_p, left->length) == 0; + return memcmp (left_ident_p->char_p, right_ident_p->char_p, left_ident_p->length) == 0; } - left_p = left->char_p; - right_p = right->char_p; - count = left->length; + left_p = left_ident_p->char_p; + right_p = right_ident_p->char_p; + count = left_ident_p->length; do { @@ -2529,14 +2528,14 @@ lexer_compare_raw_identifier_to_current (parser_context_t *context_p, /**< conte const char *right_ident_p, /**< identifier */ size_t right_ident_length) /**< identifier length */ { - lexer_lit_location_t *left = &context_p->token.lit_location; + lexer_lit_location_t *left_ident_p = &context_p->token.lit_location; - if (left->length != right_ident_length || left->has_escape) + if (left_ident_p->length != right_ident_length || left_ident_p->has_escape) { return 0; } - return memcmp (left->char_p, right_ident_p, right_ident_length) == 0; + return memcmp (left_ident_p->char_p, right_ident_p, right_ident_length) == 0; } /* lexer_compare_raw_identifier_to_current */ /** diff --git a/jerry-core/parser/js/js-parser-expr.c b/jerry-core/parser/js/js-parser-expr.c index ea032838b9..4a90fae738 100644 --- a/jerry-core/parser/js/js-parser-expr.c +++ b/jerry-core/parser/js/js-parser-expr.c @@ -429,7 +429,7 @@ parser_parse_class_literal (parser_context_t *context_p, /**< context */ if (constructor_literal_p->type == LEXER_FUNCTION_LITERAL) { /* 14.5.1 */ - parser_raise_error (context_p, PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTOR); + parser_raise_error (context_p, PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS); } parser_flush_cbc (context_p); @@ -445,7 +445,7 @@ parser_parse_class_literal (parser_context_t *context_p, /**< context */ { if (is_static && lexer_compare_raw_identifier_to_current (context_p, "prototype", 9)) { - parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROPERTY_NAME_PROTOTYPE); + parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE); } if (!lexer_check_left_paren (context_p)) @@ -1102,13 +1102,6 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */ PARSER_IS_FUNCTION | PARSER_IS_FUNC_EXPRESSION | PARSER_IS_CLOSURE); break; } -#ifndef CONFIG_DISABLE_ES2015_CLASS - case LEXER_KEYW_CLASS: - { - parser_parse_class (context_p, false); - return; - } -#endif /* !CONFIG_DISABLE_ES2015_CLASS */ case LEXER_LEFT_BRACE: { parser_parse_object_literal (context_p); @@ -1165,6 +1158,13 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */ parser_emit_cbc (context_p, CBC_PUSH_NULL); break; } +#ifndef CONFIG_DISABLE_ES2015_CLASS + case LEXER_KEYW_CLASS: + { + parser_parse_class (context_p, false); + return; + } +#endif /* !CONFIG_DISABLE_ES2015_CLASS */ #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION case LEXER_RIGHT_PAREN: { diff --git a/jerry-core/parser/js/js-parser-internal.h b/jerry-core/parser/js/js-parser-internal.h index fd7e54055b..a4b0964f89 100644 --- a/jerry-core/parser/js/js-parser-internal.h +++ b/jerry-core/parser/js/js-parser-internal.h @@ -454,7 +454,7 @@ bool lexer_construct_number_object (parser_context_t *context_p, bool is_expr, b void lexer_convert_push_number_to_push_literal (parser_context_t *context_p); uint16_t lexer_construct_function_object (parser_context_t *context_p, uint32_t extra_status_flags); void lexer_construct_regexp_object (parser_context_t *context_p, bool parse_only); -bool lexer_compare_identifier_to_current (parser_context_t *context_p, const lexer_lit_location_t *right); +bool lexer_compare_identifier_to_current (parser_context_t *context_p, const lexer_lit_location_t *right_ident_p); bool lexer_compare_raw_identifier_to_current (parser_context_t *context_p, const char *right_ident_p, size_t right_ident_length); @@ -468,6 +468,9 @@ bool lexer_compare_raw_identifier_to_current (parser_context_t *context_p, const /* Parser functions. */ void parser_parse_expression (parser_context_t *context_p, int options); +#ifndef CONFIG_DISABLE_ES2015_CLASS +void parser_parse_class (parser_context_t *context_p, bool is_statement); +#endif /* !CONFIG_DISABLE_ES2015_CLASS */ /** * @} @@ -486,9 +489,6 @@ void parser_scan_until (parser_context_t *context_p, lexer_range_t *range_p, lex */ void parser_parse_statements (parser_context_t *context_p); -#ifndef CONFIG_DISABLE_ES2015_CLASS -void parser_parse_class (parser_context_t *context_p, bool is_statement); -#endif /* !CONFIG_DISABLE_ES2015_CLASS */ void parser_free_jumps (parser_stack_iterator_t iterator); /** diff --git a/jerry-core/parser/js/js-parser-scanner.c b/jerry-core/parser/js/js-parser-scanner.c index 5466310ab2..951d11a9a0 100644 --- a/jerry-core/parser/js/js-parser-scanner.c +++ b/jerry-core/parser/js/js-parser-scanner.c @@ -41,15 +41,15 @@ typedef enum #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION SCAN_MODE_ARROW_FUNCTION, /**< arrow function might follows */ #endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */ -#ifndef CONFIG_DISABLE_ES2015_CLASS - SCAN_MODE_CLASS_DECLARATION, /**< scanning class declaration */ - SCAN_MODE_CLASS_METHOD, /**< scanning class method */ -#endif /* !CONFIG_DISABLE_ES2015_CLASS */ SCAN_MODE_POST_PRIMARY_EXPRESSION, /**< scanning post primary expression */ SCAN_MODE_PRIMARY_EXPRESSION_END, /**< scanning primary expression end */ SCAN_MODE_STATEMENT, /**< scanning statement */ SCAN_MODE_FUNCTION_ARGUMENTS, /**< scanning function arguments */ SCAN_MODE_PROPERTY_NAME, /**< scanning property name */ +#ifndef CONFIG_DISABLE_ES2015_CLASS + SCAN_MODE_CLASS_DECLARATION, /**< scanning class declaration */ + SCAN_MODE_CLASS_METHOD, /**< scanning class method */ +#endif /* !CONFIG_DISABLE_ES2015_CLASS */ } scan_modes_t; /** @@ -71,7 +71,7 @@ typedef enum SCAN_STACK_TEMPLATE_STRING, /**< template string */ #endif /* !CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS */ #ifndef CONFIG_DISABLE_ES2015_CLASS - SCAN_STACK_CLASS, /**< class language element */ + SCAN_STACK_CLASS, /**< class language element */ #endif /* !CONFIG_DISABLE_ES2015_CLASS */ } scan_stack_modes_t; @@ -106,14 +106,6 @@ parser_scan_primary_expression (parser_context_t *context_p, /**< context */ *mode = SCAN_MODE_FUNCTION_ARGUMENTS; break; } -#ifndef CONFIG_DISABLE_ES2015_CLASS - case LEXER_KEYW_CLASS: - { - parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_EXPRESSION); - *mode = SCAN_MODE_CLASS_DECLARATION; - break; - } -#endif /* !CONFIG_DISABLE_ES2015_CLASS */ case LEXER_LEFT_PAREN: { parser_stack_push_uint8 (context_p, SCAN_STACK_PAREN_EXPRESSION); @@ -164,6 +156,14 @@ parser_scan_primary_expression (parser_context_t *context_p, /**< context */ *mode = SCAN_MODE_POST_PRIMARY_EXPRESSION; break; } +#ifndef CONFIG_DISABLE_ES2015_CLASS + case LEXER_KEYW_CLASS: + { + parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_EXPRESSION); + *mode = SCAN_MODE_CLASS_DECLARATION; + break; + } +#endif /* !CONFIG_DISABLE_ES2015_CLASS */ case LEXER_RIGHT_SQUARE: { if (stack_top != SCAN_STACK_SQUARE_BRACKETED_EXPRESSION) @@ -512,7 +512,7 @@ parser_scan_statement (parser_context_t *context_p, /**< context */ *mode = SCAN_MODE_POST_PRIMARY_EXPRESSION; } #ifndef CONFIG_DISABLE_ES2015_CLASS - if (stack_top == SCAN_STACK_CLASS) + else if (stack_top == SCAN_STACK_CLASS) { *mode = SCAN_MODE_CLASS_METHOD; } @@ -767,7 +767,7 @@ parser_scan_until (parser_context_t *context_p, /**< context */ || stack_top == SCAN_STACK_BLOCK_EXPRESSION || stack_top == SCAN_STACK_CLASS || stack_top == SCAN_STACK_BLOCK_PROPERTY); -#else +#else /* CONFIG_DISABLE_ES2015_CLASS */ JERRY_ASSERT (stack_top == SCAN_STACK_BLOCK_STATEMENT || stack_top == SCAN_STACK_BLOCK_EXPRESSION || stack_top == SCAN_STACK_BLOCK_PROPERTY); diff --git a/jerry-core/parser/js/js-parser-util.c b/jerry-core/parser/js/js-parser-util.c index 2aadd2744b..a0037f0100 100644 --- a/jerry-core/parser/js/js-parser-util.c +++ b/jerry-core/parser/js/js-parser-util.c @@ -898,6 +898,20 @@ parser_error_to_string (parser_error_t error) /**< error code */ { return "Case statement must be in a switch block."; } +#ifndef CONFIG_DISABLE_ES2015_CLASS + case PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS: + { + return "Multiple constructors are not allowed."; + } + case PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR: + { + return "Class constructor may not be an accessor."; + } + case PARSER_ERR_CLASS_STATIC_PROTOTYPE: + { + return "Classes may not have a static property called 'prototype'."; + } +#endif /* !CONFIG_DISABLE_ES2015_CLASS */ case PARSER_ERR_LEFT_PAREN_EXPECTED: { return "Expected '(' token."; @@ -920,20 +934,6 @@ parser_error_to_string (parser_error_t error) /**< error code */ return "Expected '}' token."; } #endif /* !CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS */ -#ifndef CONFIG_DISABLE_ES2015_CLASS - case PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTOR: - { - return "Multiple constructors are not allowed."; - } - case PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR: - { - return "Class constructor may not be an accessor."; - } - case PARSER_ERR_CLASS_STATIC_PROPERTY_NAME_PROTOTYPE: - { - return "Classes may not have a static property called 'prototype'."; - } -#endif /* !CONFIG_DISABLE_ES2015_CLASS */ case PARSER_ERR_COLON_EXPECTED: { return "Expected ':' token."; diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index bb191a9b32..b3536e1c0b 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -2541,8 +2541,7 @@ parser_parse_function (parser_context_t *context_p, /**< context */ bool is_constructor = context_p->status_flags & PARSER_CLASS_CONSTRUCTOR; JERRY_DEBUG_MSG (is_constructor ? "\n--- Class constructor parsing start ---\n\n" : "\n--- Function parsing start ---\n\n"); - -#else +#else /* CONFIG_DISABLE_ES2015_CLASS */ JERRY_DEBUG_MSG ("\n--- Function parsing start ---\n\n"); #endif /* !CONFIG_DISABLE_ES2015_CLASS */ } @@ -2646,7 +2645,7 @@ parser_parse_function (parser_context_t *context_p, /**< context */ bool is_constructor = context_p->status_flags & PARSER_CLASS_CONSTRUCTOR; JERRY_DEBUG_MSG (is_constructor ? "\n--- Class constructor parsing end ---\n\n" : "\n--- Function parsing end ---\n\n"); -#else +#else /* CONFIG_DISABLE_ES2015_CLASS */ JERRY_DEBUG_MSG ("\n--- Function parsing end ---\n\n"); #endif /* !CONFIG_DISABLE_ES2015_CLASS */ } diff --git a/jerry-core/parser/js/js-parser.h b/jerry-core/parser/js/js-parser.h index a4f6db6501..5a5fcaacb9 100644 --- a/jerry-core/parser/js/js-parser.h +++ b/jerry-core/parser/js/js-parser.h @@ -79,6 +79,11 @@ typedef enum PARSER_ERR_MULTIPLE_DEFAULTS_NOT_ALLOWED, /**< multiple default cases are not allowed */ PARSER_ERR_DEFAULT_NOT_IN_SWITCH, /**< default statement is not in switch block */ PARSER_ERR_CASE_NOT_IN_SWITCH, /**< case statement is not in switch block */ +#ifndef CONFIG_DISABLE_ES2015_CLASS + PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS, /**< multiple class constructor */ + PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR, /**< class constructor cannot be an accessor */ + PARSER_ERR_CLASS_STATIC_PROTOTYPE, /**< static method name 'prototype' is not allowed */ +#endif /* !CONFIG_DISABLE_ES2015_CLASS */ PARSER_ERR_LEFT_PAREN_EXPECTED, /**< left paren expected */ PARSER_ERR_LEFT_BRACE_EXPECTED, /**< left brace expected */ @@ -87,11 +92,6 @@ typedef enum #ifndef CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS PARSER_ERR_RIGHT_BRACE_EXPECTED, /**< right brace expected */ #endif /* !CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS */ -#ifndef CONFIG_DISABLE_ES2015_CLASS - PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTOR, /**< multiple class constructor */ - PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR, /**< class constructor cannot be an accessor */ - PARSER_ERR_CLASS_STATIC_PROPERTY_NAME_PROTOTYPE, /**< static method name 'prototype' is not allowed */ -#endif /* !CONFIG_DISABLE_ES2015_CLASS */ PARSER_ERR_COLON_EXPECTED, /**< colon expected */ PARSER_ERR_COLON_FOR_CONDITIONAL_EXPECTED, /**< colon expected for conditional expression */ PARSER_ERR_SEMICOLON_EXPECTED, /**< semicolon expected */