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:
@@ -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.
|
||||||
|
|||||||
@@ -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, \
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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) */
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) */
|
||||||
|
|||||||
@@ -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) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user