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:
committed by
Dániel Bátyai
parent
14e95a4775
commit
110f75c99d
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) */
|
||||
|
||||
/**
|
||||
|
||||
@@ -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:
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.";
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user