Ignore:
Timestamp:
Jan 7, 2021, 3:17:44 PM (4 years ago)
Author:
[email protected]
Message:

[JSC] New expression and value function call should reserve function register if arguments include assignments
https://bugs.webkit.org/show_bug.cgi?id=220429
<rdar://problem/70598359>

Reviewed by Alexey Shvayka.

JSTests:

  • stress/comma-value-func-call-resolve.js: Added.

(shouldBe):
(fn.x):
(fn):

  • stress/construct-overwritten-variable.js:

(shouldThrow):
(new.x.x): Deleted.

  • stress/construct-spread-overwritten-variable-2.js:

(shouldThrow):
(new.x.x): Deleted.

  • stress/construct-spread-overwritten-variable.js:

(shouldThrow):
(new.x.x): Deleted.

  • stress/destructuring-func-call-resolve.js: Added.

(shouldBe):
(fn.x):
(fn):
(fn2.x):
(fn2):

  • stress/resolve-func-call-resolve.js: Added.

(shouldBe):
(fn.x):
(fn):

  • stress/tagged-template-call-resolve.js: Added.

(shouldBe):
(fn.x):
(fn):

  • test262/expectations.yaml:

Source/JavaScriptCore:

If the following code is executed, we need to reserve |x| before evaluating arguments since arguments can override
local |x| variable before calling it.

new x(x = 1)

We found there are two places we are not doing this.

  1. new expression
  2. function value call (it is checking isLocation(), but we can still use local variables for function if we use comma expression)

We introduced hasAssignment flag to ArgumentsNode, and reserve a function in a new temporary register if arguments include assignments.
We also need to increment assignmentCount in destructuring assignment.

  • bytecompiler/NodesCodegen.cpp:

(JSC::NewExprNode::emitBytecode):
(JSC::FunctionCallValueNode::emitBytecode):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createArguments):

  • parser/NodeConstructors.h:

(JSC::ArgumentsNode::ArgumentsNode):

  • parser/Nodes.h:
  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseDestructuringPattern):
(JSC::Parser<LexerType>::parseArguments):

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createArguments):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r271121 r271265  
    980980    else
    981981        expectedFunction = NoExpectedFunction;
    982     RefPtr<RegisterID> func = generator.emitNode(m_expr);
     982
     983    RefPtr<RegisterID> func = nullptr;
     984    if (m_args && m_args->hasAssignments())
     985        func = generator.newTemporary();
     986    func = generator.emitNode(func.get(), m_expr);
    983987    RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
    984988    CallArguments callArguments(generator, m_args);
     
    11011105    }
    11021106
    1103     RefPtr<RegisterID> func = generator.emitNode(m_expr);
     1107    RefPtr<RegisterID> func = nullptr;
     1108    if (m_args && m_args->hasAssignments())
     1109        func = generator.newTemporary();
     1110    func = generator.emitNode(func.get(), m_expr);
    11041111    RefPtr<RegisterID> returnValue = generator.finalDestination(dst, func.get());
    11051112    if (isOptionalChainBase())
Note: See TracChangeset for help on using the changeset viewer.