Implement the core of the generator functions. (#3368)

Some things are missing:
 - yield* support
 - generator definition in object literal
 - the hidden GeneratorFunction

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2019-11-28 11:54:27 +01:00
committed by Dániel Bátyai
parent 14e95a4775
commit 110f75c99d
35 changed files with 1535 additions and 85 deletions
+18 -11
View File
@@ -188,18 +188,18 @@
/* Stack consumption of opcodes with context. */
/* PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION must be <= 3 */
#define PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION 3
/* PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION must be <= 4 */
#define PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION 4
/* PARSER_BLOCK_CONTEXT_STACK_ALLOCATION must be <= 3 */
#define PARSER_BLOCK_CONTEXT_STACK_ALLOCATION 1
/* PARSER_WITH_CONTEXT_STACK_ALLOCATION must be <= 4 */
#define PARSER_WITH_CONTEXT_STACK_ALLOCATION 1
/* PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION must be <= 4 */
#define PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION 1
/* PARSER_TRY_CONTEXT_STACK_ALLOCATION must be <= 3 */
#define PARSER_TRY_CONTEXT_STACK_ALLOCATION 2
/* PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION must be <= 4 */
#define PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION 4
/* PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION must be <= 3 */
#define PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION 3
/* PARSER_BLOCK_CONTEXT_STACK_ALLOCATION must be <= 3 */
#define PARSER_WITH_CONTEXT_STACK_ALLOCATION 1
/* PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION must be <= 4 */
#define PARSER_BLOCK_CONTEXT_STACK_ALLOCATION 1
/* PARSER_WITH_CONTEXT_STACK_ALLOCATION must be <= 4 */
#define PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION 1
/**
* Opcode definitions.
@@ -654,6 +654,12 @@
VM_OC_INITIALIZER_PUSH_PROP | VM_OC_GET_LITERAL) \
CBC_OPCODE (CBC_EXT_SPREAD_NEW, CBC_HAS_POP_STACK_BYTE_ARG, 0, \
VM_OC_SPREAD_ARGUMENTS | VM_OC_PUT_STACK) \
CBC_OPCODE (CBC_EXT_CREATE_GENERATOR, CBC_NO_FLAG, 0, \
VM_OC_CREATE_GENERATOR) \
CBC_OPCODE (CBC_EXT_YIELD, CBC_NO_FLAG, -1, \
VM_OC_YIELD | VM_OC_GET_STACK) \
CBC_OPCODE (CBC_EXT_CONTINUE_EXEC, CBC_NO_FLAG, 1, \
VM_OC_CONTINUE_EXEC) \
\
/* Last opcode (not a real opcode). */ \
CBC_OPCODE (CBC_EXT_END, CBC_NO_FLAG, 0, \
@@ -743,7 +749,8 @@ typedef enum
CBC_CODE_FLAGS_STATIC_FUNCTION = (1u << 8), /**< this function is a static snapshot function */
CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 9), /**< this function should be ignored by debugger */
CBC_CODE_FLAGS_CONSTRUCTOR = (1u << 10), /**< this function is a constructor */
CBC_CODE_FLAGS_REST_PARAMETER = (1u << 11), /**< this function has rest parameter */
CBC_CODE_FLAGS_GENERATOR = (1u << 11), /**< this function is a generator */
CBC_CODE_FLAGS_REST_PARAMETER = (1u << 12), /**< this function has rest parameter */
} cbc_code_flags;
/**
+45
View File
@@ -604,6 +604,19 @@ lexer_parse_identifier (parser_context_t *context_p, /**< context */
{
if (JERRY_UNLIKELY (keyword_p->type >= LEXER_FIRST_FUTURE_STRICT_RESERVED_WORD))
{
#if ENABLED (JERRY_ES2015)
if (keyword_p->type == LEXER_KEYW_YIELD && (context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION))
{
if (context_p->status_flags & PARSER_DISALLOW_YIELD)
{
parser_raise_error (context_p, PARSER_ERR_YIELD_NOT_ALLOWED);
}
context_p->token.type = (uint8_t) LEXER_KEYW_YIELD;
break;
}
#endif /* ENABLED (JERRY_ES2015) */
if (context_p->status_flags & PARSER_IS_STRICT)
{
parser_raise_error (context_p, PARSER_ERR_STRICT_IDENT_NOT_ALLOWED);
@@ -1521,6 +1534,38 @@ lexer_check_arrow_param (parser_context_t *context_p) /**< context */
|| context_p->source_p[1] != LIT_CHAR_EQUALS);
} /* lexer_check_arrow_param */
/**
* Checks whether the yield expression has no argument.
*
* @return true if it has no argument
*/
bool
lexer_check_yield_no_arg (parser_context_t *context_p) /**< context */
{
if (context_p->token.flags & LEXER_WAS_NEWLINE)
{
return true;
}
switch (context_p->token.type)
{
case LEXER_RIGHT_BRACE:
case LEXER_RIGHT_PAREN:
case LEXER_RIGHT_SQUARE:
case LEXER_COMMA:
case LEXER_COLON:
case LEXER_SEMICOLON:
case LEXER_EOS:
{
return true;
}
default:
{
return false;
}
}
} /* lexer_check_yield_no_arg */
#endif /* ENABLED (JERRY_ES2015) */
/**
+43
View File
@@ -983,6 +983,22 @@ parser_parse_function_expression (parser_context_t *context_p, /**< context */
parser_line_counter_t debugger_column = context_p->token.column;
#endif /* ENABLED (JERRY_DEBUGGER) */
#if ENABLED (JERRY_ES2015)
uint32_t parent_status_flags = context_p->status_flags;
if (lexer_check_next_character (context_p, LIT_CHAR_ASTERISK))
{
/* The name of the function cannot be yield. */
context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_YIELD;
status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_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) */
if (!lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN))
{
lexer_next_token (context_p);
@@ -1019,6 +1035,10 @@ parser_parse_function_expression (parser_context_t *context_p, /**< context */
function_name_index = context_p->lit_object.index;
}
#if ENABLED (JERRY_ES2015)
context_p->status_flags = parent_status_flags;
#endif /* ENABLED (JERRY_ES2015) */
}
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
@@ -1513,6 +1533,29 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
PARSER_IS_FUNCTION | PARSER_IS_ARROW_FUNCTION | PARSER_ARROW_PARSE_ARGS);
return parser_abort_parsing_after_arrow (context_p);
}
case LEXER_KEYW_YIELD:
{
JERRY_ASSERT ((context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)
&& !(context_p->status_flags & PARSER_DISALLOW_YIELD));
parser_check_assignment_expr (context_p);
lexer_next_token (context_p);
if (!lexer_check_yield_no_arg (context_p))
{
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
}
else
{
parser_emit_cbc (context_p, CBC_PUSH_UNDEFINED);
}
parser_emit_cbc_ext (context_p, CBC_EXT_YIELD);
parser_emit_cbc_ext (context_p, CBC_EXT_CONTINUE_EXEC);
return (context_p->token.type != LEXER_RIGHT_PAREN
&& context_p->token.type != LEXER_COMMA);
}
#endif /* ENABLED (JERRY_ES2015) */
default:
{
+20 -18
View File
@@ -55,32 +55,33 @@ typedef enum
PARSER_INSIDE_WITH = (1u << 9), /**< code block is inside a with statement */
PARSER_RESOLVE_BASE_FOR_CALLS = (1u << 10), /**< the this object must be resolved when
* a function without a base object is called */
PARSER_HAS_INITIALIZED_VARS = (1u << 11), /**< a CBC_INITIALIZE_VARS instruction must be emitted */
PARSER_HAS_LATE_LIT_INIT = (1u << 12), /**< allocate memory for this string after
PARSER_HAS_LATE_LIT_INIT = (1u << 11), /**< allocate memory for this string after
* the local parser data is freed */
PARSER_NO_END_LABEL = (1u << 13), /**< return instruction must be inserted
PARSER_NO_END_LABEL = (1u << 12), /**< return instruction must be inserted
* after the last byte code */
PARSER_DEBUGGER_BREAKPOINT_APPENDED = (1u << 14), /**< pending (unsent) breakpoint
PARSER_DEBUGGER_BREAKPOINT_APPENDED = (1u << 13), /**< pending (unsent) breakpoint
* info is available */
#if ENABLED (JERRY_ES2015)
PARSER_INSIDE_BLOCK = (1u << 15), /**< script has a lexical environment for let and const */
PARSER_IS_ARROW_FUNCTION = (1u << 16), /**< an arrow function is parsed */
PARSER_ARROW_PARSE_ARGS = (1u << 17), /**< parse the argument list of an arrow function */
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_INSIDE_BLOCK = (1u << 14), /**< script has a lexical environment for let and const */
PARSER_IS_ARROW_FUNCTION = (1u << 15), /**< an arrow function is parsed */
PARSER_ARROW_PARSE_ARGS = (1u << 16), /**< parse the argument list of an arrow function */
PARSER_IS_GENERATOR_FUNCTION = (1u << 17), /**< a generator function is parsed */
PARSER_DISALLOW_YIELD = (1u << 18), /**< throw SyntaxError for yield expression */
PARSER_FUNCTION_HAS_NON_SIMPLE_PARAM = (1u << 19), /**< function has a non simple parameter */
PARSER_FUNCTION_HAS_REST_PARAM = (1u << 20), /**< function has rest parameter */
/* These four status flags must be in this order. See PARSER_CLASS_PARSE_OPTS_OFFSET. */
PARSER_CLASS_CONSTRUCTOR = (1u << 20), /**< a class constructor is parsed (this value must be kept in
PARSER_CLASS_CONSTRUCTOR = (1u << 21), /**< a class constructor is parsed (this value must be kept in
* in sync with ECMA_PARSE_CLASS_CONSTRUCTOR) */
PARSER_CLASS_HAS_SUPER = (1u << 21), /**< class has super reference */
PARSER_CLASS_IMPLICIT_SUPER = (1u << 22), /**< class has implicit parent class */
PARSER_CLASS_STATIC_FUNCTION = (1u << 23), /**< this function is a static class method */
PARSER_CLASS_SUPER_PROP_REFERENCE = (1u << 24), /**< super property call or assignment */
PARSER_IS_EVAL = (1u << 25), /**< eval code */
PARSER_CLASS_HAS_SUPER = (1u << 22), /**< class has super reference */
PARSER_CLASS_IMPLICIT_SUPER = (1u << 23), /**< class has implicit parent class */
PARSER_CLASS_STATIC_FUNCTION = (1u << 24), /**< this function is a static class method */
PARSER_CLASS_SUPER_PROP_REFERENCE = (1u << 25), /**< super property call or assignment */
PARSER_IS_EVAL = (1u << 26), /**< eval code */
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
PARSER_IS_MODULE = (1u << 26), /**< an export / import keyword is encountered */
PARSER_MODULE_DEFAULT_CLASS_OR_FUNC = (1u << 27), /**< parsing a function or class default export */
PARSER_MODULE_STORE_IDENT = (1u << 28), /**< store identifier of the current export statement */
PARSER_IS_MODULE = (1u << 27), /**< an export / import keyword is encountered */
PARSER_MODULE_DEFAULT_CLASS_OR_FUNC = (1u << 28), /**< parsing a function or class default export */
PARSER_MODULE_STORE_IDENT = (1u << 29), /**< store identifier of the current export statement */
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
#ifndef JERRY_NDEBUG
PARSER_SCANNING_SUCCESSFUL = (1u << 30), /**< scanning process was successful */
@@ -624,6 +625,7 @@ uint8_t lexer_consume_next_character (parser_context_t *context_p);
void lexer_skip_empty_statements (parser_context_t *context_p);
bool lexer_check_arrow (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);
#endif /* ENABLED (JERRY_ES2015) */
void lexer_parse_string (parser_context_t *context_p);
void lexer_expect_identifier (parser_context_t *context_p, uint8_t literal_type);
+18 -5
View File
@@ -627,9 +627,6 @@ parser_parse_var_statement (parser_context_t *context_p) /**< context */
static void
parser_parse_function_statement (parser_context_t *context_p) /**< context */
{
uint32_t status_flags;
lexer_literal_t *literal_p;
JERRY_ASSERT (context_p->token.type == LEXER_KEYW_FUNCTION);
#if ENABLED (JERRY_ES2015)
@@ -646,6 +643,16 @@ parser_parse_function_statement (parser_context_t *context_p) /**< context */
parser_line_counter_t debugger_column = context_p->token.column;
#endif /* ENABLED (JERRY_DEBUGGER) */
#if ENABLED (JERRY_ES2015)
bool is_generator_function = false;
if (lexer_check_next_character (context_p, LIT_CHAR_ASTERISK))
{
is_generator_function = true;
lexer_consume_next_character (context_p);
}
#endif /* ENABLED (JERRY_ES2015) */
lexer_expect_identifier (context_p, LEXER_NEW_IDENT_LITERAL);
JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
&& context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
@@ -663,13 +670,19 @@ parser_parse_function_statement (parser_context_t *context_p) /**< context */
context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_STORE_IDENT);
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE;
uint32_t status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE;
if (context_p->lit_object.type != LEXER_LITERAL_OBJECT_ANY)
{
JERRY_ASSERT (context_p->lit_object.type == LEXER_LITERAL_OBJECT_EVAL
|| context_p->lit_object.type == LEXER_LITERAL_OBJECT_ARGUMENTS);
status_flags |= PARSER_HAS_NON_STRICT_ARG;
}
#if ENABLED (JERRY_ES2015)
if (is_generator_function)
{
status_flags |= PARSER_IS_GENERATOR_FUNCTION | PARSER_DISALLOW_YIELD;
}
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_DEBUGGER)
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
@@ -700,7 +713,7 @@ parser_parse_function_statement (parser_context_t *context_p) /**< context */
JERRY_ASSERT (scope_stack_p[1].map_from == PARSER_SCOPE_STACK_FUNC);
literal_p = PARSER_GET_LITERAL ((size_t) scope_stack_p[1].map_to);
lexer_literal_t *literal_p = PARSER_GET_LITERAL ((size_t) scope_stack_p[1].map_to);
JERRY_ASSERT ((literal_p->type == LEXER_UNUSED_LITERAL || literal_p->type == LEXER_FUNCTION_LITERAL)
&& literal_p->status_flags == 0);
+6
View File
@@ -932,6 +932,12 @@ parser_error_to_string (parser_error_t error) /**< error code */
{
return "Arguments is not allowed to be used here in strict mode.";
}
#if ENABLED (JERRY_ES2015)
case PARSER_ERR_YIELD_NOT_ALLOWED:
{
return "Incorrect use of yield keyword.";
}
#endif /* ENABLED (JERRY_ES2015) */
case PARSER_ERR_DELETE_IDENT_NOT_ALLOWED:
{
return "Deleting identifier is not allowed in strict mode.";
+31
View File
@@ -679,6 +679,11 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
{
JERRY_DEBUG_MSG (",constructor");
}
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_GENERATOR)
{
JERRY_DEBUG_MSG (",generator");
}
#endif /* ENABLED (JERRY_ES2015) */
JERRY_DEBUG_MSG ("]\n");
@@ -1276,6 +1281,11 @@ parser_post_processing (parser_context_t *context_p) /**< context */
compiled_code_p->status_flags |= CBC_CODE_FLAGS_CONSTRUCTOR;
}
if (context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)
{
compiled_code_p->status_flags |= CBC_CODE_FLAGS_GENERATOR;
}
if (context_p->status_flags & PARSER_FUNCTION_HAS_REST_PARAM)
{
compiled_code_p->status_flags |= CBC_CODE_FLAGS_REST_PARAMETER;
@@ -1622,6 +1632,16 @@ parser_parse_function_arguments (parser_context_t *context_p, /**< context */
if (context_p->token.type == end_type)
{
#if ENABLED (JERRY_ES2015)
if (context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)
{
parser_emit_cbc_ext (context_p, CBC_EXT_CREATE_GENERATOR);
parser_emit_cbc_ext (context_p, CBC_EXT_CONTINUE_EXEC);
parser_emit_cbc (context_p, CBC_POP);
}
context_p->status_flags &= (uint32_t) ~PARSER_DISALLOW_YIELD;
#endif /* ENABLED (JERRY_ES2015) */
scanner_create_variables (context_p, SCANNER_CREATE_VARS_NO_OPTS);
return;
}
@@ -1786,6 +1806,17 @@ parser_parse_function_arguments (parser_context_t *context_p, /**< context */
parser_raise_error (context_p, error);
}
#if ENABLED (JERRY_ES2015)
if (context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)
{
parser_emit_cbc_ext (context_p, CBC_EXT_CREATE_GENERATOR);
parser_emit_cbc_ext (context_p, CBC_EXT_CONTINUE_EXEC);
parser_emit_cbc (context_p, CBC_POP);
}
context_p->status_flags &= (uint32_t) ~PARSER_DISALLOW_YIELD;
#endif /* ENABLED (JERRY_ES2015) */
scanner_revert_active (context_p);
scanner_create_variables (context_p, SCANNER_CREATE_VARS_IS_FUNCTION_BODY);
} /* parser_parse_function_arguments */
+3
View File
@@ -73,6 +73,9 @@ typedef enum
PARSER_ERR_STRICT_IDENT_NOT_ALLOWED, /**< identifier name is reserved in strict mode */
PARSER_ERR_EVAL_NOT_ALLOWED, /**< eval is not allowed here in strict mode */
PARSER_ERR_ARGUMENTS_NOT_ALLOWED, /**< arguments is not allowed here in strict mode */
#if ENABLED (JERRY_ES2015)
PARSER_ERR_YIELD_NOT_ALLOWED, /**< yield keyword is not allowed */
#endif /* ENABLED (JERRY_ES2015) */
PARSER_ERR_DELETE_IDENT_NOT_ALLOWED, /**< identifier delete is not allowed in strict mode */
PARSER_ERR_EVAL_CANNOT_ASSIGNED, /**< eval cannot be assigned in strict mode */
PARSER_ERR_ARGUMENTS_CANNOT_ASSIGNED, /**< arguments cannot be assigned in strict mode */
@@ -175,6 +175,9 @@ typedef enum
#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
SCANNER_LITERAL_POOL_IN_EXPORT = (1 << 6), /**< the declared variables are exported by the module system */
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
#if ENABLED (JERRY_ES2015)
SCANNER_LITERAL_POOL_GENERATOR = (1 << 7), /**< generator function */
#endif /* ENABLED (JERRY_ES2015) */
} scanner_literal_pool_flags_t;
/**
+21 -4
View File
@@ -402,10 +402,13 @@ scanner_push_literal_pool (parser_context_t *context_p, /**< context */
JERRY_ASSERT (prev_literal_pool_p != NULL);
status_flags |= SCANNER_LITERAL_POOL_NO_ARGUMENTS;
if (prev_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_IN_WITH)
{
status_flags |= SCANNER_LITERAL_POOL_IN_WITH;
}
#if ENABLED (JERRY_ES2015)
const uint16_t copied_flags = SCANNER_LITERAL_POOL_IN_WITH | SCANNER_LITERAL_POOL_GENERATOR;
#else /* !ENABLED (JERRY_ES2015) */
const uint16_t copied_flags = SCANNER_LITERAL_POOL_IN_WITH;
#endif /* ENABLED (JERRY_ES2015) */
status_flags |= (uint16_t) (prev_literal_pool_p->status_flags & copied_flags);
}
parser_list_init (&literal_pool_p->literal_pool,
@@ -775,6 +778,20 @@ scanner_pop_literal_pool (parser_context_t *context_p, /**< context */
prev_literal_pool_p->no_declarations = (uint16_t) no_declarations;
}
#if ENABLED (JERRY_ES2015)
if (is_function && prev_literal_pool_p != NULL)
{
if (prev_literal_pool_p->status_flags & SCANNER_LITERAL_POOL_GENERATOR)
{
context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION;
}
else
{
context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION;
}
}
#endif /* ENABLED (JERRY_ES2015) */
scanner_context_p->active_literal_pool_p = literal_pool_p->prev_p;
parser_list_free (&literal_pool_p->literal_pool);
+55 -2
View File
@@ -179,7 +179,9 @@ scanner_process_arrow (parser_context_t *context_p, /**< context */
scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p;
literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_FUNCTION_WITHOUT_ARGUMENTS;
literal_pool_p->status_flags &= (uint16_t) ~SCANNER_LITERAL_POOL_IN_WITH;
literal_pool_p->status_flags &= (uint16_t) ~(SCANNER_LITERAL_POOL_IN_WITH | SCANNER_LITERAL_POOL_GENERATOR);
context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION;
scanner_filter_arguments (context_p, scanner_context_p);
@@ -208,6 +210,8 @@ scanner_process_simple_arrow (parser_context_t *context_p, /**< context */
PARSER_PLUS_EQUAL_LC (context_p->column, 2);
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_process_simple_arrow */
@@ -480,7 +484,21 @@ scanner_scan_primary_expression (parser_context_t *context_p, /**< context */
{
scanner_push_literal_pool (context_p, scanner_context_p, SCANNER_LITERAL_POOL_FUNCTION);
#if ENABLED (JERRY_ES2015)
context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION;
#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;
context_p->status_flags |= PARSER_IS_GENERATOR_FUNCTION;
lexer_next_token (context_p);
}
#endif /* ENABLED (JERRY_ES2015) */
if (context_p->token.type == LEXER_LITERAL
&& context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
{
@@ -609,6 +627,19 @@ scanner_scan_primary_expression (parser_context_t *context_p, /**< context */
#endif /* ENABLED (JERRY_ES2015) */
break;
}
#if ENABLED (JERRY_ES2015)
case LEXER_KEYW_YIELD:
{
lexer_next_token (context_p);
if (lexer_check_yield_no_arg (context_p))
{
scanner_context_p->mode = SCAN_MODE_PRIMARY_EXPRESSION_END;
}
return SCAN_KEEP_TOKEN;
}
#endif /* ENABLED (JERRY_ES2015) */
case LEXER_RIGHT_PAREN:
{
if (stack_top == SCAN_STACK_PAREN_EXPRESSION)
@@ -1590,6 +1621,23 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
case LEXER_KEYW_FUNCTION:
{
lexer_next_token (context_p);
uint16_t status_flags = SCANNER_LITERAL_POOL_FUNCTION;
#if ENABLED (JERRY_ES2015)
if (context_p->token.type == LEXER_MULTIPLY)
{
status_flags |= SCANNER_LITERAL_POOL_GENERATOR;
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;
}
#endif /* ENABLED (JERRY_ES2015) */
if (context_p->token.type != LEXER_LITERAL
|| context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
{
@@ -1618,7 +1666,7 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
literal_p->type |= SCANNER_LITERAL_IS_VAR | SCANNER_LITERAL_IS_FUNC;
#endif /* ENABLED (JERRY_ES2015) */
scanner_push_literal_pool (context_p, scanner_context_p, SCANNER_LITERAL_POOL_FUNCTION);
scanner_push_literal_pool (context_p, scanner_context_p, status_flags);
scanner_context_p->mode = SCAN_MODE_FUNCTION_ARGUMENTS;
parser_stack_push_uint8 (context_p, SCAN_STACK_FUNCTION_STATEMENT);
@@ -3102,6 +3150,7 @@ scan_completed:
#if ENABLED (JERRY_ES2015)
JERRY_ASSERT (scanner_context.active_binding_list_p == NULL);
JERRY_ASSERT (!(context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION));
#endif /* ENABLED (JERRY_ES2015) */
JERRY_ASSERT (scanner_context.active_literal_pool_p == NULL);
@@ -3147,6 +3196,10 @@ scan_completed:
}
}
PARSER_TRY_END
#if ENABLED (JERRY_ES2015)
context_p->status_flags &= (uint32_t) ~PARSER_IS_GENERATOR_FUNCTION;
#endif /* ENABLED (JERRY_ES2015) */
}
PARSER_TRY_END