Skip to content

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

Merged
merged 1 commit into from
Jan 16, 2019

Conversation

rerobika
Copy link
Member

@rerobika rerobika commented Jan 9, 2019

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]

@LaszloLango
Copy link
Contributor

#2269 did not fix the problem entirely.

What is the remained issue? Is it possible to add a new test case for it?

@rerobika
Copy link
Member Author

rerobika commented Jan 9, 2019

@LaszloLango I've just added the new test for it, but the fix became a bit more complicated.

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 */
Copy link
Member

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

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 */
Copy link
Member

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);
Copy link
Member

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));

@@ -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);
Copy link
Member

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));
Copy link
Member

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 & ...

Copy link
Member Author

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);
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member Author

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);
Copy link
Member

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.

@rerobika
Copy link
Member Author

@akosthekiss Thank for the review I've updated the PR also rebased it to the latest master.

Copy link
Member

@zherczeg zherczeg left a 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);
Copy link
Member

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.

Copy link
Member Author

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.

@rerobika rerobika force-pushed the fix_issue_2667 branch 2 times, most recently from 75105c3 to a91e6ec Compare January 15, 2019 10:52
Copy link
Member

@akosthekiss akosthekiss left a 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]
@rerobika
Copy link
Member Author

@akosthekiss Thanks for the review, I've fixed the related style issues.

Copy link
Member

@akosthekiss akosthekiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@zherczeg zherczeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@akosthekiss akosthekiss added bug Undesired behaviour ES2015 Related to ES2015 features labels Jan 16, 2019
@akosthekiss akosthekiss merged commit 86e60dd into jerryscript-project:master Jan 16, 2019
@rerobika rerobika deleted the fix_issue_2667 branch February 28, 2019 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Undesired behaviour ES2015 Related to ES2015 features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants