Fix pre-scanner function name parsing. (#3093)

The function names of classes were incorrectly parsed.
Also made the parsing more strict (more issues were captured by the pre-scanner).

Fixes #3088
Fixes #3089

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2019-09-11 16:55:58 +02:00
committed by Dániel Bátyai
parent fbde788d1f
commit f3d3c34c30
4 changed files with 97 additions and 33 deletions
+16
View File
@@ -2447,6 +2447,22 @@ lexer_scan_identifier (parser_context_t *context_p, /**< context */
return;
}
}
#if ENABLED (JERRY_ES2015_CLASS)
if (ident_opts & LEXER_SCAN_CLASS_PROPERTY)
{
lexer_next_token (context_p);
if (context_p->token.type == LEXER_LITERAL
#if ENABLED (JERRY_ES2015_OBJECT_INITIALIZER)
|| context_p->token.type == LEXER_LEFT_SQUARE
#endif /* ENABLED (JERRY_ES2015_OBJECT_INITIALIZER) */
|| context_p->token.type == LEXER_RIGHT_BRACE
|| context_p->token.type == LEXER_SEMICOLON)
{
return;
}
}
#endif /* ENABLED (JERRY_ES2015_CLASS) */
parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
} /* lexer_scan_identifier */
+4 -1
View File
@@ -262,7 +262,10 @@ typedef enum
{
LEXER_SCAN_IDENT_NO_OPTS = (1u << 0), /**< no options */
LEXER_SCAN_IDENT_PROPERTY = (1u << 1), /**< scan valid property names */
LEXER_SCAN_IDENT_NO_KEYW = (1u << 2), /**< don\t scan keywords (e.g. get/set) */
LEXER_SCAN_IDENT_NO_KEYW = (1u << 2), /**< don't scan keywords (e.g. get/set) */
#if ENABLED (JERRY_ES2015_CLASS)
LEXER_SCAN_CLASS_PROPERTY = (1u << 3), /**< scan valid class property names */
#endif /* ENABLED (JERRY_ES2015_CLASS) */
} lexer_scan_ident_opts_t;
/**
+60 -32
View File
@@ -80,7 +80,7 @@ typedef enum
SCAN_STACK_ARROW_EXPRESSION, /**< (possible) arrow function */
#endif /* ENABLED (JERRY_ES2015_ARROW_FUNCTION) */
#if ENABLED (JERRY_ES2015_CLASS)
SCAN_STACK_CLASS, /**< class language element */
SCAN_STACK_CLASS_FUNCTION, /**< class function expression */
SCAN_STACK_CLASS_EXTENDS, /**< class extends expression */
#endif /* ENABLED (JERRY_ES2015_CLASS) */
#if ENABLED (JERRY_ES2015_FUNCTION_PARAMETER_INITIALIZER)
@@ -180,9 +180,16 @@ scanner_scan_primary_expression (parser_context_t *context_p, /**< context */
}
case LEXER_KEYW_FUNCTION:
{
lexer_next_token (context_p);
if (context_p->token.type == LEXER_LITERAL
&& context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
{
lexer_next_token (context_p);
}
parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_EXPRESSION);
scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
break;
return true;
}
case LEXER_LEFT_PAREN:
{
@@ -441,7 +448,7 @@ scanner_scan_primary_expression_end (parser_context_t *context_p, /**< context *
case SCAN_STACK_BLOCK_EXPRESSION:
case SCAN_STACK_BLOCK_PROPERTY:
#if ENABLED (JERRY_ES2015_CLASS)
case SCAN_STACK_CLASS:
case SCAN_STACK_CLASS_FUNCTION:
#endif /* ENABLED (JERRY_ES2015_CLASS) */
{
scanner_context_p->mode = SCAN_MODE_STATEMENT;
@@ -685,13 +692,8 @@ scanner_scan_primary_expression_end (parser_context_t *context_p, /**< context *
stack_top = (scan_stack_modes_t) context_p->stack_top_uint8;
if (stack_top == SCAN_STACK_BLOCK_PROPERTY
|| stack_top == SCAN_STACK_CLASS)
|| stack_top == SCAN_STACK_CLASS_FUNCTION)
{
if (context_p->token.type != LEXER_LEFT_PAREN)
{
scanner_raise_error (context_p);
}
scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
return true;
}
@@ -759,7 +761,7 @@ scanner_scan_primary_expression_end (parser_context_t *context_p, /**< context *
}
scanner_context_p->mode = SCAN_MODE_CLASS_METHOD;
parser_stack_pop_uint8 (context_p);
return false;
return true;
}
#endif /* ENABLED (JERRY_ES2015_CLASS) */
#if ENABLED (JERRY_ES2015_FUNCTION_PARAMETER_INITIALIZER)
@@ -983,10 +985,11 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
return true;
}
#if ENABLED (JERRY_ES2015_CLASS)
case SCAN_STACK_CLASS:
case SCAN_STACK_CLASS_FUNCTION:
{
scanner_context_p->mode = SCAN_MODE_CLASS_METHOD;
break;
parser_stack_pop_uint8 (context_p);
return true;
}
#endif /* ENABLED (JERRY_ES2015_CLASS) */
default:
@@ -1005,6 +1008,13 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
}
case LEXER_KEYW_FUNCTION:
{
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);
}
parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_STATEMENT);
scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
return false;
@@ -1142,7 +1152,30 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
if (context_p->token.type == LEXER_KEYW_DEFAULT)
{
return false;
lexer_next_token (context_p);
if (context_p->token.type == LEXER_KEYW_FUNCTION)
{
lexer_next_token (context_p);
if (context_p->token.type == LEXER_LITERAL
&& context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
{
lexer_next_token (context_p);
}
parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_EXPRESSION);
scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
return true;
}
#if ENABLED (JERRY_ES2015_CLASS)
if (context_p->token.type == LEXER_KEYW_CLASS)
{
return true;
}
#endif /* ENABLED (JERRY_ES2015_CLASS) */
scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION;
return true;
}
if (context_p->token.type == LEXER_MULTIPLY)
@@ -1331,18 +1364,20 @@ scanner_scan_all (parser_context_t *context_p) /**< context */
}
scanner_context.mode = SCAN_MODE_CLASS_METHOD;
break;
/* FALLTHRU */
}
case SCAN_MODE_CLASS_METHOD:
{
if (type == LEXER_SEMICOLON)
JERRY_ASSERT (stack_top == SCAN_STACK_BLOCK_STATEMENT || stack_top == SCAN_STACK_BLOCK_EXPRESSION);
lexer_scan_identifier (context_p, LEXER_SCAN_CLASS_PROPERTY);
if (context_p->token.type == LEXER_SEMICOLON)
{
break;
}
if (type == LEXER_RIGHT_BRACE
&& (stack_top == SCAN_STACK_BLOCK_STATEMENT
|| stack_top == SCAN_STACK_BLOCK_EXPRESSION))
if (context_p->token.type == LEXER_RIGHT_BRACE)
{
scanner_context.mode = (stack_top == SCAN_STACK_BLOCK_EXPRESSION ? SCAN_MODE_PRIMARY_EXPRESSION_END
: SCAN_MODE_STATEMENT);
@@ -1352,16 +1387,16 @@ scanner_scan_all (parser_context_t *context_p) /**< context */
if (lexer_compare_literal_to_identifier (context_p, "static", 6))
{
lexer_next_token (context_p);
lexer_scan_identifier (context_p, LEXER_SCAN_CLASS_PROPERTY);
}
if (lexer_compare_literal_to_identifier (context_p, "get", 3)
|| lexer_compare_literal_to_identifier (context_p, "set", 3))
{
lexer_next_token (context_p);
lexer_scan_identifier (context_p, LEXER_SCAN_CLASS_PROPERTY);
}
parser_stack_push_uint8 (context_p, SCAN_STACK_CLASS);
parser_stack_push_uint8 (context_p, SCAN_STACK_CLASS_FUNCTION);
#if ENABLED (JERRY_ES2015_OBJECT_INITIALIZER)
if (context_p->token.type == LEXER_LEFT_SQUARE)
@@ -1372,6 +1407,7 @@ scanner_scan_all (parser_context_t *context_p) /**< context */
}
#endif /* ENABLED (JERRY_ES2015_OBJECT_INITIALIZER) */
lexer_next_token (context_p);
scanner_context.mode = SCAN_MODE_FUNCTION_ARGUMENTS;
continue;
}
@@ -1428,7 +1464,7 @@ scanner_scan_all (parser_context_t *context_p) /**< context */
#if ENABLED (JERRY_ES2015_CLASS)
JERRY_ASSERT (stack_top == SCAN_STACK_BLOCK_STATEMENT
|| stack_top == SCAN_STACK_BLOCK_EXPRESSION
|| stack_top == SCAN_STACK_CLASS
|| stack_top == SCAN_STACK_CLASS_FUNCTION
|| stack_top == SCAN_STACK_BLOCK_PROPERTY);
#else /* !ENABLED (JERRY_ES2015_CLASS) */
JERRY_ASSERT (stack_top == SCAN_STACK_BLOCK_STATEMENT
@@ -1436,15 +1472,7 @@ scanner_scan_all (parser_context_t *context_p) /**< context */
|| stack_top == SCAN_STACK_BLOCK_PROPERTY);
#endif /* ENABLED (JERRY_ES2015_CLASS) */
if (context_p->token.type == LEXER_LITERAL
&& (context_p->token.lit_location.type == LEXER_IDENT_LITERAL
|| context_p->token.lit_location.type == LEXER_STRING_LITERAL
|| context_p->token.lit_location.type == LEXER_NUMBER_LITERAL))
{
lexer_next_token (context_p);
}
if (context_p->token.type != LEXER_LEFT_PAREN)
if (type != LEXER_LEFT_PAREN)
{
scanner_raise_error (context_p);
}
@@ -1543,7 +1571,7 @@ scanner_scan_all (parser_context_t *context_p) /**< context */
}
scanner_context.mode = SCAN_MODE_FUNCTION_ARGUMENTS;
continue;
break;
}
lexer_next_token (context_p);
+17
View File
@@ -83,12 +83,21 @@ class C {
3() {
return 3;
}
super() {
return 42;
}
return() {
return 43;
}
}
var c = new C;
assert (c.c1() === 5);
assert (c.c2() === undefined);
assert (c["3"]() === 3);
assert (c.super() === 42);
assert (c.return() === 43);
assert (c.constructor === C);
class D {
@@ -151,6 +160,10 @@ var F = class ClassF {
static 2 (a) {
return 2 * a;
}
static function(a) {
return 3 * a;
}
}
var f = new F(5);
@@ -163,6 +176,7 @@ assert (F.f3(1, 1) === 2);
assert (F.constructor(5) === 5);
assert (F.static(5) === 5);
assert (F["2"](5) === 10);
assert (F.function(5) === 15);
assert (f.constructor === F);
var G = class {
@@ -202,3 +216,6 @@ G["1"] = 20;
assert (G["1"] === 20);
G.constructor = 30;
assert (G.constructor === 30);
// Pre-scanner regression test
for (var tmp in {}) ;