Skip to content
Permalink
Browse files
[JSC] Use emitPutProperty / emitGetPropertyValue consistently to hand…
…le private names in edge cases

https://bugs.webkit.org/show_bug.cgi?id=234794

Reviewed by Alexey Shvayka.

JSTests:

* test262/expectations.yaml:

Source/JavaScriptCore:

This patch consistently uses emitPutProperty / emitGetPropertyValue so that we handle private names
in edge cases.

* bytecompiler/NodesCodegen.cpp:
(JSC::TaggedTemplateNode::emitBytecode):
(JSC::ForInNode::emitLoopHeader):
(JSC::ForOfNode::emitBytecode):
(JSC::AssignmentElementNode::bindValue const):


Canonical link: https://commits.webkit.org/245666@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@287531 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Constellation committed Jan 3, 2022
1 parent 3fdb4c0 commit c4fb57efeaf88e9c6d67f2b49cb296175d292759
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 63 deletions.
@@ -1,3 +1,12 @@
2022-01-02 Yusuke Suzuki <ysuzuki@apple.com>

[JSC] Use emitPutProperty / emitGetPropertyValue consistently to handle private names in edge cases
https://bugs.webkit.org/show_bug.cgi?id=234794

Reviewed by Alexey Shvayka.

* test262/expectations.yaml:

2021-12-22 Saam Barati <sbarati@apple.com>

LLInt should loop OSR into BBQ and BBQ should loop OSR into OMG
@@ -0,0 +1,16 @@
function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error('bad value: ' + actual);
}

class C {
#field;

m(object) {
object.#field ??= 44;
return this.#field;
}
}

let c = new C();
shouldBe(c.m(c), 44);
@@ -2151,27 +2151,6 @@ test/language/statements/class/elements/nested-private-direct-eval-err-contains-
test/language/statements/class/elements/privatefieldset-evaluation-order-1.js:
default: 'Test262Error: Expected a ReferenceError to be thrown but no exception was thrown at all'
strict mode: 'Test262Error: Expected a ReferenceError to be thrown but no exception was thrown at all'
test/language/statements/class/elements/privatefieldset-evaluation-order-3.js:
default: 'Test262Error: Expected SameValue(«undefined», «pass») to be true'
strict mode: 'Test262Error: Expected SameValue(«undefined», «pass») to be true'
test/language/statements/class/elements/privatefieldset-typeerror-10.js:
default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
test/language/statements/class/elements/privatefieldset-typeerror-11.js:
default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
test/language/statements/class/elements/privatefieldset-typeerror-6.js:
default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
test/language/statements/class/elements/privatefieldset-typeerror-7.js:
default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
test/language/statements/class/elements/privatefieldset-typeerror-8.js:
default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
test/language/statements/class/elements/privatefieldset-typeerror-9.js:
default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
test/language/statements/class/subclass/default-constructor-spread-override.js:
default: 'Test262Error: @@iterator invoked'
strict mode: 'Test262Error: @@iterator invoked'
@@ -1,3 +1,19 @@
2022-01-02 Yusuke Suzuki <ysuzuki@apple.com>

[JSC] Use emitPutProperty / emitGetPropertyValue consistently to handle private names in edge cases
https://bugs.webkit.org/show_bug.cgi?id=234794

Reviewed by Alexey Shvayka.

This patch consistently uses emitPutProperty / emitGetPropertyValue so that we handle private names
in edge cases.

* bytecompiler/NodesCodegen.cpp:
(JSC::TaggedTemplateNode::emitBytecode):
(JSC::ForInNode::emitLoopHeader):
(JSC::ForOfNode::emitBytecode):
(JSC::AssignmentElementNode::bindValue const):

2022-01-02 Zan Dobersek <zdobersek@igalia.com>

Remove unused AbstractMacroAssembler::repatchJumpToNop() function
@@ -371,13 +371,10 @@ RegisterID* TaggedTemplateNode::emitBytecode(BytecodeGenerator& generator, Regis
} else {
ASSERT(m_tag->isDotAccessorNode());
DotAccessorNode* dot = static_cast<DotAccessorNode*>(m_tag);
tag = generator.newTemporary();
base = generator.newTemporary();
base = generator.emitNode(base.get(), dot->base());
if (dot->base()->isSuperNode()) {
RefPtr<RegisterID> thisValue = generator.ensureThis();
tag = generator.emitGetById(generator.newTemporary(), base.get(), thisValue.get(), dot->identifier());
} else
tag = generator.emitGetById(generator.newTemporary(), base.get(), dot->identifier());
tag = dot->emitGetPropertyValue(generator, tag.get(), base.get());
}

RefPtr<RegisterID> templateObject = generator.emitGetTemplateObject(nullptr, this);
@@ -3676,21 +3673,13 @@ RegisterID* ShortCircuitReadModifyDotNode::emitBytecode(BytecodeGenerator& gener
RefPtr<RegisterID> result = generator.tempDestination(dst);

generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
if (m_base->isSuperNode()) {
thisValue = generator.ensureThis();
generator.emitGetById(result.get(), base.get(), thisValue.get(), m_ident);
} else
generator.emitGetById(result.get(), base.get(), m_ident);

emitGetPropertyValue(generator, result.get(), base.get(), thisValue);
Ref<Label> afterAssignment = generator.newLabel();
emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());

