Implement parsing await. (#3738)

Several bugs fixed for parsing yield as well.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2020-05-15 22:26:05 +02:00
committed by GitHub
parent a6f6bce6f0
commit 1f00d750b7
21 changed files with 569 additions and 135 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ extern "C"
/** /**
* Jerry snapshot format version. * Jerry snapshot format version.
*/ */
#define JERRY_SNAPSHOT_VERSION (43u) #define JERRY_SNAPSHOT_VERSION (44u)
/** /**
* Flags for jerry_generate_snapshot and jerry_generate_function_snapshot. * Flags for jerry_generate_snapshot and jerry_generate_function_snapshot.
+4 -2
View File
@@ -707,9 +707,11 @@
CBC_OPCODE (CBC_EXT_CREATE_GENERATOR, CBC_NO_FLAG, 1, \ CBC_OPCODE (CBC_EXT_CREATE_GENERATOR, CBC_NO_FLAG, 1, \
VM_OC_CREATE_GENERATOR) \ VM_OC_CREATE_GENERATOR) \
CBC_OPCODE (CBC_EXT_YIELD, CBC_NO_FLAG, 0, \ CBC_OPCODE (CBC_EXT_YIELD, CBC_NO_FLAG, 0, \
VM_OC_YIELD | VM_OC_GET_STACK) \ VM_OC_YIELD) \
CBC_OPCODE (CBC_EXT_YIELD_ITERATOR, CBC_NO_FLAG, 0, \ CBC_OPCODE (CBC_EXT_YIELD_ITERATOR, CBC_NO_FLAG, 0, \
VM_OC_YIELD | VM_OC_GET_STACK) \ VM_OC_YIELD) \
CBC_OPCODE (CBC_EXT_AWAIT, CBC_NO_FLAG, 0, \
VM_OC_AWAIT) \
CBC_OPCODE (CBC_EXT_RETURN, CBC_NO_FLAG, -1, \ CBC_OPCODE (CBC_EXT_RETURN, CBC_NO_FLAG, -1, \
VM_OC_EXT_RETURN | VM_OC_GET_STACK) \ VM_OC_EXT_RETURN | VM_OC_GET_STACK) \
CBC_OPCODE (CBC_EXT_RETURN_PROMISE, CBC_NO_FLAG, -1, \ CBC_OPCODE (CBC_EXT_RETURN_PROMISE, CBC_NO_FLAG, -1, \
+98 -13
View File
@@ -817,6 +817,29 @@ lexer_parse_identifier (parser_context_t *context_p, /**< context */
if (JERRY_LIKELY (keyword_p->type < LEXER_FIRST_NON_RESERVED_KEYWORD)) if (JERRY_LIKELY (keyword_p->type < LEXER_FIRST_NON_RESERVED_KEYWORD))
{ {
#if ENABLED (JERRY_ES2015)
if (JERRY_UNLIKELY (keyword_p->type == LEXER_KEYW_AWAIT))
{
if (!(context_p->status_flags & PARSER_IS_ASYNC_FUNCTION)
&& !(context_p->global_status_flags & ECMA_PARSE_MODULE))
{
break;
}
if (context_p->status_flags & PARSER_DISALLOW_AWAIT_YIELD)
{
if (ident_start_p == buffer_p)
{
parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD);
}
parser_raise_error (context_p, PARSER_ERR_AWAIT_NOT_ALLOWED);
}
context_p->token.type = (uint8_t) LEXER_KEYW_AWAIT;
break;
}
#endif /* ENABLED (JERRY_ES2015) */
if (ident_start_p == buffer_p) if (ident_start_p == buffer_p)
{ {
/* Escape sequences are not allowed in a keyword. */ /* Escape sequences are not allowed in a keyword. */
@@ -828,30 +851,31 @@ lexer_parse_identifier (parser_context_t *context_p, /**< context */
} }
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
if (keyword_p->type == LEXER_KEYW_YIELD && (context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)) if (keyword_p->type == LEXER_KEYW_LET && (context_p->status_flags & PARSER_IS_STRICT))
{ {
if (ident_start_p == buffer_p) if (ident_start_p == buffer_p)
{ {
parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD); parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD);
} }
if (context_p->status_flags & PARSER_DISALLOW_YIELD) context_p->token.type = (uint8_t) LEXER_KEYW_LET;
break;
}
if (keyword_p->type == LEXER_KEYW_YIELD && (context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION))
{ {
if (context_p->status_flags & PARSER_DISALLOW_AWAIT_YIELD)
{
if (ident_start_p == buffer_p)
{
parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD);
}
parser_raise_error (context_p, PARSER_ERR_YIELD_NOT_ALLOWED); parser_raise_error (context_p, PARSER_ERR_YIELD_NOT_ALLOWED);
} }
context_p->token.type = (uint8_t) LEXER_KEYW_YIELD; context_p->token.type = (uint8_t) LEXER_KEYW_YIELD;
break; break;
} }
if (keyword_p->type == LEXER_KEYW_LET && ident_start_p != buffer_p)
{
if (context_p->status_flags & PARSER_IS_STRICT)
{
context_p->token.type = (uint8_t) LEXER_KEYW_LET;
}
break;
}
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
if (keyword_p->type >= LEXER_FIRST_FUTURE_STRICT_RESERVED_WORD if (keyword_p->type >= LEXER_FIRST_FUTURE_STRICT_RESERVED_WORD
@@ -1948,8 +1972,11 @@ lexer_check_yield_no_arg (parser_context_t *context_p) /**< context */
bool bool
lexer_consume_generator (parser_context_t *context_p) /**< context */ lexer_consume_generator (parser_context_t *context_p) /**< context */
{ {
JERRY_ASSERT (context_p->token.flags & LEXER_NO_SKIP_SPACES); if (!(context_p->token.flags & LEXER_NO_SKIP_SPACES))
JERRY_ASSERT (context_p->token.type == LEXER_KEYW_ASYNC); {
lexer_skip_spaces (context_p);
context_p->token.flags = (uint8_t) (context_p->token.flags | LEXER_NO_SKIP_SPACES);
}
if (context_p->source_p >= context_p->source_end_p if (context_p->source_p >= context_p->source_end_p
|| context_p->source_p[0] != LIT_CHAR_ASTERISK || context_p->source_p[0] != LIT_CHAR_ASTERISK
@@ -1964,6 +1991,54 @@ lexer_consume_generator (parser_context_t *context_p) /**< context */
return true; return true;
} /* lexer_consume_generator */ } /* lexer_consume_generator */
/**
* Update await / yield keywords after an arrow function with expression.
*/
void
lexer_update_await_yield (parser_context_t *context_p, /**< context */
uint32_t status_flags) /**< parser status flags after restore */
{
if (!(status_flags & PARSER_IS_STRICT))
{
if (status_flags & PARSER_IS_GENERATOR_FUNCTION)
{
if (context_p->token.type == LEXER_LITERAL
&& context_p->token.keyword_type == LEXER_KEYW_YIELD)
{
context_p->token.type = LEXER_KEYW_YIELD;
}
}
else
{
if (context_p->token.type == LEXER_KEYW_YIELD)
{
JERRY_ASSERT (context_p->token.keyword_type == LEXER_KEYW_YIELD);
context_p->token.type = LEXER_LITERAL;
}
}
}
if (!(context_p->global_status_flags & ECMA_PARSE_MODULE))
{
if (status_flags & PARSER_IS_ASYNC_FUNCTION)
{
if (context_p->token.type == LEXER_LITERAL
&& context_p->token.keyword_type == LEXER_KEYW_AWAIT)
{
context_p->token.type = LEXER_KEYW_AWAIT;
}
}
else
{
if (context_p->token.type == LEXER_KEYW_AWAIT)
{
JERRY_ASSERT (context_p->token.keyword_type == LEXER_KEYW_AWAIT);
context_p->token.type = LEXER_LITERAL;
}
}
}
} /* lexer_update_await_yield */
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
/** /**
@@ -2853,6 +2928,16 @@ lexer_expect_identifier (parser_context_t *context_p, /**< context */
} }
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ #endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
#if ENABLED (JERRY_ES2015)
if (context_p->token.type == LEXER_KEYW_YIELD)
{
parser_raise_error (context_p, PARSER_ERR_YIELD_NOT_ALLOWED);
}
if (context_p->token.type == LEXER_KEYW_AWAIT)
{
parser_raise_error (context_p, PARSER_ERR_AWAIT_NOT_ALLOWED);
}
#endif /* ENABLED (JERRY_ES2015) */
parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
} /* lexer_expect_identifier */ } /* lexer_expect_identifier */
+3 -4
View File
@@ -58,6 +58,9 @@ typedef enum
LEXER_BIT_NOT, /**< "~" */ LEXER_BIT_NOT, /**< "~" */
LEXER_KEYW_VOID, /**< void */ LEXER_KEYW_VOID, /**< void */
LEXER_KEYW_TYPEOF, /**< typeof */ LEXER_KEYW_TYPEOF, /**< typeof */
#if ENABLED (JERRY_ES2015)
LEXER_KEYW_AWAIT, /**< await */
#endif /* ENABLED (JERRY_ES2015) */
LEXER_KEYW_DELETE, /**< delete */ LEXER_KEYW_DELETE, /**< delete */
LEXER_INCREASE, /**< "++" */ LEXER_INCREASE, /**< "++" */
LEXER_DECREASE, /**< "--" */ LEXER_DECREASE, /**< "--" */
@@ -164,9 +167,6 @@ typedef enum
LEXER_KEYW_EXPORT, /**< export */ LEXER_KEYW_EXPORT, /**< export */
LEXER_KEYW_IMPORT, /**< import */ LEXER_KEYW_IMPORT, /**< import */
LEXER_KEYW_ENUM, /**< enum */ LEXER_KEYW_ENUM, /**< enum */
#if ENABLED (JERRY_ES2015)
LEXER_KEYW_AWAIT, /**< await */
#endif /* ENABLED (JERRY_ES2015) */
/* These are virtual tokens. */ /* These are virtual tokens. */
LEXER_EXPRESSION_START, /**< expression start */ LEXER_EXPRESSION_START, /**< expression start */
@@ -177,7 +177,6 @@ typedef enum
LEXER_ASSIGN_CONST, /**< a const binding is reassigned */ LEXER_ASSIGN_CONST, /**< a const binding is reassigned */
LEXER_CLASS_CONSTRUCTOR, /**< special value for class constructor method */ LEXER_CLASS_CONSTRUCTOR, /**< special value for class constructor method */
LEXER_INVALID_PATTERN, /**< special value for invalid destructuring pattern */ LEXER_INVALID_PATTERN, /**< special value for invalid destructuring pattern */
LEXER_ARROW_LEFT_PAREN, /**< start of arrow function argument list */
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
+82 -30
View File
@@ -644,8 +644,14 @@ parser_parse_class_literal (parser_context_t *context_p, /**< context */
} }
} }
status_flags &= (uint32_t) ~(PARSER_IS_GENERATOR_FUNCTION
| PARSER_IS_ASYNC_FUNCTION
| PARSER_DISALLOW_AWAIT_YIELD);
if (context_p->token.type == LEXER_KEYW_ASYNC) if (context_p->token.type == LEXER_KEYW_ASYNC)
{ {
status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
if (!lexer_consume_generator (context_p)) if (!lexer_consume_generator (context_p))
{ {
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS); lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
@@ -655,11 +661,7 @@ parser_parse_class_literal (parser_context_t *context_p, /**< context */
if (context_p->token.type == LEXER_MULTIPLY) if (context_p->token.type == LEXER_MULTIPLY)
{ {
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS); lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_YIELD; status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
}
else
{
status_flags &= (uint32_t) ~(PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_YIELD);
} }
if (context_p->token.type == LEXER_RIGHT_SQUARE) if (context_p->token.type == LEXER_RIGHT_SQUARE)
@@ -1006,17 +1008,19 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
break; break;
} }
case LEXER_KEYW_ASYNC: case LEXER_KEYW_ASYNC:
{
lexer_consume_generator (context_p);
/* FALLTHRU */
}
case LEXER_MULTIPLY: case LEXER_MULTIPLY:
{ {
uint32_t status_flags = PARSER_FUNCTION_CLOSURE; uint32_t status_flags = PARSER_FUNCTION_CLOSURE;
if (context_p->token.type == LEXER_KEYW_ASYNC)
{
status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
lexer_consume_generator (context_p);
}
if (context_p->token.type == LEXER_MULTIPLY) if (context_p->token.type == LEXER_MULTIPLY)
{ {
status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_YIELD; status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
} }
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS); lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
@@ -1164,8 +1168,15 @@ parser_parse_function_expression (parser_context_t *context_p, /**< context */
uint16_t function_literal_index; uint16_t function_literal_index;
int32_t function_name_index = -1; int32_t function_name_index = -1;
#if !ENABLED (JERRY_ES2015)
JERRY_ASSERT (status_flags & PARSER_IS_FUNC_EXPRESSION);
#endif /* !ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_ES2015)
if (status_flags & PARSER_IS_FUNC_EXPRESSION) if (status_flags & PARSER_IS_FUNC_EXPRESSION)
{ {
#endif /* !ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_DEBUGGER) #if ENABLED (JERRY_DEBUGGER)
parser_line_counter_t debugger_line = context_p->token.line; parser_line_counter_t debugger_line = context_p->token.line;
parser_line_counter_t debugger_column = context_p->token.column; parser_line_counter_t debugger_column = context_p->token.column;
@@ -1174,16 +1185,21 @@ parser_parse_function_expression (parser_context_t *context_p, /**< context */
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
uint32_t parent_status_flags = context_p->status_flags; uint32_t parent_status_flags = context_p->status_flags;
if (lexer_check_next_character (context_p, LIT_CHAR_ASTERISK)) context_p->status_flags &= (uint32_t) ~(PARSER_IS_ASYNC_FUNCTION
| PARSER_IS_GENERATOR_FUNCTION
| PARSER_DISALLOW_AWAIT_YIELD);
if (status_flags & PARSER_IS_ASYNC_FUNCTION)
{
/* The name of the function cannot be await. */
context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
}
if (lexer_consume_generator (context_p))
{ {
/* The name of the function cannot be yield. */ /* The name of the function cannot be yield. */
context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_YIELD; context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_YIELD; status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
lexer_consume_next_character (context_p);
}
else
{
context_p->status_flags &= (uint32_t) ~(PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_YIELD);
} }
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
@@ -1225,8 +1241,8 @@ parser_parse_function_expression (parser_context_t *context_p, /**< context */
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
context_p->status_flags = parent_status_flags; context_p->status_flags = parent_status_flags;
#endif /* ENABLED (JERRY_ES2015) */
} }
#endif /* ENABLED (JERRY_ES2015) */
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
{ {
@@ -1486,13 +1502,28 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
while (true) while (true)
{ {
/* Convert plus and minus binary operators to unary operators. */ /* Convert plus and minus binary operators to unary operators. */
if (context_p->token.type == LEXER_ADD) switch (context_p->token.type)
{
case LEXER_ADD:
{ {
context_p->token.type = LEXER_PLUS; context_p->token.type = LEXER_PLUS;
break;
} }
else if (context_p->token.type == LEXER_SUBTRACT) case LEXER_SUBTRACT:
{ {
context_p->token.type = LEXER_NEGATE; context_p->token.type = LEXER_NEGATE;
break;
}
#if ENABLED (JERRY_ES2015)
case LEXER_KEYW_AWAIT:
{
if (JERRY_UNLIKELY (context_p->token.lit_location.has_escape))
{
parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD);
}
break;
}
#endif /* ENABLED (JERRY_ES2015) */
} }
/* Bracketed expressions are primary expressions. At this /* Bracketed expressions are primary expressions. At this
@@ -1561,30 +1592,41 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
case LEXER_LITERAL: case LEXER_LITERAL:
{ {
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
if (context_p->next_scanner_info_p->source_p == context_p->source_p) if (JERRY_UNLIKELY (context_p->next_scanner_info_p->source_p == context_p->source_p))
{ {
JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION); JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
uint32_t arrow_status_flags = (PARSER_IS_FUNCTION | PARSER_IS_ARROW_FUNCTION);
if (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC) if (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC)
{ {
JERRY_ASSERT (lexer_token_is_async (context_p)); JERRY_ASSERT (lexer_token_is_async (context_p));
JERRY_ASSERT (!(context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_STATEMENT)); JERRY_ASSERT (!(context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_STATEMENT));
uint32_t saved_status_flags = context_p->status_flags;
context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
lexer_next_token (context_p); lexer_next_token (context_p);
context_p->status_flags = saved_status_flags;
if (context_p->token.type == LEXER_KEYW_FUNCTION) if (context_p->token.type == LEXER_KEYW_FUNCTION)
{ {
parser_parse_function_expression (context_p, PARSER_FUNCTION_CLOSURE | PARSER_IS_FUNC_EXPRESSION); uint32_t status_flags = (PARSER_FUNCTION_CLOSURE
| PARSER_IS_FUNC_EXPRESSION
| PARSER_IS_ASYNC_FUNCTION
| PARSER_DISALLOW_AWAIT_YIELD);
parser_parse_function_expression (context_p, status_flags);
break; break;
} }
if (context_p->token.type == LEXER_LEFT_PAREN)
{ arrow_status_flags = (PARSER_IS_FUNCTION
context_p->token.type = LEXER_ARROW_LEFT_PAREN; | PARSER_IS_ARROW_FUNCTION
} | PARSER_IS_ASYNC_FUNCTION
| PARSER_DISALLOW_AWAIT_YIELD);
} }
parser_check_assignment_expr (context_p); parser_check_assignment_expr (context_p);
parser_parse_function_expression (context_p, PARSER_IS_FUNCTION | PARSER_IS_ARROW_FUNCTION); parser_parse_function_expression (context_p, arrow_status_flags);
return parser_abort_parsing_after_arrow (context_p); return parser_abort_parsing_after_arrow (context_p);
} }
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
@@ -1789,14 +1831,18 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
parser_check_assignment_expr (context_p); parser_check_assignment_expr (context_p);
context_p->token.type = LEXER_ARROW_LEFT_PAREN;
parser_parse_function_expression (context_p, PARSER_IS_FUNCTION | PARSER_IS_ARROW_FUNCTION); parser_parse_function_expression (context_p, PARSER_IS_FUNCTION | PARSER_IS_ARROW_FUNCTION);
return parser_abort_parsing_after_arrow (context_p); return parser_abort_parsing_after_arrow (context_p);
} }
case LEXER_KEYW_YIELD: case LEXER_KEYW_YIELD:
{ {
JERRY_ASSERT ((context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION) JERRY_ASSERT ((context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)
&& !(context_p->status_flags & PARSER_DISALLOW_YIELD)); && !(context_p->status_flags & PARSER_DISALLOW_AWAIT_YIELD));
if (context_p->token.lit_location.has_escape)
{
parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD);
}
parser_check_assignment_expr (context_p); parser_check_assignment_expr (context_p);
lexer_next_token (context_p); lexer_next_token (context_p);
@@ -2216,6 +2262,12 @@ parser_process_unary_expression (parser_context_t *context_p, /**< context */
} }
parser_emit_unary_lvalue_opcode (context_p, (cbc_opcode_t) token); parser_emit_unary_lvalue_opcode (context_p, (cbc_opcode_t) token);
} }
#if ENABLED (JERRY_ES2015)
else if (JERRY_UNLIKELY (token == LEXER_KEYW_AWAIT))
{
parser_emit_cbc_ext (context_p, CBC_EXT_AWAIT);
}
#endif /* ENABLED (JERRY_ES2015) */
else else
{ {
token = (uint8_t) (LEXER_UNARY_OP_TOKEN_TO_OPCODE (token)); token = (uint8_t) (LEXER_UNARY_OP_TOKEN_TO_OPCODE (token));
+2 -1
View File
@@ -63,7 +63,7 @@ typedef enum
PARSER_IS_ARROW_FUNCTION = (1u << 13), /**< an arrow function is parsed */ PARSER_IS_ARROW_FUNCTION = (1u << 13), /**< an arrow function is parsed */
PARSER_IS_GENERATOR_FUNCTION = (1u << 14), /**< a generator function is parsed */ PARSER_IS_GENERATOR_FUNCTION = (1u << 14), /**< a generator function is parsed */
PARSER_IS_ASYNC_FUNCTION = (1u << 15), /**< an async function is parsed */ PARSER_IS_ASYNC_FUNCTION = (1u << 15), /**< an async function is parsed */
PARSER_DISALLOW_YIELD = (1u << 16), /**< throw SyntaxError for yield expression */ PARSER_DISALLOW_AWAIT_YIELD = (1u << 16), /**< throw SyntaxError for await / yield keywords */
PARSER_FUNCTION_IS_PARSING_ARGS = (1u << 17), /**< set when parsing function arguments */ PARSER_FUNCTION_IS_PARSING_ARGS = (1u << 17), /**< set when parsing function arguments */
PARSER_FUNCTION_HAS_NON_SIMPLE_PARAM = (1u << 18), /**< function has a non simple parameter */ PARSER_FUNCTION_HAS_NON_SIMPLE_PARAM = (1u << 18), /**< function has a non simple parameter */
PARSER_FUNCTION_HAS_REST_PARAM = (1u << 19), /**< function has rest parameter */ PARSER_FUNCTION_HAS_REST_PARAM = (1u << 19), /**< function has rest parameter */
@@ -681,6 +681,7 @@ bool lexer_check_arrow (parser_context_t *context_p);
bool lexer_check_arrow_param (parser_context_t *context_p); bool lexer_check_arrow_param (parser_context_t *context_p);
bool lexer_check_yield_no_arg (parser_context_t *context_p); bool lexer_check_yield_no_arg (parser_context_t *context_p);
bool lexer_consume_generator (parser_context_t *context_p); bool lexer_consume_generator (parser_context_t *context_p);
void lexer_update_await_yield (parser_context_t *context_p, uint32_t status_flags);
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
void lexer_parse_string (parser_context_t *context_p, lexer_string_options_t opts); void lexer_parse_string (parser_context_t *context_p, lexer_string_options_t opts);
void lexer_expect_identifier (parser_context_t *context_p, uint8_t literal_type); void lexer_expect_identifier (parser_context_t *context_p, uint8_t literal_type);
+23 -6
View File
@@ -684,10 +684,9 @@ parser_parse_function_statement (parser_context_t *context_p) /**< context */
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
bool is_generator_function = false; bool is_generator_function = false;
if (lexer_check_next_character (context_p, LIT_CHAR_ASTERISK)) if (lexer_consume_generator (context_p))
{ {
is_generator_function = true; is_generator_function = true;
lexer_consume_next_character (context_p);
} }
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
@@ -715,10 +714,17 @@ parser_parse_function_statement (parser_context_t *context_p) /**< context */
status_flags |= PARSER_HAS_NON_STRICT_ARG; status_flags |= PARSER_HAS_NON_STRICT_ARG;
} }
JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
if (is_generator_function) if (is_generator_function)
{ {
status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_YIELD; status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
}
if (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC)
{
status_flags |= PARSER_IS_ASYNC_FUNCTION | PARSER_DISALLOW_AWAIT_YIELD;
} }
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
@@ -3054,12 +3060,23 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
if (JERRY_UNLIKELY (lexer_token_is_async (context_p)) if (JERRY_UNLIKELY (lexer_token_is_async (context_p))
&& context_p->next_scanner_info_p->source_p == context_p->source_p) && context_p->next_scanner_info_p->source_p == context_p->source_p)
{ {
JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION); bool is_statement = true;
if (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_STATEMENT) if (context_p->next_scanner_info_p->type == SCANNER_TYPE_FUNCTION)
{ {
JERRY_ASSERT (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC); is_statement = (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_STATEMENT) != 0;
JERRY_ASSERT (!is_statement || (context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC));
}
else
{
JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_ERR_ASYNC_FUNCTION);
scanner_release_next (context_p, sizeof (scanner_info_t));
}
if (is_statement)
{
if (parser_statement_flags[context_p->stack_top_uint8] & PARSER_STATM_SINGLE_STATM) if (parser_statement_flags[context_p->stack_top_uint8] & PARSER_STATM_SINGLE_STATM)
{ {
parser_raise_error (context_p, PARSER_ERR_LEXICAL_SINGLE_STATEMENT); parser_raise_error (context_p, PARSER_ERR_LEXICAL_SINGLE_STATEMENT);
+5 -1
View File
@@ -951,7 +951,11 @@ parser_error_to_string (parser_error_t error) /**< error code */
} }
case PARSER_ERR_YIELD_NOT_ALLOWED: case PARSER_ERR_YIELD_NOT_ALLOWED:
{ {
return "Incorrect use of yield keyword."; return "Yield expression is not allowed here.";
}
case PARSER_ERR_AWAIT_NOT_ALLOWED:
{
return "Await expression is not allowed here.";
} }
case PARSER_ERR_FOR_IN_OF_DECLARATION: case PARSER_ERR_FOR_IN_OF_DECLARATION:
{ {
+8 -6
View File
@@ -1718,10 +1718,10 @@ parser_parse_function_arguments (parser_context_t *context_p, /**< context */
bool has_duplicated_arg_names = false; bool has_duplicated_arg_names = false;
/* TODO: Currently async iterators are not supported, so generators ignore the async modifier. */ /* TODO: Currently async iterators are not supported, so generators ignore the async modifier. */
if ((context_p->next_scanner_info_p->u8_arg & SCANNER_FUNCTION_ASYNC) uint32_t mask = (PARSER_IS_GENERATOR_FUNCTION | PARSER_IS_ASYNC_FUNCTION);
&& !(context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)) if ((context_p->status_flags & mask) == mask)
{ {
context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION; context_p->status_flags &= (uint32_t) ~PARSER_IS_ASYNC_FUNCTION;
} }
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
@@ -1734,7 +1734,7 @@ parser_parse_function_arguments (parser_context_t *context_p, /**< context */
parser_emit_cbc (context_p, CBC_POP); parser_emit_cbc (context_p, CBC_POP);
} }
context_p->status_flags &= (uint32_t) ~PARSER_DISALLOW_YIELD; context_p->status_flags &= (uint32_t) ~PARSER_DISALLOW_AWAIT_YIELD;
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
scanner_create_variables (context_p, SCANNER_CREATE_VARS_NO_OPTS); scanner_create_variables (context_p, SCANNER_CREATE_VARS_NO_OPTS);
return; return;
@@ -1972,7 +1972,7 @@ parser_parse_function_arguments (parser_context_t *context_p, /**< context */
} }
} }
context_p->status_flags &= (uint32_t) ~(PARSER_DISALLOW_YIELD | PARSER_FUNCTION_IS_PARSING_ARGS); context_p->status_flags &= (uint32_t) ~(PARSER_DISALLOW_AWAIT_YIELD | PARSER_FUNCTION_IS_PARSING_ARGS);
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
scanner_create_variables (context_p, SCANNER_CREATE_VARS_IS_FUNCTION_BODY); scanner_create_variables (context_p, SCANNER_CREATE_VARS_IS_FUNCTION_BODY);
@@ -2529,7 +2529,7 @@ parser_parse_arrow_function (parser_context_t *context_p, /**< context */
} }
#endif /* ENABLED (JERRY_DEBUGGER) */ #endif /* ENABLED (JERRY_DEBUGGER) */
if (context_p->token.type == LEXER_ARROW_LEFT_PAREN) if (context_p->token.type == LEXER_LEFT_PAREN)
{ {
lexer_next_token (context_p); lexer_next_token (context_p);
parser_parse_function_arguments (context_p, LEXER_RIGHT_PAREN); parser_parse_function_arguments (context_p, LEXER_RIGHT_PAREN);
@@ -2581,6 +2581,8 @@ parser_parse_arrow_function (parser_context_t *context_p, /**< context */
} }
} }
parser_flush_cbc (context_p); parser_flush_cbc (context_p);
lexer_update_await_yield (context_p, saved_context.status_flags);
} }
compiled_code_p = parser_post_processing (context_p); compiled_code_p = parser_post_processing (context_p);
+2 -1
View File
@@ -79,7 +79,8 @@ typedef enum
PARSER_ERR_ARGUMENTS_NOT_ALLOWED, /**< arguments is not allowed here in strict mode */ PARSER_ERR_ARGUMENTS_NOT_ALLOWED, /**< arguments is not allowed here in strict mode */
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
PARSER_ERR_USE_STRICT_NOT_ALLOWED, /**< use strict directive is not allowed */ PARSER_ERR_USE_STRICT_NOT_ALLOWED, /**< use strict directive is not allowed */
PARSER_ERR_YIELD_NOT_ALLOWED, /**< yield keyword is not allowed */ PARSER_ERR_YIELD_NOT_ALLOWED, /**< yield expression is not allowed */
PARSER_ERR_AWAIT_NOT_ALLOWED, /**< await expression is not allowed */
PARSER_ERR_FOR_IN_OF_DECLARATION, /**< variable declaration in for-in or for-of loop */ PARSER_ERR_FOR_IN_OF_DECLARATION, /**< variable declaration in for-in or for-of loop */
PARSER_ERR_DUPLICATED_PROTO, /**< duplicated __proto__ fields are not allowed */ PARSER_ERR_DUPLICATED_PROTO, /**< duplicated __proto__ fields are not allowed */
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
+35 -5
View File
@@ -95,10 +95,13 @@ typedef enum
SCAN_STACK_CATCH_STATEMENT, /**< catch statement */ SCAN_STACK_CATCH_STATEMENT, /**< catch statement */
SCAN_STACK_ARRAY_LITERAL, /**< array literal or destructuring assignment or binding */ SCAN_STACK_ARRAY_LITERAL, /**< array literal or destructuring assignment or binding */
SCAN_STACK_OBJECT_LITERAL, /**< object literal group */ SCAN_STACK_OBJECT_LITERAL, /**< object literal group */
SCAN_STACK_PROPERTY_ACCESSOR, /**< property accessor in squarey brackets */ SCAN_STACK_PROPERTY_ACCESSOR, /**< property accessor in square brackets */
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
/* These four must be in this order. */
SCAN_STACK_COMPUTED_PROPERTY, /**< computed property name */ SCAN_STACK_COMPUTED_PROPERTY, /**< computed property name */
SCAN_STACK_COMPUTED_GENERATOR_FUNCTION, /**< computed property name */ SCAN_STACK_COMPUTED_GENERATOR, /**< computed generator function */
SCAN_STACK_COMPUTED_ASYNC, /**< computed async function */
SCAN_STACK_COMPUTED_ASYNC_GENERATOR, /**< computed async function */
SCAN_STACK_TEMPLATE_STRING, /**< template string */ SCAN_STACK_TEMPLATE_STRING, /**< template string */
SCAN_STACK_TAGGED_TEMPLATE_LITERAL, /**< tagged template literal */ SCAN_STACK_TAGGED_TEMPLATE_LITERAL, /**< tagged template literal */
SCAN_STACK_PRIVATE_BLOCK_EARLY, /**< private block for single statements (force early declarations) */ SCAN_STACK_PRIVATE_BLOCK_EARLY, /**< private block for single statements (force early declarations) */
@@ -115,6 +118,20 @@ typedef enum
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
} scan_stack_modes_t; } scan_stack_modes_t;
/**
* Scanner context flag types.
*/
typedef enum
{
SCANNER_CONTEXT_NO_FLAGS = 0, /**< no flags are set */
#if ENABLED (JERRY_ES2015)
SCANNER_CONTEXT_THROW_ERR_ASYNC_FUNCTION = (1 << 0), /**< throw async function error */
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_DEBUGGER)
SCANNER_CONTEXT_DEBUGGER_ENABLED = (1 << 1), /**< debugger is enabled */
#endif /* ENABLED (JERRY_DEBUGGER) */
} scanner_context_flags_t;
/** /**
* Checks whether the stack top is a for statement start. * Checks whether the stack top is a for statement start.
*/ */
@@ -269,6 +286,7 @@ typedef enum
SCANNER_LITERAL_POOL_FUNCTION_STATEMENT = (1 << 8), /**< function statement */ SCANNER_LITERAL_POOL_FUNCTION_STATEMENT = (1 << 8), /**< function statement */
SCANNER_LITERAL_POOL_GENERATOR = (1 << 9), /**< generator function */ SCANNER_LITERAL_POOL_GENERATOR = (1 << 9), /**< generator function */
SCANNER_LITERAL_POOL_ASYNC = (1 << 10), /**< async function */ SCANNER_LITERAL_POOL_ASYNC = (1 << 10), /**< async function */
SCANNER_LITERAL_POOL_ASYNC_ARROW = (1 << 11), /**< can be an async arrow function */
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
} scanner_literal_pool_flags_t; } scanner_literal_pool_flags_t;
@@ -278,6 +296,18 @@ typedef enum
#define SCANNER_LITERAL_POOL_FUNCTION_WITHOUT_ARGUMENTS \ #define SCANNER_LITERAL_POOL_FUNCTION_WITHOUT_ARGUMENTS \
(SCANNER_LITERAL_POOL_FUNCTION | SCANNER_LITERAL_POOL_NO_ARGUMENTS) (SCANNER_LITERAL_POOL_FUNCTION | SCANNER_LITERAL_POOL_NO_ARGUMENTS)
/**
* Getting the generator and async properties of literal pool status flags.
*/
#define SCANNER_FROM_LITERAL_POOL_TO_COMPUTED(status_flags) \
((uint8_t) ((((status_flags) >> 9) & 0x3) + SCAN_STACK_COMPUTED_PROPERTY))
/**
* Setting the generator and async properties of literal pool status flags.
*/
#define SCANNER_FROM_COMPUTED_TO_LITERAL_POOL(mode) \
(((mode) - SCAN_STACK_COMPUTED_PROPERTY) << 9)
/** /**
* Local literal pool. * Local literal pool.
*/ */
@@ -297,11 +327,11 @@ struct scanner_context_t
{ {
uint32_t context_status_flags; /**< original status flags of the context */ uint32_t context_status_flags; /**< original status flags of the context */
uint8_t mode; /**< scanner mode */ uint8_t mode; /**< scanner mode */
#if ENABLED (JERRY_DEBUGGER)
uint8_t debugger_enabled; /**< debugger is enabled */
#endif /* ENABLED (JERRY_DEBUGGER) */
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
uint8_t binding_type; /**< current destructuring binding type */ uint8_t binding_type; /**< current destructuring binding type */
#endif /* ENABLED (JERRY_ES2015) */
uint16_t status_flags; /**< scanner status flags */
#if ENABLED (JERRY_ES2015)
scanner_binding_list_t *active_binding_list_p; /**< currently active binding list */ scanner_binding_list_t *active_binding_list_p; /**< currently active binding list */
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
scanner_literal_pool_t *active_literal_pool_p; /**< currently active literal pool */ scanner_literal_pool_t *active_literal_pool_p; /**< currently active literal pool */
+28 -12
View File
@@ -108,14 +108,24 @@ scanner_check_arrow (parser_context_t *context_p, /**< context */
} }
scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p; scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p;
uint16_t status_flags = literal_pool_p->status_flags;
literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_FUNCTION_WITHOUT_ARGUMENTS; status_flags |= SCANNER_LITERAL_POOL_FUNCTION_WITHOUT_ARGUMENTS;
literal_pool_p->status_flags &= (uint16_t) ~(SCANNER_LITERAL_POOL_IN_WITH | SCANNER_LITERAL_POOL_GENERATOR); status_flags &= (uint16_t) ~(SCANNER_LITERAL_POOL_IN_WITH
| SCANNER_LITERAL_POOL_GENERATOR
| SCANNER_LITERAL_POOL_ASYNC);
context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION; context_p->status_flags &= (uint32_t) ~(PARSER_IS_GENERATOR_FUNCTION | PARSER_IS_ASYNC_FUNCTION);
if (status_flags & SCANNER_LITERAL_POOL_ASYNC_ARROW)
{
status_flags |= SCANNER_LITERAL_POOL_ASYNC;
context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION;
}
literal_pool_p->status_flags = status_flags;
scanner_filter_arguments (context_p, scanner_context_p); scanner_filter_arguments (context_p, scanner_context_p);
scanner_check_arrow_body (context_p, scanner_context_p); scanner_check_arrow_body (context_p, scanner_context_p);
} /* scanner_check_arrow */ } /* scanner_check_arrow */
@@ -127,10 +137,19 @@ scanner_scan_simple_arrow (parser_context_t *context_p, /**< context */
scanner_context_t *scanner_context_p, /**< scanner context */ scanner_context_t *scanner_context_p, /**< scanner context */
const uint8_t *source_p) /**< identifier end position */ const uint8_t *source_p) /**< identifier end position */
{ {
scanner_literal_pool_t *literal_pool_p; uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION_WITHOUT_ARGUMENTS;
literal_pool_p = scanner_push_literal_pool (context_p,
scanner_context_p, context_p->status_flags &= (uint32_t) ~(PARSER_IS_GENERATOR_FUNCTION | PARSER_IS_ASYNC_FUNCTION);
SCANNER_LITERAL_POOL_FUNCTION_WITHOUT_ARGUMENTS);
if (scanner_context_p->async_source_p != NULL)
{
JERRY_ASSERT (scanner_context_p->async_source_p == source_p);
status_flags |= SCANNER_LITERAL_POOL_ASYNC;
context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION;
}
scanner_literal_pool_t *literal_pool_p = scanner_push_literal_pool (context_p, scanner_context_p, status_flags);
literal_pool_p->source_p = source_p; literal_pool_p->source_p = source_p;
lexer_lit_location_t *location_p = scanner_add_literal (context_p, scanner_context_p); lexer_lit_location_t *location_p = scanner_add_literal (context_p, scanner_context_p);
@@ -141,8 +160,6 @@ scanner_scan_simple_arrow (parser_context_t *context_p, /**< context */
PARSER_PLUS_EQUAL_LC (context_p->column, 2); PARSER_PLUS_EQUAL_LC (context_p->column, 2);
context_p->token.flags = (uint8_t) (context_p->token.flags & ~LEXER_NO_SKIP_SPACES); context_p->token.flags = (uint8_t) (context_p->token.flags & ~LEXER_NO_SKIP_SPACES);
context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION;
scanner_check_arrow_body (context_p, scanner_context_p); scanner_check_arrow_body (context_p, scanner_context_p);
} /* scanner_scan_simple_arrow */ } /* scanner_scan_simple_arrow */
@@ -266,7 +283,6 @@ scanner_check_async_function (parser_context_t *context_p, /**< context */
} }
scanner_scan_simple_arrow (context_p, scanner_context_p, scanner_context_p->async_source_p); scanner_scan_simple_arrow (context_p, scanner_context_p, scanner_context_p->async_source_p);
scanner_context_p->active_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_ASYNC;
scanner_context_p->async_source_p = NULL; scanner_context_p->async_source_p = NULL;
return false; return false;
} }
@@ -475,7 +491,7 @@ scanner_scan_bracket (parser_context_t *context_p, /**< context */
if (JERRY_UNLIKELY (scanner_context_p->async_source_p != NULL)) if (JERRY_UNLIKELY (scanner_context_p->async_source_p != NULL))
{ {
status_flags |= SCANNER_LITERAL_POOL_ASYNC; status_flags |= SCANNER_LITERAL_POOL_ASYNC_ARROW;
arrow_source_p = scanner_context_p->async_source_p; arrow_source_p = scanner_context_p->async_source_p;
scanner_context_p->async_source_p = NULL; scanner_context_p->async_source_p = NULL;
} }
+32 -4
View File
@@ -76,7 +76,7 @@ scanner_raise_error (parser_context_t *context_p) /**< context */
* Raise a variable redeclaration error. * Raise a variable redeclaration error.
*/ */
void void
scanner_raise_redeclaration_error (parser_context_t *context_p) scanner_raise_redeclaration_error (parser_context_t *context_p) /**< context */
{ {
scanner_info_t *info_p = scanner_insert_info (context_p, context_p->source_p, sizeof (scanner_info_t)); scanner_info_t *info_p = scanner_insert_info (context_p, context_p->source_p, sizeof (scanner_info_t));
info_p->type = SCANNER_TYPE_ERR_REDECLARED; info_p->type = SCANNER_TYPE_ERR_REDECLARED;
@@ -403,13 +403,31 @@ scanner_push_literal_pool (parser_context_t *context_p, /**< context */
status_flags |= SCANNER_LITERAL_POOL_NO_ARGUMENTS; status_flags |= SCANNER_LITERAL_POOL_NO_ARGUMENTS;
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
const uint16_t copied_flags = SCANNER_LITERAL_POOL_IN_WITH | SCANNER_LITERAL_POOL_GENERATOR; const uint16_t copied_flags = (SCANNER_LITERAL_POOL_IN_WITH
| SCANNER_LITERAL_POOL_GENERATOR
| SCANNER_LITERAL_POOL_ASYNC);
#else /* !ENABLED (JERRY_ES2015) */ #else /* !ENABLED (JERRY_ES2015) */
const uint16_t copied_flags = SCANNER_LITERAL_POOL_IN_WITH; const uint16_t copied_flags = SCANNER_LITERAL_POOL_IN_WITH;
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
status_flags |= (uint16_t) (prev_literal_pool_p->status_flags & copied_flags); status_flags |= (uint16_t) (prev_literal_pool_p->status_flags & copied_flags);
} }
#if ENABLED (JERRY_ES2015)
else
{
context_p->status_flags &= (uint32_t) ~(PARSER_IS_GENERATOR_FUNCTION | PARSER_IS_ASYNC_FUNCTION);
if (status_flags & SCANNER_LITERAL_POOL_GENERATOR)
{
context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION;
}
if (status_flags & SCANNER_LITERAL_POOL_ASYNC)
{
context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION;
}
}
#endif /* ENABLED (JERRY_ES2015) */
if (prev_literal_pool_p != NULL) if (prev_literal_pool_p != NULL)
{ {
@@ -486,7 +504,7 @@ scanner_pop_literal_pool (parser_context_t *context_p, /**< context */
} }
#if ENABLED (JERRY_DEBUGGER) #if ENABLED (JERRY_DEBUGGER)
if (scanner_context_p->debugger_enabled) if (scanner_context_p->status_flags & SCANNER_CONTEXT_DEBUGGER_ENABLED)
{ {
/* When debugger is enabled, identifiers are not stored in registers. However, /* When debugger is enabled, identifiers are not stored in registers. However,
* this does not affect 'eval' detection, so 'arguments' object is not created. */ * this does not affect 'eval' detection, so 'arguments' object is not created. */
@@ -899,6 +917,15 @@ scanner_pop_literal_pool (parser_context_t *context_p, /**< context */
{ {
context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION; context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION;
} }
if (prev_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_ASYNC)
{
context_p->status_flags |= PARSER_IS_ASYNC_FUNCTION;
}
else
{
context_p->status_flags &= (uint32_t) ~PARSER_IS_ASYNC_FUNCTION;
}
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
} }
@@ -1611,7 +1638,8 @@ scanner_cleanup (parser_context_t *context_p) /**< context */
JERRY_ASSERT (scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS JERRY_ASSERT (scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS
|| scanner_info_p->type == SCANNER_TYPE_LET_EXPRESSION || scanner_info_p->type == SCANNER_TYPE_LET_EXPRESSION
|| scanner_info_p->type == SCANNER_TYPE_CLASS_CONSTRUCTOR || scanner_info_p->type == SCANNER_TYPE_CLASS_CONSTRUCTOR
|| scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED); || scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED
|| scanner_info_p->type == SCANNER_TYPE_ERR_ASYNC_FUNCTION);
#else /* !ENABLED (JERRY_ES2015) */ #else /* !ENABLED (JERRY_ES2015) */
JERRY_ASSERT (scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS); JERRY_ASSERT (scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS);
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
+80 -41
View File
@@ -50,12 +50,19 @@ typedef enum
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
/** JERRY_STATIC_ASSERT (SCANNER_FROM_LITERAL_POOL_TO_COMPUTED (SCANNER_LITERAL_POOL_GENERATOR)
* Returns the correct computed property mode based on the literal_pool_flags. == SCAN_STACK_COMPUTED_GENERATOR,
*/ scanner_invalid_conversion_from_literal_pool_generator_to_computed_generator);
#define GET_COMPUTED_PROPERTY_MODE(literal_pool_flags) \ JERRY_STATIC_ASSERT (SCANNER_FROM_LITERAL_POOL_TO_COMPUTED (SCANNER_LITERAL_POOL_ASYNC)
(((literal_pool_flags) & SCANNER_LITERAL_POOL_GENERATOR) ? SCAN_STACK_COMPUTED_GENERATOR_FUNCTION \ == SCAN_STACK_COMPUTED_ASYNC,
: SCAN_STACK_COMPUTED_PROPERTY) scanner_invalid_conversion_from_literal_pool_async_to_computed_async);
JERRY_STATIC_ASSERT (SCANNER_FROM_COMPUTED_TO_LITERAL_POOL (SCAN_STACK_COMPUTED_GENERATOR)
== SCANNER_LITERAL_POOL_GENERATOR,
scanner_invalid_conversion_from_computed_generator_to_literal_pool_generator);
JERRY_STATIC_ASSERT (SCANNER_FROM_COMPUTED_TO_LITERAL_POOL (SCAN_STACK_COMPUTED_ASYNC)
== SCANNER_LITERAL_POOL_ASYNC,
scanner_invalid_conversion_from_computed_async_to_literal_pool_async);
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
@@ -93,23 +100,24 @@ scanner_scan_primary_expression (parser_context_t *context_p, /**< context */
} }
case LEXER_KEYW_FUNCTION: case LEXER_KEYW_FUNCTION:
{ {
scanner_push_literal_pool (context_p, scanner_context_p, SCANNER_LITERAL_POOL_FUNCTION); uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION;
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION; if (scanner_context_p->async_source_p != NULL)
#endif /* ENABLED (JERRY_ES2015) */
lexer_next_token (context_p);
#if ENABLED (JERRY_ES2015)
if (context_p->token.type == LEXER_MULTIPLY)
{ {
scanner_context_p->active_literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_GENERATOR; status_flags |= SCANNER_LITERAL_POOL_ASYNC;
context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION; }
lexer_next_token (context_p);
if (lexer_consume_generator (context_p))
{
status_flags |= SCANNER_LITERAL_POOL_GENERATOR;
} }
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
scanner_push_literal_pool (context_p, scanner_context_p, status_flags);
lexer_next_token (context_p);
if (context_p->token.type == LEXER_LITERAL if (context_p->token.type == LEXER_LITERAL
&& context_p->token.lit_location.type == LEXER_IDENT_LITERAL) && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
{ {
@@ -957,7 +965,9 @@ scanner_scan_primary_expression_end (parser_context_t *context_p, /**< context *
} }
return SCAN_NEXT_TOKEN; return SCAN_NEXT_TOKEN;
} }
case SCAN_STACK_COMPUTED_GENERATOR_FUNCTION: case SCAN_STACK_COMPUTED_GENERATOR:
case SCAN_STACK_COMPUTED_ASYNC:
case SCAN_STACK_COMPUTED_ASYNC_GENERATOR:
{ {
if (type != LEXER_RIGHT_SQUARE) if (type != LEXER_RIGHT_SQUARE)
{ {
@@ -970,10 +980,11 @@ scanner_scan_primary_expression_end (parser_context_t *context_p, /**< context *
JERRY_ASSERT (context_p->stack_top_uint8 == SCAN_STACK_OBJECT_LITERAL JERRY_ASSERT (context_p->stack_top_uint8 == SCAN_STACK_OBJECT_LITERAL
|| context_p->stack_top_uint8 == SCAN_STACK_FUNCTION_PROPERTY); || context_p->stack_top_uint8 == SCAN_STACK_FUNCTION_PROPERTY);
scanner_push_literal_pool (context_p, uint16_t status_flags = (uint16_t) (SCANNER_LITERAL_POOL_FUNCTION
scanner_context_p, | SCANNER_LITERAL_POOL_GENERATOR
SCANNER_LITERAL_POOL_FUNCTION | SCANNER_LITERAL_POOL_GENERATOR); | SCANNER_FROM_COMPUTED_TO_LITERAL_POOL (stack_top));
context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION;
scanner_push_literal_pool (context_p, scanner_context_p, status_flags);
scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS; scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
return SCAN_KEEP_TOKEN; return SCAN_KEEP_TOKEN;
@@ -1015,6 +1026,7 @@ scanner_scan_primary_expression_end (parser_context_t *context_p, /**< context *
{ {
scanner_pop_literal_pool (context_p, scanner_context_p); scanner_pop_literal_pool (context_p, scanner_context_p);
parser_stack_pop_uint8 (context_p); parser_stack_pop_uint8 (context_p);
lexer_update_await_yield (context_p, context_p->status_flags);
scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END; scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
return SCAN_KEEP_TOKEN; return SCAN_KEEP_TOKEN;
} }
@@ -1358,24 +1370,24 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
} }
case LEXER_KEYW_FUNCTION: case LEXER_KEYW_FUNCTION:
{ {
lexer_next_token (context_p);
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION | SCANNER_LITERAL_POOL_FUNCTION_STATEMENT; uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION | SCANNER_LITERAL_POOL_FUNCTION_STATEMENT;
if (scanner_context_p->async_source_p != NULL)
{
scanner_context_p->status_flags |= SCANNER_CONTEXT_THROW_ERR_ASYNC_FUNCTION;
status_flags |= SCANNER_LITERAL_POOL_ASYNC;
}
#endif /* ENABLED (JERRY_ES2015) */
lexer_next_token (context_p);
#if ENABLED (JERRY_ES2015)
if (context_p->token.type == LEXER_MULTIPLY) if (context_p->token.type == LEXER_MULTIPLY)
{ {
status_flags |= SCANNER_LITERAL_POOL_GENERATOR; status_flags |= SCANNER_LITERAL_POOL_GENERATOR;
lexer_next_token (context_p); lexer_next_token (context_p);
/* This flag should be set after the function name is read. */
context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION;
} }
else
{
context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION;
}
#else /* !ENABLED (JERRY_ES2015) */
uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION;
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
if (context_p->token.type != LEXER_LITERAL if (context_p->token.type != LEXER_LITERAL
@@ -1397,8 +1409,12 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
} }
literal_p->type |= SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_FUNC_DECLARATION; literal_p->type |= SCANNER_LITERAL_IS_FUNC | SCANNER_LITERAL_IS_FUNC_DECLARATION;
scanner_context_p->status_flags &= (uint16_t) ~SCANNER_CONTEXT_THROW_ERR_ASYNC_FUNCTION;
#else #else
literal_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_FUNC; literal_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_FUNC;
uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION;
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
scanner_push_literal_pool (context_p, scanner_context_p, status_flags); scanner_push_literal_pool (context_p, scanner_context_p, status_flags);
@@ -2254,8 +2270,12 @@ scanner_scan_all (parser_context_t *context_p, /**< context */
#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */ #endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
scanner_context.context_status_flags = context_p->status_flags; scanner_context.context_status_flags = context_p->status_flags;
scanner_context.status_flags = SCANNER_CONTEXT_NO_FLAGS;
#if ENABLED (JERRY_DEBUGGER) #if ENABLED (JERRY_DEBUGGER)
scanner_context.debugger_enabled = (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) ? 1 : 0; if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
{
scanner_context.status_flags |= SCANNER_CONTEXT_DEBUGGER_ENABLED;
}
#endif /* ENABLED (JERRY_DEBUGGER) */ #endif /* ENABLED (JERRY_DEBUGGER) */
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
scanner_context.binding_type = SCANNER_BINDING_NONE; scanner_context.binding_type = SCANNER_BINDING_NONE;
@@ -2310,6 +2330,13 @@ scanner_scan_all (parser_context_t *context_p, /**< context */
status_flags |= SCANNER_LITERAL_POOL_IS_STRICT; status_flags |= SCANNER_LITERAL_POOL_IS_STRICT;
} }
#if ENABLED (JERRY_ES2015)
if (context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)
{
status_flags |= SCANNER_LITERAL_POOL_GENERATOR;
}
#endif /* ENABLED (JERRY_ES2015) */
scanner_push_literal_pool (context_p, &scanner_context, status_flags); scanner_push_literal_pool (context_p, &scanner_context, status_flags);
scanner_context.mode = SCAN_MODE_FUNCTION_ARGUMENTS; scanner_context.mode = SCAN_MODE_FUNCTION_ARGUMENTS;
parser_stack_push_uint8 (context_p, SCAN_STACK_SCRIPT_FUNCTION); parser_stack_push_uint8 (context_p, SCAN_STACK_SCRIPT_FUNCTION);
@@ -2459,7 +2486,7 @@ scanner_scan_all (parser_context_t *context_p, /**< context */
if (context_p->token.type == LEXER_LEFT_SQUARE) if (context_p->token.type == LEXER_LEFT_SQUARE)
{ {
parser_stack_push_uint8 (context_p, GET_COMPUTED_PROPERTY_MODE (literal_pool_flags)); parser_stack_push_uint8 (context_p, SCANNER_FROM_LITERAL_POOL_TO_COMPUTED (literal_pool_flags));
scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION; scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
break; break;
} }
@@ -2889,15 +2916,10 @@ scanner_scan_all (parser_context_t *context_p, /**< context */
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
if (context_p->token.type == LEXER_LEFT_SQUARE) if (context_p->token.type == LEXER_LEFT_SQUARE)
{ {
parser_stack_push_uint8 (context_p, GET_COMPUTED_PROPERTY_MODE (literal_pool_flags)); parser_stack_push_uint8 (context_p, SCANNER_FROM_LITERAL_POOL_TO_COMPUTED (literal_pool_flags));
scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION; scanner_context.mode = SCAN_MODE_PRIMARY_EXPRESSION;
break; break;
} }
if (literal_pool_flags & SCANNER_LITERAL_POOL_GENERATOR)
{
context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION;
}
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
if (context_p->token.type != LEXER_LITERAL) if (context_p->token.type != LEXER_LITERAL)
@@ -3150,9 +3172,20 @@ scan_completed:
} }
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
/* The following loop may allocate memory, so it is enclosed in a try/catch. */ /* The following code may allocate memory, so it is enclosed in a try/catch. */
PARSER_TRY (context_p->try_buffer) PARSER_TRY (context_p->try_buffer)
{ {
#if ENABLED (JERRY_ES2015)
if (scanner_context.status_flags & SCANNER_CONTEXT_THROW_ERR_ASYNC_FUNCTION)
{
JERRY_ASSERT (scanner_context.async_source_p != NULL);
scanner_info_t *info_p;
info_p = scanner_insert_info (context_p, scanner_context.async_source_p, sizeof (scanner_info_t));
info_p->type = SCANNER_TYPE_ERR_ASYNC_FUNCTION;
}
#endif /* ENABLED (JERRY_ES2015) */
while (scanner_context.active_literal_pool_p != NULL) while (scanner_context.active_literal_pool_p != NULL)
{ {
scanner_pop_literal_pool (context_p, &scanner_context); scanner_pop_literal_pool (context_p, &scanner_context);
@@ -3426,6 +3459,12 @@ scan_completed:
(int) (info_p->source_p - source_start_p)); (int) (info_p->source_p - source_start_p));
break; break;
} }
case SCANNER_TYPE_ERR_ASYNC_FUNCTION:
{
JERRY_DEBUG_MSG (" ERR_ASYNC_FUNCTION: source:%d\n",
(int) (info_p->source_p - source_start_p));
break;
}
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
} }
+1
View File
@@ -49,6 +49,7 @@ typedef enum
SCANNER_TYPE_CLASS_CONSTRUCTOR, /**< class constructor */ SCANNER_TYPE_CLASS_CONSTRUCTOR, /**< class constructor */
SCANNER_TYPE_LET_EXPRESSION, /**< let expression */ SCANNER_TYPE_LET_EXPRESSION, /**< let expression */
SCANNER_TYPE_ERR_REDECLARED, /**< syntax error: a variable is redeclared */ SCANNER_TYPE_ERR_REDECLARED, /**< syntax error: a variable is redeclared */
SCANNER_TYPE_ERR_ASYNC_FUNCTION, /**< an invalid async function follows */
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
} scanner_info_type_t; } scanner_info_type_t;
+6 -2
View File
@@ -1990,8 +1990,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
frame_ctx_p->call_operation = VM_EXEC_RETURN; frame_ctx_p->call_operation = VM_EXEC_RETURN;
frame_ctx_p->byte_code_p = byte_code_p; frame_ctx_p->byte_code_p = byte_code_p;
frame_ctx_p->stack_top_p = stack_top_p; frame_ctx_p->stack_top_p = --stack_top_p;
return left_value; return *stack_top_p;
}
case VM_OC_AWAIT:
{
continue;
} }
case VM_OC_EXT_RETURN: case VM_OC_EXT_RETURN:
{ {
+2
View File
@@ -265,6 +265,7 @@ typedef enum
VM_OC_SPREAD_ARGUMENTS, /**< perform function call/construct with spreaded arguments */ VM_OC_SPREAD_ARGUMENTS, /**< perform function call/construct with spreaded arguments */
VM_OC_CREATE_GENERATOR, /**< create a generator object */ VM_OC_CREATE_GENERATOR, /**< create a generator object */
VM_OC_YIELD, /**< yield operation */ VM_OC_YIELD, /**< yield operation */
VM_OC_AWAIT, /**< await operation */
VM_OC_EXT_RETURN, /**< return which also clears the stack */ VM_OC_EXT_RETURN, /**< return which also clears the stack */
VM_OC_RETURN_PROMISE, /**< return from an async function */ VM_OC_RETURN_PROMISE, /**< return from an async function */
VM_OC_STRING_CONCAT, /**< string concatenation */ VM_OC_STRING_CONCAT, /**< string concatenation */
@@ -329,6 +330,7 @@ typedef enum
VM_OC_SPREAD_ARGUMENTS = VM_OC_NONE, /**< perform function call/construct with spreaded arguments */ VM_OC_SPREAD_ARGUMENTS = VM_OC_NONE, /**< perform function call/construct with spreaded arguments */
VM_OC_CREATE_GENERATOR = VM_OC_NONE, /**< create a generator object */ VM_OC_CREATE_GENERATOR = VM_OC_NONE, /**< create a generator object */
VM_OC_YIELD = VM_OC_NONE, /**< yield operation */ VM_OC_YIELD = VM_OC_NONE, /**< yield operation */
VM_OC_AWAIT = VM_OC_NONE, /**< await operation */
VM_OC_EXT_RETURN = VM_OC_NONE, /**< return which also clears the stack */ VM_OC_EXT_RETURN = VM_OC_NONE, /**< return which also clears the stack */
VM_OC_RETURN_PROMISE = VM_OC_NONE, /**< return from an async function */ VM_OC_RETURN_PROMISE = VM_OC_NONE, /**< return from an async function */
VM_OC_STRING_CONCAT = VM_OC_NONE, /**< string concatenation */ VM_OC_STRING_CONCAT = VM_OC_NONE, /**< string concatenation */
+138
View File
@@ -0,0 +1,138 @@
// 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 test checks await expressions (nothing else). */
function check_syntax_error (code)
{
try {
eval (code)
assert (false)
} catch (e) {
assert (e instanceof SyntaxError)
}
}
check_syntax_error("(async function await() {})")
check_syntax_error("(async function *await() {})")
check_syntax_error("async function f(await) {}")
check_syntax_error("(async function f(await) {})")
check_syntax_error("async function f(a = await new Promise) {}")
check_syntax_error("async function f() { function await() {} }")
check_syntax_error("async await => 0");
check_syntax_error("async (await) => 0");
check_syntax_error("async function f() { await () => 0 }");
check_syntax_error("async (a) => a\\u0077ait a");
check_syntax_error("async (a) => { () => 0\na\\u0077ait a }");
// Valid uses of await
async a => await a
async a => { await a }
async (a) => await a
async(a) => { await a }
// Nested async and non-async functions
async (a) => {
() => await
await a
}
(a) => {
await
async (a) => await a
await
async (a) => await a
a\u0077ait
}
async function f1(a) {
await a
(function () { await ? async function(a) { await a } : await })
await a
}
async (a) => {
await a;
() => await ? async (a) => await a : await
await a
}
async (a) => {
(a = () => await, [b] = (c))
await a
(a, b = () => await)
await a
}
// Object initializers
var o = {
async await(a) {
await a;
() => await
await a
},
f(a) {
await
async (a) => await a
await
async (a) => await a
a\u0077ait
},
async ["g"] () {
await a;
() => await
await a
}
}
async function f2(a) {
var o = {
[await a]() { await % await }
}
await a;
}
class C {
async await(a) {
await a;
() => await
await a
}
f(a) {
await
async (a) => await a
await
async (a) => await a
a\u0077ait
}
async ["g"] () {
await a;
() => await
await a
}
}
async function f3(a) {
class C {
[await a]() { await % await }
}
await a;
}
+1 -1
View File
@@ -43,7 +43,7 @@
// Test %GeneratorPrototype% prototype chain // Test %GeneratorPrototype% prototype chain
(function () { (function () {
function* g(){} function* g(){}
var iterator = new g.constructor("a","b","c","yield a; yield b; yield c;")(1,2,3); var iterator = new g.constructor("a","b","c","() => yield\n yield a; yield b; yield c;")(1,2,3);
var item = iterator.next(); var item = iterator.next();
assert(item.value === 1); assert(item.value === 1);
+13
View File
@@ -58,6 +58,7 @@ check_syntax_error("function *gen(){ (yield\n1) }");
check_syntax_error("function *gen(){ function yield() {} }"); check_syntax_error("function *gen(){ function yield() {} }");
check_syntax_error("function *gen(){ (yield)=>1 }"); check_syntax_error("function *gen(){ (yield)=>1 }");
check_syntax_error("function *gen(){ yield => 1 }"); check_syntax_error("function *gen(){ yield => 1 }");
check_syntax_error("function *gen(){ yi\\u0065ld 1 }");
function *gen4() { function *gen4() {
var f = function yield(i) { var f = function yield(i) {
@@ -71,3 +72,15 @@ function *gen4() {
} }
assert(gen4().next().value === 39); assert(gen4().next().value === 39);
(function *() {
() => yield
yield 1;
})
function *gen5() {
var o = {
["f"]() { yield % yield }
}
yield 1;
}
+1 -1
View File
@@ -223,7 +223,7 @@ main (void)
/* Check the snapshot data. Unused bytes should be filled with zeroes */ /* Check the snapshot data. Unused bytes should be filled with zeroes */
const uint8_t expected_data[] = const uint8_t expected_data[] =
{ {
0x4A, 0x52, 0x52, 0x59, 0x2B, 0x00, 0x00, 0x00, 0x4A, 0x52, 0x52, 0x59, 0x2C, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x03, 0x00, 0x01, 0x00, 0x41, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x41, 0x00, 0x01, 0x00,