-
Notifications
You must be signed in to change notification settings - Fork 684
Inner classes should not finalize the parent's class heritage environment #2686
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inner classes should not finalize the parent's class heritage environment #2686
Conversation
What is the remained issue? Is it possible to add a new test case for it? |
257d751
to
9e3ceb6
Compare
@LaszloLango I've just added the new test for it, but the fix became a bit more complicated. |
9e3ceb6
to
57c236c
Compare
PARSER_CLASS_CONSTRUCTOR = (1u << 20), /**< 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_STATIC_FUNCTION = (1u << 22), /**< this function is a static class method */ | ||
PARSER_CLASS_SUPER_PROP_REFERENCE = (1u << 23), /**< super property call or assignment */ | ||
PARSER_CLASS_IMPLICIT_SUPER = (1u << 22), /**< super property call or assignment */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment seems to be copy-pasted from PARSER_CLASS_SUPER_PROP_REFERENCE
jerry-core/ecma/base/ecma-globals.h
Outdated
ECMA_PARSE_CLASS_CONSTRUCTOR = (1u << 2), /**< a class constructor is being parsed (this value must be kept in | ||
* in sync with PARSER_CLASS_CONSTRUCTOR) */ | ||
ECMA_PARSE_HAS_SUPER = (1u << 3), /**< the current context has super reference */ | ||
ECMA_PARSE_HAS_STATIC_SUPER = (1u << 4), /**< the current context is a static class method */ | ||
ECMA_PARSE_HAS_IMPL_SUPER = (1u << 4), /**< the current context has super implicit super reference */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one too many supers in comment
JERRY_ASSERT (ecma_get_object_prototype (func_obj_p) == NULL); | ||
#ifndef JERRY_NDEBUG | ||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); | ||
JERRY_ASSERT (ecma_get_object_prototype (func_obj_p) == prototype_obj_p); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge these lines into a single statement to avoid the need for preprocessor guards and temporary variables.
JERRY_ASSERT (ecma_get_object_prototype (func_obj_p) == ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE));
jerry-core/vm/vm.c
Outdated
@@ -1328,7 +1328,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ | |||
|
|||
if (ecma_is_value_null (super_value)) | |||
{ | |||
super_class_p = ecma_create_object (NULL, 0, ECMA_OBJECT_TYPE_GENERAL); | |||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); | |||
super_class_p = ecma_create_object (prototype_obj_p, 0, ECMA_OBJECT_TYPE_GENERAL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge these lines.
super_class_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE), 0, ECMA_OBJECT_TYPE_GENERAL);
@@ -369,7 +369,8 @@ parser_parse_class_literal (parser_context_t *context_p) /**< context */ | |||
parser_emit_cbc (context_p, CBC_CREATE_OBJECT); | |||
|
|||
bool super_called = false; | |||
uint32_t status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | (context_p->status_flags & PARSER_CLASS_HAS_SUPER); | |||
uint32_t status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE; | |||
status_flags |= (context_p->status_flags & (PARSER_CLASS_HAS_SUPER | PARSER_CLASS_IMPLICIT_SUPER)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that the expression is broken out into a separate statement, the outer parentheses are unnecessary.
status_flags |= context_p->status_flags & ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly, the only problem with the single statement that it reaches the line length limit, but the outer parentheses can be removed.
literal_p->u.bytecode_p = parser_parse_function (context_p, constructor_status_flags); | ||
literal_p->type = LEXER_FUNCTION_LITERAL; | ||
parser_emit_cbc_literal (context_p, PARSER_TO_EXT_OPCODE (CBC_EXT_SET_CLASS_LITERAL), context_p->literal_count); | ||
parser_emit_cbc_literal (context_p, PARSER_TO_EXT_OPCODE (CBC_EXT_SET_CLASS_LITERAL), result_index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that this change is necessary. Where else is result_index
used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be. That was currently an unrevealed bug, since the parser_parse_function
can overwrite the literal_object and increase the literal count as well. But thanks for the reminding I'll add a test case for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I see what I've missed here: is it parser_parse_function
that may update context_p->literal_count
and that's why it should be saved? If so, it's OK. But I think it would be better not to inject result_index
in the middle of literal_p->field
assignments. It could be simple moved two lines upwards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly. Okay it can me moved up.
@@ -587,7 +587,10 @@ parser_parse_class (parser_context_t *context_p, /**< context */ | |||
} | |||
} | |||
|
|||
if (context_p->token.type == LEXER_KEYW_EXTENDS) | |||
bool create_class_env = (bool) (context_p->token.type == LEXER_KEYW_EXTENDS | |||
|| context_p->status_flags & PARSER_CLASS_HAS_SUPER); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. I think this should rather be written as
(context_p->token.type == LEXER_KEYW_EXTENDS)
|| (bool) (context_p->status_flags & PARSER_CLASS_HAS_SUPER)
The == results a bool, the || results a bool. It's only the & that needs casting.
57c236c
to
4078926
Compare
@akosthekiss Thank for the review I've updated the PR also rebased it to the latest master. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't say it is worth to support this likely unintentional bug.
@@ -582,7 +582,10 @@ parser_parse_class (parser_context_t *context_p, /**< context */ | |||
} | |||
} | |||
|
|||
if (context_p->token.type == LEXER_KEYW_EXTENDS) | |||
bool create_class_env = (context_p->token.type == LEXER_KEYW_EXTENDS | |||
|| context_p->status_flags & PARSER_CLASS_HAS_SUPER); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would enclose this expression into brackets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I've forgotten it.
75105c3
to
a91e6ec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've spotted some style issues in the test file. The rest LGTM
This patch is the proper fix for jerryscript-project#2667, since jerryscript-project#2269 did not fix the problem entirely. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik [email protected]
a91e6ec
to
51622f7
Compare
@akosthekiss Thanks for the review, I've fixed the related style issues. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This patch is the proper fix for #2667, since #2269 did not fix the problem entirely.
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik [email protected]