Implement ECMAScript 2022 private class methods and fields (#4831)

Co-authored-by: Robert Fancsik robert.fancsik@h-lab.eu
Co-authored-by: Martin Negyokru mnegyokru@inf.u-szeged.hu
JerryScript-DCO-1.0-Signed-off-by: Adam Szilagyi aszilagy@inf.u-szeged.hu
This commit is contained in:
Szilagyi Adam
2021-11-26 12:24:59 +01:00
committed by GitHub
parent 841e21a970
commit 70e275e92f
35 changed files with 2196 additions and 4341 deletions
+74 -3
View File
@@ -331,6 +331,21 @@ scanner_release_switch_cases (scanner_case_info_t *case_p) /**< case list */
}
} /* scanner_release_switch_cases */
/**
* Release private fields.
*/
void
scanner_release_private_fields (scanner_class_private_member_t *member_p) /**< private member list */
{
while (member_p != NULL)
{
scanner_class_private_member_t *prev_p = member_p->prev_p;
jmem_heap_free_block (member_p, sizeof (scanner_class_private_member_t));
member_p = prev_p;
}
} /* scanner_release_private_fields */
/**
* Seek to correct position in the scanner info list.
*/
@@ -406,7 +421,7 @@ scanner_scope_find_lexical_declaration (parser_context_t *context_p, /**< contex
if (JERRY_LIKELY (!(literal_p->status_flags & LEXER_LIT_LOCATION_HAS_ESCAPE)))
{
name_p = parser_new_ecma_string_from_literal ((lexer_literal_t *) literal_p);
name_p = ecma_new_ecma_string_from_utf8 (literal_p->char_p, literal_p->length);
}
else
{
@@ -414,7 +429,7 @@ scanner_scope_find_lexical_declaration (parser_context_t *context_p, /**< contex
lexer_convert_ident_to_cesu8 (destination_p, literal_p->char_p, literal_p->length);
name_p = parser_new_ecma_string_from_literal ((lexer_literal_t *) literal_p);
name_p = ecma_new_ecma_string_from_utf8 (destination_p, literal_p->length);
scanner_free (destination_p, literal_p->length);
}
@@ -1535,6 +1550,46 @@ scanner_append_argument (parser_context_t *context_p, /**< context */
return literal_p;
} /* scanner_append_argument */
/**
* Add private identifiers to private ident pool
*/
void
scanner_add_private_identifier (parser_context_t *context_p, /**< context */
scanner_private_field_flags_t opts) /**< options */
{
scan_stack_modes_t stack_top = (scan_stack_modes_t) context_p->stack_top_uint8;
parser_stack_pop_uint8 (context_p);
scanner_class_info_t *class_info_p;
parser_stack_pop (context_p, &class_info_p, sizeof (scanner_class_info_t *));
scanner_class_private_member_t *iter = class_info_p->members;
scanner_private_field_flags_t search_flag =
((opts & SCANNER_PRIVATE_FIELD_PROPERTY) ? SCANNER_PRIVATE_FIELD_PROPERTY_GETTER_SETTER
: (opts & SCANNER_PRIVATE_FIELD_GETTER_SETTER));
while (iter != NULL)
{
if (lexer_compare_identifiers (context_p, &context_p->token.lit_location, &iter->loc)
&& (iter->u8_arg & search_flag))
{
scanner_raise_error (context_p);
}
iter = iter->prev_p;
}
scanner_class_private_member_t *p_member;
p_member = (scanner_class_private_member_t *) scanner_malloc (context_p, sizeof (scanner_class_private_member_t));
p_member->loc = context_p->token.lit_location;
p_member->u8_arg = (uint8_t) opts;
p_member->prev_p = class_info_p->members;
class_info_p->members = p_member;
parser_stack_push (context_p, &class_info_p, sizeof (scanner_class_info_t *));
parser_stack_push_uint8 (context_p, (uint8_t) stack_top);
} /* scanner_add_private_identifier */
/**
* Check whether an eval call is performed and update the status flags accordingly.
*/
@@ -1729,6 +1784,15 @@ scanner_push_class_declaration (parser_context_t *context_p, /**< context */
literal_pool_p->source_p = source_p;
literal_pool_p->status_flags |= SCANNER_LITERAL_POOL_CLASS_NAME;
const uint8_t *class_source_p = scanner_context_p->active_literal_pool_p->source_p;
scanner_class_info_t *class_info_p =
(scanner_class_info_t *) scanner_insert_info (context_p, class_source_p, sizeof (scanner_class_info_t));
class_info_p->info.type = SCANNER_TYPE_CLASS_CONSTRUCTOR;
class_info_p->members = NULL;
class_info_p->info.u8_arg = SCANNER_CONSTRUCTOR_IMPLICIT;
parser_stack_push (context_p, &class_info_p, sizeof (scanner_class_info_t *));
parser_stack_push_uint8 (context_p, SCAN_STACK_IMPLICIT_CLASS_CONSTRUCTOR);
scanner_context_p->mode = SCAN_MODE_CLASS_DECLARATION;
@@ -1935,12 +1999,19 @@ scanner_cleanup (parser_context_t *context_p) /**< context */
size = sizeof (scanner_switch_info_t);
break;
}
#if JERRY_ESNEXT
case SCANNER_TYPE_CLASS_CONSTRUCTOR:
{
scanner_release_private_fields (((scanner_class_info_t *) scanner_info_p)->members);
size = sizeof (scanner_class_info_t);
break;
}
#endif /* JERRY_ESNEXT */
default:
{
#if JERRY_ESNEXT
JERRY_ASSERT (
scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS || scanner_info_p->type == SCANNER_TYPE_LITERAL_FLAGS
|| scanner_info_p->type == SCANNER_TYPE_CLASS_CONSTRUCTOR
|| scanner_info_p->type == SCANNER_TYPE_LET_EXPRESSION || scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED
|| scanner_info_p->type == SCANNER_TYPE_ERR_ASYNC_FUNCTION
|| scanner_info_p->type == SCANNER_TYPE_EXPORT_MODULE_SPECIFIER);