generator.emitNode(result.get(), m_right);
generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
if (m_base->isSuperNode())
generator.emitPutById(base.get(), thisValue.get(), m_ident, result.get());
else
generator.emitPutById(base.get(), m_ident, result.get());
emitPutProperty(generator, base.get(), result.get(), thisValue);
generator.emitProfileType(result.get(), divotStart(), divotEnd());

generator.emitLabel(afterAssignment.get());
@@ -4136,17 +4125,13 @@ void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propert

if (m_lexpr->isDotAccessorNode()) {
DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
const Identifier& ident = assignNode->identifier();
RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
if (assignNode->base()->isSuperNode()) {
RefPtr<RegisterID> thisValue = generator.ensureThis();
generator.emitPutById(base.get(), thisValue.get(), ident, propertyName);
} else
generator.emitPutById(base.get(), ident, propertyName);
assignNode->emitPutProperty(generator, base.get(), propertyName);
generator.emitProfileType(propertyName, assignNode->divotStart(), assignNode->divotEnd());
return;
}

if (m_lexpr->isBracketAccessorNode()) {
BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
@@ -4289,15 +4274,9 @@ void ForOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
generator.emitProfileType(value, var, m_lexpr->position(), m_lexpr->position() + ident.length());
} else if (m_lexpr->isDotAccessorNode()) {
DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
const Identifier& ident = assignNode->identifier();
RefPtr<RegisterID> base = generator.emitNode(assignNode->base());

generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd());
if (assignNode->base()->isSuperNode()) {
RefPtr<RegisterID> thisValue = generator.ensureThis();
generator.emitPutById(base.get(), thisValue.get(), ident, value);
} else
generator.emitPutById(base.get(), ident, value);
assignNode->emitPutProperty(generator, base.get(), value);
generator.emitProfileType(value, assignNode->divotStart(), assignNode->divotEnd());
} else if (m_lexpr->isBracketAccessorNode()) {
BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
@@ -5713,11 +5692,7 @@ void AssignmentElementNode::bindValue(BytecodeGenerator& generator, RegisterID*
DotAccessorNode* lhs = static_cast<DotAccessorNode*>(m_assignmentTarget);
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(lhs->base(), true, false);
generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
if (lhs->base()->isSuperNode()) {
RefPtr<RegisterID> thisValue = generator.ensureThis();
generator.emitPutById(base.get(), thisValue.get(), lhs->identifier(), value);
} else
generator.emitPutById(base.get(), lhs->identifier(), value);
lhs->emitPutProperty(generator, base.get(), value);
generator.emitProfileType(value, divotStart(), divotEnd());
} else if (m_assignmentTarget->isBracketAccessorNode()) {
BracketAccessorNode* lhs = static_cast<BracketAccessorNode*>(m_assignmentTarget);
@@ -1620,7 +1620,7 @@ ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, Expr
return new (m_parserArena) AssignDotNode(location, dot->base(), dot->identifier(), dot->type(), expr, exprHasAssignments, dot->divot(), start, end);

if (op == Operator::CoalesceEq || op == Operator::OrEq || op == Operator::AndEq) {
auto* node = new (m_parserArena) ShortCircuitReadModifyDotNode(location, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, start, end);
auto* node = new (m_parserArena) ShortCircuitReadModifyDotNode(location, dot->base(), dot->identifier(), dot->type(), op, expr, exprHasAssignments, divot, start, end);
node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset);
return node;
}
@@ -798,11 +798,9 @@ namespace JSC {
{
}

inline ShortCircuitReadModifyDotNode::ShortCircuitReadModifyDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
: ExpressionNode(location)
inline ShortCircuitReadModifyDotNode::ShortCircuitReadModifyDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, DotType type, Operator oper, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
: BaseDotNode(location, base, ident, type)
, ThrowableSubExpressionData(divot, divotStart, divotEnd)
, m_base(base)
, m_ident(ident)
, m_right(right)
, m_operator(oper)
, m_rightHasAssignments(rightHasAssignments)
@@ -1561,15 +1561,13 @@ namespace JSC {
bool m_rightHasAssignments : 1;
};

class ShortCircuitReadModifyDotNode final : public ExpressionNode, public ThrowableSubExpressionData {
class ShortCircuitReadModifyDotNode final : public BaseDotNode, public ThrowableSubExpressionData {
public:
ShortCircuitReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
ShortCircuitReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, DotType, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);

private:
RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = nullptr) final;

ExpressionNode* m_base;
const Identifier& m_ident;
ExpressionNode* m_right;
Operator m_operator;
bool m_rightHasAssignments : 1;

0 comments on commit c4fb57e

Please sign in to comment.