Implement function name support for script functions and classes (#3745)
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
@@ -21,6 +21,15 @@ JERRY_STATIC_ASSERT ((sizeof (cbc_uint8_arguments_t) % sizeof (jmem_cpointer_t))
|
||||
JERRY_STATIC_ASSERT ((sizeof (cbc_uint16_arguments_t) % sizeof (jmem_cpointer_t)) == 0,
|
||||
sizeof_cbc_uint16_arguments_t_must_be_divisible_by_sizeof_jmem_cpointer_t);
|
||||
|
||||
/**
|
||||
* The reason of these two static asserts to notify the developer to increase the JERRY_SNAPSHOT_VERSION
|
||||
* whenever new bytecodes are introduced or existing ones have been deleted.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (CBC_END == 238,
|
||||
number_of_cbc_opcodes_changed);
|
||||
JERRY_STATIC_ASSERT (CBC_EXT_END == 115,
|
||||
number_of_cbc_ext_opcodes_changed);
|
||||
|
||||
#if ENABLED (JERRY_PARSER)
|
||||
|
||||
/** \addtogroup parser Parser
|
||||
|
||||
@@ -590,28 +590,38 @@
|
||||
VM_OC_THROW_CONST_ERROR) \
|
||||
CBC_OPCODE (CBC_EXT_REQUIRE_OBJECT_COERCIBLE, CBC_NO_FLAG, 0, \
|
||||
VM_OC_REQUIRE_OBJECT_COERCIBLE) \
|
||||
CBC_OPCODE (CBC_EXT_SET_FUNCTION_NAME, CBC_HAS_LITERAL_ARG, 0, \
|
||||
VM_OC_SET_FUNCTION_NAME | VM_OC_GET_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SET_CLASS_NAME, CBC_HAS_LITERAL_ARG, 0, \
|
||||
VM_OC_SET_FUNCTION_NAME) \
|
||||
CBC_OPCODE (CBC_EXT_SET_COMPUTED_FUNCTION_NAME, CBC_NO_FLAG, 0, \
|
||||
VM_OC_SET_FUNCTION_NAME) \
|
||||
CBC_OPCODE (CBC_EXT_SET_COMPUTED_GETTER_NAME, CBC_NO_FLAG, 0, \
|
||||
VM_OC_SET_FUNCTION_NAME) \
|
||||
CBC_OPCODE (CBC_EXT_SET_COMPUTED_SETTER_NAME, CBC_NO_FLAG, 0, \
|
||||
VM_OC_SET_FUNCTION_NAME) \
|
||||
\
|
||||
/* Computed / class property related opcodes. */ \
|
||||
CBC_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY, CBC_NO_FLAG, -2, \
|
||||
VM_OC_SET_COMPUTED_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_STACK) \
|
||||
CBC_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG, -1, \
|
||||
VM_OC_SET_COMPUTED_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SET_COMPUTED_GETTER, CBC_HAS_LITERAL_ARG, -1, \
|
||||
VM_OC_SET_GETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SET_COMPUTED_SETTER, CBC_HAS_LITERAL_ARG, -1, \
|
||||
VM_OC_SET_SETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SET_COMPUTED_GETTER, CBC_NO_FLAG, -2, \
|
||||
VM_OC_SET_GETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_STACK) \
|
||||
CBC_OPCODE (CBC_EXT_SET_COMPUTED_SETTER, CBC_NO_FLAG, -2, \
|
||||
VM_OC_SET_SETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_STACK) \
|
||||
CBC_OPCODE (CBC_EXT_SET_STATIC_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
|
||||
VM_OC_SET_PROPERTY | VM_OC_GET_LITERAL_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG, -1, \
|
||||
VM_OC_SET_COMPUTED_PROPERTY | VM_OC_GET_STACK_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_PROPERTY, CBC_NO_FLAG, -2, \
|
||||
VM_OC_SET_COMPUTED_PROPERTY | VM_OC_GET_STACK_STACK) \
|
||||
CBC_OPCODE (CBC_EXT_SET_STATIC_GETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
|
||||
VM_OC_SET_GETTER | VM_OC_GET_LITERAL_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SET_STATIC_SETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
|
||||
VM_OC_SET_SETTER | VM_OC_GET_LITERAL_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_GETTER, CBC_HAS_LITERAL_ARG, -1, \
|
||||
VM_OC_SET_GETTER | VM_OC_GET_STACK_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_SETTER, CBC_HAS_LITERAL_ARG, -1, \
|
||||
VM_OC_SET_SETTER | VM_OC_GET_STACK_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_GETTER, CBC_NO_FLAG, -2, \
|
||||
VM_OC_SET_GETTER | VM_OC_GET_STACK_STACK) \
|
||||
CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_SETTER, CBC_NO_FLAG, -2, \
|
||||
VM_OC_SET_SETTER | VM_OC_GET_STACK_STACK) \
|
||||
CBC_OPCODE (CBC_EXT_SET__PROTO__, CBC_NO_FLAG, -1, \
|
||||
VM_OC_SET__PROTO__ | VM_OC_GET_STACK) \
|
||||
\
|
||||
|
||||
@@ -174,6 +174,7 @@ typedef enum
|
||||
LEXER_PROPERTY_SETTER, /**< property setter function */
|
||||
LEXER_COMMA_SEP_LIST, /**< comma separated bracketed expression list */
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
LEXER_ASSIGN_GROUP_EXPR, /**< indetifier for the assignment is located in a group expression */
|
||||
LEXER_ASSIGN_CONST, /**< a const binding is reassigned */
|
||||
LEXER_CLASS_CONSTRUCTOR, /**< special value for class constructor method */
|
||||
LEXER_INVALID_PATTERN, /**< special value for invalid destructuring pattern */
|
||||
|
||||
@@ -603,7 +603,18 @@ parser_parse_class_literal (parser_context_t *context_p, /**< context */
|
||||
}
|
||||
}
|
||||
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
|
||||
if (is_computed)
|
||||
{
|
||||
parser_emit_cbc_ext (context_p, is_getter ? CBC_EXT_SET_COMPUTED_GETTER_NAME
|
||||
: CBC_EXT_SET_COMPUTED_SETTER_NAME);
|
||||
parser_emit_cbc_ext (context_p, opcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
parser_set_function_name (context_p, function_literal_index, literal_index, accessor_status_flags);
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
|
||||
}
|
||||
|
||||
is_static = false;
|
||||
continue;
|
||||
}
|
||||
@@ -693,20 +704,29 @@ parse_class_method:
|
||||
CBC_PUSH_LITERAL,
|
||||
function_literal_index);
|
||||
|
||||
if (is_computed)
|
||||
{
|
||||
parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_FUNCTION_NAME);
|
||||
parser_emit_cbc_ext (context_p, is_static ? CBC_EXT_SET_STATIC_COMPUTED_PROPERTY
|
||||
: CBC_EXT_SET_COMPUTED_PROPERTY);
|
||||
is_static = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
parser_set_function_name (context_p, function_literal_index, literal_index, 0);
|
||||
|
||||
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
|
||||
|
||||
context_p->last_cbc.value = literal_index;
|
||||
|
||||
if (is_static)
|
||||
{
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (is_computed ? CBC_EXT_SET_STATIC_COMPUTED_PROPERTY_LITERAL
|
||||
: CBC_EXT_SET_STATIC_PROPERTY_LITERAL);
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_STATIC_PROPERTY_LITERAL);
|
||||
is_static = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
context_p->last_cbc_opcode = (is_computed ? PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL)
|
||||
: CBC_SET_LITERAL_PROPERTY);
|
||||
context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
|
||||
}
|
||||
}
|
||||
} /* parser_parse_class_literal */
|
||||
@@ -721,8 +741,8 @@ parser_parse_class (parser_context_t *context_p, /**< context */
|
||||
{
|
||||
JERRY_ASSERT (context_p->token.type == LEXER_KEYW_CLASS);
|
||||
|
||||
uint16_t class_ident_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
|
||||
uint16_t class_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
|
||||
uint16_t class_ident_index = UINT16_MAX;
|
||||
uint16_t class_name_index = UINT16_MAX;
|
||||
parser_class_literal_opts_t opts = PARSER_CLASS_LITERAL_NO_OPTS;
|
||||
|
||||
if (context_p->next_scanner_info_p->source_p == context_p->source_p)
|
||||
@@ -763,14 +783,13 @@ parser_parse_class (parser_context_t *context_p, /**< context */
|
||||
/* Class expression may contain an identifier. */
|
||||
if (context_p->token.type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
|
||||
{
|
||||
/* NOTE: If 'Function.name' will be supported, the current literal object must be set to 'name' property. */
|
||||
lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL);
|
||||
class_name_index = context_p->lit_object.index;
|
||||
lexer_next_token (context_p);
|
||||
}
|
||||
}
|
||||
|
||||
if (class_name_index != PARSER_MAXIMUM_NUMBER_OF_LITERALS)
|
||||
if (class_name_index != UINT16_MAX)
|
||||
{
|
||||
parser_emit_cbc_ext_literal (context_p, CBC_EXT_PUSH_NAMED_CLASS_ENV, class_name_index);
|
||||
}
|
||||
@@ -804,9 +823,10 @@ parser_parse_class (parser_context_t *context_p, /**< context */
|
||||
/* ClassDeclaration is parsed. Continue with class body. */
|
||||
parser_parse_class_literal (context_p, opts);
|
||||
|
||||
if (class_name_index != PARSER_MAXIMUM_NUMBER_OF_LITERALS)
|
||||
if (class_name_index != UINT16_MAX)
|
||||
{
|
||||
parser_emit_cbc_ext_literal (context_p, CBC_EXT_FINALIZE_NAMED_CLASS, class_name_index);
|
||||
parser_emit_cbc_ext_literal (context_p, CBC_EXT_SET_FUNCTION_NAME, class_name_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -824,10 +844,9 @@ parser_parse_class (parser_context_t *context_p, /**< context */
|
||||
}
|
||||
|
||||
parser_emit_cbc_literal (context_p, (uint16_t) opcode, class_ident_index);
|
||||
parser_flush_cbc (context_p);
|
||||
}
|
||||
|
||||
parser_flush_cbc (context_p);
|
||||
|
||||
if (!is_strict)
|
||||
{
|
||||
/* Restore flag */
|
||||
@@ -856,6 +875,8 @@ parser_parse_object_method (parser_context_t *context_p) /**< context */
|
||||
CBC_PUSH_LITERAL,
|
||||
function_literal_index);
|
||||
|
||||
context_p->last_cbc.literal_type = LEXER_FUNCTION_LITERAL;
|
||||
|
||||
lexer_next_token (context_p);
|
||||
} /* parser_parse_object_method */
|
||||
|
||||
@@ -922,8 +943,9 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
|
||||
#if !ENABLED (JERRY_ES2015)
|
||||
parser_object_literal_item_types_t item_type;
|
||||
#endif /* !ENABLED (JERRY_ES2015) */
|
||||
bool is_getter = context_p->token.type == LEXER_PROPERTY_GETTER;
|
||||
|
||||
if (context_p->token.type == LEXER_PROPERTY_GETTER)
|
||||
if (is_getter)
|
||||
{
|
||||
status_flags = PARSER_FUNCTION_CLOSURE | PARSER_IS_PROPERTY_GETTER;
|
||||
opcode = CBC_EXT_SET_GETTER;
|
||||
@@ -946,7 +968,9 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
|
||||
uint16_t literal_index = context_p->lit_object.index;
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (context_p->token.type == LEXER_RIGHT_SQUARE)
|
||||
bool is_computed = context_p->token.type == LEXER_RIGHT_SQUARE;
|
||||
|
||||
if (is_computed)
|
||||
{
|
||||
opcode = ((opcode == CBC_EXT_SET_GETTER) ? CBC_EXT_SET_COMPUTED_GETTER
|
||||
: CBC_EXT_SET_COMPUTED_SETTER);
|
||||
@@ -969,6 +993,20 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
|
||||
literal_index);
|
||||
|
||||
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (is_computed)
|
||||
{
|
||||
parser_emit_cbc_ext (context_p, is_getter ? CBC_EXT_SET_COMPUTED_GETTER_NAME
|
||||
: CBC_EXT_SET_COMPUTED_SETTER_NAME);
|
||||
parser_emit_cbc_ext (context_p, opcode);
|
||||
lexer_next_token (context_p);
|
||||
break;
|
||||
}
|
||||
|
||||
parser_set_function_name (context_p, function_literal_index, literal_index, status_flags);
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
|
||||
context_p->last_cbc.value = function_literal_index;
|
||||
|
||||
@@ -983,9 +1021,18 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
|
||||
if (context_p->token.type == LEXER_LEFT_PAREN)
|
||||
{
|
||||
parser_parse_object_method (context_p);
|
||||
|
||||
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
|
||||
|
||||
if (parser_check_anonymous_function_declaration (context_p) < PARSER_NAMED_FUNCTION)
|
||||
{
|
||||
parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_FUNCTION_NAME);
|
||||
parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_PROPERTY);
|
||||
}
|
||||
else
|
||||
{
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -997,6 +1044,11 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
|
||||
lexer_next_token (context_p);
|
||||
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
|
||||
|
||||
if (parser_check_anonymous_function_declaration (context_p) < PARSER_NAMED_FUNCTION)
|
||||
{
|
||||
parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_FUNCTION_NAME);
|
||||
}
|
||||
|
||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
||||
{
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
|
||||
@@ -1028,10 +1080,11 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
|
||||
uint16_t opcode = CBC_SET_LITERAL_PROPERTY;
|
||||
/* This assignment is a nop for CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL. */
|
||||
uint16_t literal_index = context_p->lit_object.index;
|
||||
bool is_computed = context_p->token.type == LEXER_RIGHT_SQUARE;
|
||||
|
||||
if (context_p->token.type == LEXER_RIGHT_SQUARE)
|
||||
if (is_computed)
|
||||
{
|
||||
opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
|
||||
opcode = CBC_EXT_SET_COMPUTED_PROPERTY;
|
||||
}
|
||||
|
||||
uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags);
|
||||
@@ -1041,6 +1094,17 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
|
||||
function_literal_index);
|
||||
|
||||
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
|
||||
|
||||
if (is_computed)
|
||||
{
|
||||
parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_FUNCTION_NAME);
|
||||
parser_emit_cbc_ext (context_p, opcode);
|
||||
lexer_next_token (context_p);
|
||||
break;
|
||||
}
|
||||
|
||||
parser_set_function_name (context_p, function_literal_index, literal_index, status_flags);
|
||||
|
||||
context_p->last_cbc_opcode = opcode;
|
||||
context_p->last_cbc.value = literal_index;
|
||||
|
||||
@@ -1086,6 +1150,7 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
|
||||
parser_parse_object_method (context_p);
|
||||
|
||||
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
|
||||
parser_set_function_name (context_p, context_p->last_cbc.literal_index, literal_index, 0);
|
||||
context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
|
||||
context_p->last_cbc.value = literal_index;
|
||||
break;
|
||||
@@ -1123,11 +1188,24 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
|
||||
|
||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (context_p->last_cbc.literal_type == LEXER_FUNCTION_LITERAL)
|
||||
{
|
||||
parser_set_function_name (context_p, context_p->last_cbc.literal_index, literal_index, 0);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
|
||||
context_p->last_cbc.value = literal_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_FINALIZE_ANONYMOUS_CLASS))
|
||||
{
|
||||
uint16_t name_index = scanner_save_literal (context_p, literal_index);
|
||||
parser_emit_cbc_ext_literal (context_p, CBC_EXT_SET_CLASS_NAME, name_index);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, literal_index);
|
||||
}
|
||||
|
||||
@@ -1262,6 +1340,13 @@ parser_parse_function_expression (parser_context_t *context_p, /**< context */
|
||||
|
||||
JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE);
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (function_name_index != -1)
|
||||
{
|
||||
parser_set_function_name (context_p, function_literal_index, (uint16_t) function_name_index, 0);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
if (literals == 1)
|
||||
{
|
||||
context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
|
||||
@@ -2382,6 +2467,11 @@ parser_append_binary_single_assignment_token (parser_context_t *context_p, /**<
|
||||
assign_opcode = CBC_ASSIGN_SET_IDENT;
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (pattern_flags & PARSER_PATTERN_GROUP_EXPR)
|
||||
{
|
||||
parser_stack_push_uint8 (context_p, LEXER_ASSIGN_GROUP_EXPR);
|
||||
}
|
||||
|
||||
if (!(pattern_flags & (PARSER_PATTERN_LET | PARSER_PATTERN_CONST | PARSER_PATTERN_LOCAL)))
|
||||
{
|
||||
if (scanner_literal_is_const_reg (context_p, literal_index))
|
||||
@@ -2574,7 +2664,8 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
|
||||
opcode = (cbc_opcode_t) context_p->stack_top_uint8;
|
||||
parser_stack_pop_uint8 (context_p);
|
||||
|
||||
int32_t index = -1;
|
||||
uint16_t index = UINT16_MAX;
|
||||
|
||||
if (cbc_flags[opcode] & CBC_HAS_LITERAL_ARG)
|
||||
{
|
||||
JERRY_ASSERT (opcode == CBC_ASSIGN_SET_IDENT
|
||||
@@ -2589,6 +2680,14 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
bool group_expr_assingment = false;
|
||||
|
||||
if (JERRY_UNLIKELY (context_p->stack_top_uint8 == LEXER_ASSIGN_GROUP_EXPR))
|
||||
{
|
||||
group_expr_assingment = true;
|
||||
parser_stack_pop_uint8 (context_p);
|
||||
}
|
||||
|
||||
if (JERRY_UNLIKELY (context_p->stack_top_uint8 == LEXER_ASSIGN_CONST))
|
||||
{
|
||||
parser_stack_pop_uint8 (context_p);
|
||||
@@ -2596,20 +2695,37 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
if (index >= 0)
|
||||
if (index != UINT16_MAX)
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (!group_expr_assingment)
|
||||
{
|
||||
uint16_t function_literal_index = parser_check_anonymous_function_declaration (context_p);
|
||||
|
||||
if (function_literal_index == PARSER_ANONYMOUS_CLASS)
|
||||
{
|
||||
uint16_t name_index = scanner_save_literal (context_p, index);
|
||||
parser_emit_cbc_ext_literal (context_p, CBC_EXT_SET_CLASS_NAME, name_index);
|
||||
}
|
||||
else if (function_literal_index < PARSER_NAMED_FUNCTION)
|
||||
{
|
||||
parser_set_function_name (context_p, function_literal_index, (uint16_t) index, 0);
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL
|
||||
&& opcode == CBC_ASSIGN_SET_IDENT)
|
||||
{
|
||||
JERRY_ASSERT (CBC_ARGS_EQ (CBC_ASSIGN_LITERAL_SET_IDENT,
|
||||
CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
|
||||
|
||||
context_p->last_cbc.value = (uint16_t) index;
|
||||
context_p->last_cbc.value = index;
|
||||
context_p->last_cbc_opcode = CBC_ASSIGN_LITERAL_SET_IDENT;
|
||||
continue;
|
||||
}
|
||||
|
||||
parser_emit_cbc_literal (context_p, (uint16_t) opcode, (uint16_t) index);
|
||||
parser_emit_cbc_literal (context_p, (uint16_t) opcode, index);
|
||||
|
||||
if (opcode == CBC_ASSIGN_PROP_THIS_LITERAL
|
||||
&& (context_p->stack_depth >= context_p->stack_limit))
|
||||
@@ -2803,6 +2919,15 @@ parser_pattern_form_assignment (parser_context_t *context_p, /**< context */
|
||||
{
|
||||
JERRY_UNUSED (ident_line_counter);
|
||||
|
||||
uint16_t name_index = UINT16_MAX;
|
||||
|
||||
if ((flags & PARSER_PATTERN_BINDING)
|
||||
|| (context_p->last_cbc_opcode == CBC_PUSH_LITERAL
|
||||
&& context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL))
|
||||
{
|
||||
name_index = context_p->lit_object.index;
|
||||
}
|
||||
|
||||
parser_stack_push_uint8 (context_p, LEXER_EXPRESSION_START);
|
||||
uint8_t assign_opcode = parser_append_binary_single_assignment_token (context_p, flags);
|
||||
|
||||
@@ -2823,6 +2948,21 @@ parser_pattern_form_assignment (parser_context_t *context_p, /**< context */
|
||||
parser_emit_cbc_ext_forward_branch (context_p, CBC_EXT_DEFAULT_INITIALIZER, &skip_init);
|
||||
|
||||
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
|
||||
|
||||
if (name_index != UINT16_MAX)
|
||||
{
|
||||
uint16_t function_literal_index = parser_check_anonymous_function_declaration (context_p);
|
||||
|
||||
if (function_literal_index == PARSER_ANONYMOUS_CLASS)
|
||||
{
|
||||
name_index = scanner_save_literal (context_p, name_index);
|
||||
parser_emit_cbc_ext_literal (context_p, CBC_EXT_SET_CLASS_NAME, name_index);
|
||||
}
|
||||
else if (function_literal_index < PARSER_NAMED_FUNCTION)
|
||||
{
|
||||
parser_set_function_name (context_p, function_literal_index, name_index, 0);
|
||||
}
|
||||
}
|
||||
parser_set_branch_to_current_position (context_p, &skip_init);
|
||||
}
|
||||
|
||||
@@ -3240,14 +3380,16 @@ parser_process_expression_sequence (parser_context_t *context_p) /**< context */
|
||||
/**
|
||||
* Process group expression.
|
||||
*/
|
||||
static void
|
||||
static bool
|
||||
parser_process_group_expression (parser_context_t *context_p, /**< context */
|
||||
size_t *grouping_level_p) /**< grouping level */
|
||||
{
|
||||
JERRY_ASSERT (*grouping_level_p >= PARSER_GROUPING_LEVEL_INCREASE);
|
||||
(*grouping_level_p) -= PARSER_GROUPING_LEVEL_INCREASE;
|
||||
|
||||
if (context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST)
|
||||
uint8_t token = context_p->stack_top_uint8;
|
||||
|
||||
if (token == LEXER_COMMA_SEP_LIST)
|
||||
{
|
||||
parser_push_result (context_p);
|
||||
parser_flush_cbc (context_p);
|
||||
@@ -3255,6 +3397,22 @@ parser_process_group_expression (parser_context_t *context_p, /**< context */
|
||||
|
||||
parser_stack_pop_uint8 (context_p);
|
||||
lexer_next_token (context_p);
|
||||
|
||||
if (context_p->token.type == LEXER_ASSIGN)
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (JERRY_UNLIKELY (token == LEXER_LEFT_PAREN))
|
||||
{
|
||||
flags = PARSER_PATTERN_GROUP_EXPR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
parser_append_binary_single_assignment_token (context_p, flags);
|
||||
lexer_next_token (context_p);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} /* parser_process_group_expression */
|
||||
|
||||
/**
|
||||
@@ -3315,6 +3473,7 @@ parser_parse_expression (parser_context_t *context_p, /**< context */
|
||||
|
||||
while (true)
|
||||
{
|
||||
parse_unary_expression:
|
||||
if (parser_parse_unary_expression (context_p, &grouping_level))
|
||||
{
|
||||
parser_process_binary_opcodes (context_p, 0);
|
||||
@@ -3361,7 +3520,10 @@ process_unary_expression:
|
||||
&& (context_p->stack_top_uint8 == LEXER_LEFT_PAREN
|
||||
|| context_p->stack_top_uint8 == LEXER_COMMA_SEP_LIST))
|
||||
{
|
||||
parser_process_group_expression (context_p, &grouping_level);
|
||||
if (parser_process_group_expression (context_p, &grouping_level))
|
||||
{
|
||||
goto parse_unary_expression;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ typedef enum
|
||||
PARSER_PATTERN_REST_ELEMENT = (1u << 7), /**< parse rest array initializer */
|
||||
PARSER_PATTERN_ARGUMENTS = (1u << 8), /**< parse arguments binding */
|
||||
PARSER_PATTERN_ARRAY = (1u << 9), /**< array pattern is being parsed */
|
||||
PARSER_PATTERN_GROUP_EXPR = (1u << 10), /**< group expression is being assigned */
|
||||
} parser_pattern_flags_t;
|
||||
|
||||
/**
|
||||
@@ -415,6 +416,21 @@ typedef struct
|
||||
*/
|
||||
#define PARSER_REGISTER_START 0x8000
|
||||
|
||||
/**
|
||||
* Lastly emitted opcode is not a function literal
|
||||
*/
|
||||
#define PARSER_NOT_FUNCTION_LITERAL UINT16_MAX
|
||||
|
||||
/**
|
||||
* Lastly emitted opcode is not a named function literal
|
||||
*/
|
||||
#define PARSER_NAMED_FUNCTION (uint16_t) (PARSER_NOT_FUNCTION_LITERAL - 1)
|
||||
|
||||
/**
|
||||
* Lastly emitted opcode is not an anonymous class literal
|
||||
*/
|
||||
#define PARSER_ANONYMOUS_CLASS (uint16_t) (PARSER_NAMED_FUNCTION - 1)
|
||||
|
||||
/* Forward definitions for js-scanner-internal.h. */
|
||||
struct scanner_context_t;
|
||||
typedef struct scanner_context_t scanner_context_t;
|
||||
@@ -692,6 +708,7 @@ void lexer_convert_ident_to_cesu8 (uint8_t *destination_p, const uint8_t *source
|
||||
const uint8_t *lexer_convert_literal_to_chars (parser_context_t *context_p, const lexer_lit_location_t *literal_p,
|
||||
uint8_t *local_byte_array_p, lexer_string_options_t opts);
|
||||
void lexer_expect_object_literal_id (parser_context_t *context_p, uint32_t ident_opts);
|
||||
uint16_t scanner_save_literal (parser_context_t *context_p, uint16_t ident_index);
|
||||
void lexer_construct_literal_object (parser_context_t *context_p, const lexer_lit_location_t *lit_location_p,
|
||||
uint8_t literal_type);
|
||||
bool lexer_construct_number_object (parser_context_t *context_p, bool is_expr, bool is_negative_number);
|
||||
@@ -814,6 +831,11 @@ void parser_module_add_names_to_node (parser_context_t *context_p,
|
||||
ecma_compiled_code_t *parser_parse_function (parser_context_t *context_p, uint32_t status_flags);
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
ecma_compiled_code_t *parser_parse_arrow_function (parser_context_t *context_p, uint32_t status_flags);
|
||||
void parser_set_function_name (parser_context_t *context_p, uint16_t function_literal_index, uint16_t name_index,
|
||||
uint32_t status_flags);
|
||||
void parser_compiled_code_set_function_name (parser_context_t *context_p, ecma_compiled_code_t *bytecode_p,
|
||||
uint16_t name_index, uint32_t status_flags);
|
||||
uint16_t parser_check_anonymous_function_declaration (parser_context_t *context_p);
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/* Error management. */
|
||||
|
||||
@@ -571,6 +571,18 @@ parser_parse_var_statement (parser_context_t *context_p) /**< context */
|
||||
cbc_opcode_t opcode = CBC_ASSIGN_SET_IDENT;
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
uint16_t function_literal_index = parser_check_anonymous_function_declaration (context_p);
|
||||
|
||||
if (function_literal_index == PARSER_ANONYMOUS_CLASS)
|
||||
{
|
||||
uint16_t name_index = scanner_save_literal (context_p, index);
|
||||
parser_emit_cbc_ext_literal (context_p, CBC_EXT_SET_CLASS_NAME, name_index);
|
||||
}
|
||||
else if (function_literal_index < PARSER_NAMED_FUNCTION)
|
||||
{
|
||||
parser_set_function_name (context_p, function_literal_index, index, 0);
|
||||
}
|
||||
|
||||
if (declaration_type != LEXER_KEYW_VAR
|
||||
&& (index < PARSER_REGISTER_START))
|
||||
{
|
||||
@@ -706,6 +718,7 @@ parser_parse_function_statement (parser_context_t *context_p) /**< context */
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
uint16_t function_name_index = context_p->lit_object.index;
|
||||
parser_module_append_export_name (context_p);
|
||||
context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_STORE_IDENT);
|
||||
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
|
||||
@@ -828,6 +841,10 @@ parser_parse_function_statement (parser_context_t *context_p) /**< context */
|
||||
literal_p->u.bytecode_p = compiled_code_p;
|
||||
literal_p->type = LEXER_FUNCTION_LITERAL;
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
parser_compiled_code_set_function_name (context_p, compiled_code_p, function_name_index, 0);
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
lexer_next_token (context_p);
|
||||
} /* parser_parse_function_statement */
|
||||
|
||||
@@ -2623,13 +2640,13 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_DEBUGGER) */
|
||||
|
||||
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
#if ENABLED (JERRY_RESOURCE_NAME)
|
||||
if (JERRY_CONTEXT (resource_name) != ECMA_VALUE_UNDEFINED)
|
||||
{
|
||||
parser_emit_cbc_ext (context_p, CBC_EXT_RESOURCE_NAME);
|
||||
parser_flush_cbc (context_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
|
||||
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
|
||||
#if ENABLED (JERRY_LINE_INFO)
|
||||
context_p->last_line_info_line = 0;
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) */
|
||||
|
||||
@@ -1191,18 +1191,24 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
/* function.name */
|
||||
if (!(context_p->status_flags & PARSER_CLASS_CONSTRUCTOR))
|
||||
{
|
||||
total_size += sizeof (ecma_value_t);
|
||||
}
|
||||
|
||||
if (context_p->tagged_template_literal_cp != JMEM_CP_NULL)
|
||||
{
|
||||
total_size += sizeof (ecma_value_t);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
#if ENABLED (JERRY_RESOURCE_NAME)
|
||||
if (JERRY_CONTEXT (resource_name) != ECMA_VALUE_UNDEFINED)
|
||||
{
|
||||
total_size += sizeof (ecma_value_t);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
|
||||
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
|
||||
|
||||
#if ENABLED (JERRY_SNAPSHOT_SAVE)
|
||||
total_size_used = total_size;
|
||||
@@ -1590,13 +1596,14 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PARSER_DUMP_BYTE_CODE) */
|
||||
|
||||
ecma_value_t *base_p = (ecma_value_t *) (((uint8_t *) compiled_code_p) + total_size);
|
||||
|
||||
if (PARSER_NEEDS_MAPPED_ARGUMENTS (context_p->status_flags))
|
||||
{
|
||||
parser_list_iterator_t literal_iterator;
|
||||
uint16_t argument_count = 0;
|
||||
uint16_t register_count = context_p->register_count;
|
||||
ecma_value_t *argument_base_p = (ecma_value_t *) (((uint8_t *) compiled_code_p) + total_size);
|
||||
argument_base_p -= context_p->argument_count;
|
||||
base_p -= context_p->argument_count;
|
||||
|
||||
parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
|
||||
while (argument_count < context_p->argument_count)
|
||||
@@ -1614,7 +1621,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
/* All arguments must be moved to initialized registers. */
|
||||
if (literal_p->type == LEXER_UNUSED_LITERAL)
|
||||
{
|
||||
argument_base_p[argument_count] = ECMA_VALUE_EMPTY;
|
||||
base_p[argument_count] = ECMA_VALUE_EMPTY;
|
||||
argument_count++;
|
||||
continue;
|
||||
}
|
||||
@@ -1623,22 +1630,29 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
|
||||
JERRY_ASSERT (literal_p->prop.index >= register_count);
|
||||
|
||||
argument_base_p[argument_count] = literal_pool_p[literal_p->prop.index];
|
||||
base_p[argument_count] = literal_pool_p[literal_p->prop.index];
|
||||
argument_count++;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (!(context_p->status_flags & PARSER_CLASS_CONSTRUCTOR))
|
||||
{
|
||||
*(--base_p) = ECMA_VALUE_EMPTY;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
#if ENABLED (JERRY_RESOURCE_NAME)
|
||||
if (JERRY_CONTEXT (resource_name) != ECMA_VALUE_UNDEFINED)
|
||||
{
|
||||
*(--base_p) = JERRY_CONTEXT (resource_name);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (context_p->tagged_template_literal_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_value_t *tagged_base_p = (ecma_value_t *) (((uint8_t *) compiled_code_p) + total_size);
|
||||
|
||||
if (PARSER_NEEDS_MAPPED_ARGUMENTS (context_p->status_flags))
|
||||
{
|
||||
tagged_base_p -= context_p->argument_count;
|
||||
}
|
||||
|
||||
tagged_base_p[-1] = (ecma_value_t) context_p->tagged_template_literal_cp;
|
||||
base_p[-1] = (ecma_value_t) context_p->tagged_template_literal_cp;
|
||||
|
||||
ecma_collection_t *collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t,
|
||||
context_p->tagged_template_literal_cp);
|
||||
@@ -1650,27 +1664,6 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
if (JERRY_CONTEXT (resource_name) != ECMA_VALUE_UNDEFINED)
|
||||
{
|
||||
ecma_value_t *resource_name_p = (ecma_value_t *) (((uint8_t *) compiled_code_p) + total_size);
|
||||
|
||||
if (PARSER_NEEDS_MAPPED_ARGUMENTS (context_p->status_flags))
|
||||
{
|
||||
resource_name_p -= context_p->argument_count;
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (context_p->tagged_template_literal_cp != JMEM_CP_NULL)
|
||||
{
|
||||
resource_name_p--;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
resource_name_p[-1] = JERRY_CONTEXT (resource_name);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
|
||||
|
||||
#if ENABLED (JERRY_DEBUGGER)
|
||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
||||
{
|
||||
@@ -2599,6 +2592,124 @@ parser_parse_arrow_function (parser_context_t *context_p, /**< context */
|
||||
return compiled_code_p;
|
||||
} /* parser_parse_arrow_function */
|
||||
|
||||
/**
|
||||
* Check whether the last emitted cbc opcode was an anonymous function declaration
|
||||
*
|
||||
* @return PARSER_NOT_FUNCTION_LITERAL - if the last opcode is not a function literal
|
||||
* PARSER_NAMED_FUNCTION - if the last opcode is not a named function declataion
|
||||
* PARSER_ANONYMOUS_CLASS - if the last opcode is an anonymous class declaration
|
||||
* literal index of the anonymous function literal - otherwise
|
||||
*/
|
||||
uint16_t
|
||||
parser_check_anonymous_function_declaration (parser_context_t *context_p) /**< context */
|
||||
{
|
||||
if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_FINALIZE_ANONYMOUS_CLASS))
|
||||
{
|
||||
return PARSER_ANONYMOUS_CLASS;
|
||||
}
|
||||
|
||||
if (context_p->last_cbc.literal_type != LEXER_FUNCTION_LITERAL)
|
||||
{
|
||||
return PARSER_NOT_FUNCTION_LITERAL;
|
||||
}
|
||||
|
||||
uint16_t literal_index = PARSER_NOT_FUNCTION_LITERAL;
|
||||
|
||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
||||
{
|
||||
literal_index = context_p->last_cbc.literal_index;
|
||||
}
|
||||
else if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
|
||||
{
|
||||
literal_index = context_p->last_cbc.value;
|
||||
}
|
||||
else if (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS)
|
||||
{
|
||||
literal_index = context_p->last_cbc.third_literal_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PARSER_NOT_FUNCTION_LITERAL;
|
||||
}
|
||||
|
||||
const ecma_compiled_code_t *bytecode_p;
|
||||
bytecode_p = (const ecma_compiled_code_t *) (PARSER_GET_LITERAL (literal_index)->u.bytecode_p);
|
||||
ecma_value_t *func_name_start_p = ecma_compiled_code_resolve_function_name (bytecode_p);
|
||||
|
||||
return (*func_name_start_p == ECMA_VALUE_EMPTY ? literal_index : PARSER_NAMED_FUNCTION);
|
||||
} /* parser_check_anonymous_function_declaration */
|
||||
|
||||
/**
|
||||
* Set the function name of the function literal corresponds to the given function literal index
|
||||
* to the given character buffer of literal corresponds to the given name index.
|
||||
*/
|
||||
void
|
||||
parser_set_function_name (parser_context_t *context_p, /**< context */
|
||||
uint16_t function_literal_index, /**< function literal index */
|
||||
uint16_t name_index, /**< function name literal index */
|
||||
uint32_t status_flags) /**< status flags */
|
||||
{
|
||||
ecma_compiled_code_t *bytecode_p;
|
||||
bytecode_p = (ecma_compiled_code_t *) (PARSER_GET_LITERAL (function_literal_index)->u.bytecode_p);
|
||||
|
||||
parser_compiled_code_set_function_name (context_p, bytecode_p, name_index, status_flags);
|
||||
} /* parser_set_function_name */
|
||||
|
||||
/**
|
||||
* Set the function name of the given compiled code
|
||||
* to the given character buffer of literal corresponds to the given name index.
|
||||
*/
|
||||
void
|
||||
parser_compiled_code_set_function_name (parser_context_t *context_p, /**< context */
|
||||
ecma_compiled_code_t *bytecode_p, /**< function literal index */
|
||||
uint16_t name_index, /**< function name literal index */
|
||||
uint32_t status_flags) /**< status flags */
|
||||
{
|
||||
ecma_value_t *func_name_start_p;
|
||||
func_name_start_p = ecma_compiled_code_resolve_function_name ((const ecma_compiled_code_t *) bytecode_p);
|
||||
|
||||
if (JERRY_UNLIKELY (*func_name_start_p != ECMA_VALUE_EMPTY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parser_scope_stack_t *scope_stack_start_p = context_p->scope_stack_p;
|
||||
parser_scope_stack_t *scope_stack_p = scope_stack_start_p + context_p->scope_stack_top;
|
||||
|
||||
while (scope_stack_p > scope_stack_start_p)
|
||||
{
|
||||
scope_stack_p--;
|
||||
|
||||
if (scope_stack_p->map_from != PARSER_SCOPE_STACK_FUNC
|
||||
&& scanner_decode_map_to (scope_stack_p) == name_index)
|
||||
{
|
||||
name_index = scope_stack_p->map_from;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lexer_literal_t *name_lit_p = (lexer_literal_t *) PARSER_GET_LITERAL (name_index);
|
||||
|
||||
uint8_t *name_buffer_p = (uint8_t *) name_lit_p->u.char_p;
|
||||
uint32_t name_length = name_lit_p->prop.length;
|
||||
|
||||
if (status_flags & (PARSER_IS_PROPERTY_GETTER | PARSER_IS_PROPERTY_SETTER))
|
||||
{
|
||||
name_length += 4;
|
||||
name_buffer_p = (uint8_t *) parser_malloc (context_p, name_length * sizeof (uint8_t));
|
||||
char *prefix_p = (status_flags & PARSER_IS_PROPERTY_GETTER) ? "get " : "set ";
|
||||
memcpy (name_buffer_p, prefix_p, 4);
|
||||
memcpy (name_buffer_p + 4, name_lit_p->u.char_p, name_lit_p->prop.length);
|
||||
}
|
||||
|
||||
*func_name_start_p = ecma_find_or_create_literal_string (name_buffer_p, name_length);
|
||||
|
||||
if (name_buffer_p != name_lit_p->u.char_p)
|
||||
{
|
||||
parser_free (name_buffer_p, name_length);
|
||||
}
|
||||
} /* parser_compiled_code_set_function_name */
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/**
|
||||
|
||||
@@ -2429,6 +2429,38 @@ scanner_decode_map_to (parser_scope_stack_t *stack_item_p) /**< scope stack item
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
|
||||
/**
|
||||
* Find the given literal index in the scope stack
|
||||
* and save it the constant literal pool if the literal is register stored
|
||||
*
|
||||
* @return given literal index - if literal corresponds to this index is not register stored
|
||||
* literal index on which literal index has been mapped - otherwise
|
||||
*/
|
||||
uint16_t
|
||||
scanner_save_literal (parser_context_t *context_p, /**< context */
|
||||
uint16_t literal_index) /**< literal index */
|
||||
{
|
||||
if (literal_index >= PARSER_REGISTER_START)
|
||||
{
|
||||
literal_index = (uint16_t) (literal_index - (PARSER_REGISTER_START - 1));
|
||||
|
||||
parser_scope_stack_t *scope_stack_p = context_p->scope_stack_p + context_p->scope_stack_top;
|
||||
|
||||
do
|
||||
{
|
||||
/* Registers must be found in the scope stack. */
|
||||
JERRY_ASSERT (scope_stack_p > context_p->scope_stack_p);
|
||||
scope_stack_p--;
|
||||
}
|
||||
while (literal_index != (scope_stack_p->map_to & PARSER_SCOPE_STACK_REGISTER_MASK));
|
||||
|
||||
literal_index = scope_stack_p->map_from;
|
||||
PARSER_GET_LITERAL (literal_index)->status_flags |= LEXER_FLAG_USED;
|
||||
}
|
||||
|
||||
return literal_index;
|
||||
} /* scanner_save_literal */
|
||||
|
||||
/**
|
||||
* Checks whether the literal is a const in the current scope.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user