Skip to content

Commit

Permalink
Apply TCO for sequence and logical operations located at the end of t…
Browse files Browse the repository at this point in the history
…he return statement

Signed-off-by: HyukWoo Park <[email protected]>
  • Loading branch information
clover2123 authored and ksh8281 committed Oct 23, 2023
1 parent cdb47df commit 7f7d8c3
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 19 deletions.
50 changes: 43 additions & 7 deletions src/parser/ast/BinaryExpressionLogicalAndNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,55 @@ class BinaryExpressionLogicalAndNode : public ExpressionNode {
context->m_canSkipCopyToRegister = false;
}

size_t resultRegisterExpected = dstRegister;

m_left->generateExpressionByteCode(codeBlock, context, resultRegisterExpected);
if (UNLIKELY(m_left->isLiteral())) {
ExecutionState stateForTest(codeBlock->m_codeBlock->context());
bool boolVal = m_left->asLiteral()->value().toBoolean(stateForTest);
if (boolVal) {
m_right->generateExpressionByteCode(codeBlock, context, dstRegister);
} else {
m_left->generateExpressionByteCode(codeBlock, context, dstRegister);
}
} else {
m_left->generateExpressionByteCode(codeBlock, context, dstRegister);
codeBlock->pushCode<JumpIfFalse>(JumpIfFalse(ByteCodeLOC(m_loc.index), dstRegister), context, this->m_loc.index);
size_t pos = codeBlock->lastCodePosition<JumpIfFalse>();

m_right->generateExpressionByteCode(codeBlock, context, dstRegister);
codeBlock->peekCode<JumpIfFalse>(pos)->m_jumpPosition = codeBlock->currentCodeSize();
}

codeBlock->pushCode<JumpIfFalse>(JumpIfFalse(ByteCodeLOC(m_loc.index), resultRegisterExpected), context, this->m_loc.index);
size_t pos = codeBlock->lastCodePosition<JumpIfFalse>();
context->m_canSkipCopyToRegister = directBefore;
}

m_right->generateExpressionByteCode(codeBlock, context, resultRegisterExpected);
#if defined(ENABLE_TCO)
virtual void generateTCOExpressionByteCode(ByteCodeBlock* codeBlock, ByteCodeGenerateContext* context, ByteCodeRegisterIndex dstRegister, bool& isTailCall) override
{
bool isSlow = !canUseDirectRegister(context, m_left, m_right);
bool directBefore = context->m_canSkipCopyToRegister;
if (isSlow) {
context->m_canSkipCopyToRegister = false;
}

codeBlock->peekCode<JumpIfFalse>(pos)->m_jumpPosition = codeBlock->currentCodeSize();
if (UNLIKELY(m_left->isLiteral())) {
ExecutionState stateForTest(codeBlock->m_codeBlock->context());
bool boolVal = m_left->asLiteral()->value().toBoolean(stateForTest);
if (boolVal) {
m_right->generateTCOExpressionByteCode(codeBlock, context, dstRegister, isTailCall);
} else {
m_left->generateTCOExpressionByteCode(codeBlock, context, dstRegister, isTailCall);
}
} else {
m_left->generateExpressionByteCode(codeBlock, context, dstRegister);
codeBlock->pushCode<JumpIfFalse>(JumpIfFalse(ByteCodeLOC(m_loc.index), dstRegister), context, this->m_loc.index);
size_t pos = codeBlock->lastCodePosition<JumpIfFalse>();

m_right->generateExpressionByteCode(codeBlock, context, dstRegister);
codeBlock->peekCode<JumpIfFalse>(pos)->m_jumpPosition = codeBlock->currentCodeSize();
}

context->m_canSkipCopyToRegister = directBefore;
}
#endif

virtual void iterateChildrenIdentifier(const std::function<void(AtomicString name, bool isAssignment)>& fn) override
{
Expand Down
48 changes: 43 additions & 5 deletions src/parser/ast/BinaryExpressionLogicalOrNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,55 @@ class BinaryExpressionLogicalOrNode : public ExpressionNode {
context->m_canSkipCopyToRegister = false;
}

m_left->generateExpressionByteCode(codeBlock, context, dstRegister);
if (UNLIKELY(m_left->isLiteral())) {
ExecutionState stateForTest(codeBlock->m_codeBlock->context());
bool boolVal = m_left->asLiteral()->value().toBoolean(stateForTest);
if (boolVal) {
m_left->generateExpressionByteCode(codeBlock, context, dstRegister);
} else {
m_right->generateExpressionByteCode(codeBlock, context, dstRegister);
}
} else {
m_left->generateExpressionByteCode(codeBlock, context, dstRegister);
codeBlock->pushCode<JumpIfTrue>(JumpIfTrue(ByteCodeLOC(m_loc.index), dstRegister), context, this->m_loc.index);
size_t pos = codeBlock->lastCodePosition<JumpIfTrue>();

m_right->generateExpressionByteCode(codeBlock, context, dstRegister);
codeBlock->peekCode<JumpIfTrue>(pos)->m_jumpPosition = codeBlock->currentCodeSize();
}

codeBlock->pushCode<JumpIfTrue>(JumpIfTrue(ByteCodeLOC(m_loc.index), dstRegister), context, this->m_loc.index);
size_t pos = codeBlock->lastCodePosition<JumpIfTrue>();
context->m_canSkipCopyToRegister = directBefore;
}

m_right->generateExpressionByteCode(codeBlock, context, dstRegister);
#if defined(ENABLE_TCO)
virtual void generateTCOExpressionByteCode(ByteCodeBlock* codeBlock, ByteCodeGenerateContext* context, ByteCodeRegisterIndex dstRegister, bool& isTailCall) override
{
bool isSlow = !canUseDirectRegister(context, m_left, m_right);
bool directBefore = context->m_canSkipCopyToRegister;
if (isSlow) {
context->m_canSkipCopyToRegister = false;
}

codeBlock->peekCode<JumpIfTrue>(pos)->m_jumpPosition = codeBlock->currentCodeSize();
if (UNLIKELY(m_left->isLiteral())) {
ExecutionState stateForTest(codeBlock->m_codeBlock->context());
bool boolVal = m_left->asLiteral()->value().toBoolean(stateForTest);
if (boolVal) {
m_left->generateTCOExpressionByteCode(codeBlock, context, dstRegister, isTailCall);
} else {
m_right->generateTCOExpressionByteCode(codeBlock, context, dstRegister, isTailCall);
}
} else {
m_left->generateExpressionByteCode(codeBlock, context, dstRegister);
codeBlock->pushCode<JumpIfTrue>(JumpIfTrue(ByteCodeLOC(m_loc.index), dstRegister), context, this->m_loc.index);
size_t pos = codeBlock->lastCodePosition<JumpIfTrue>();

m_right->generateExpressionByteCode(codeBlock, context, dstRegister);
codeBlock->peekCode<JumpIfTrue>(pos)->m_jumpPosition = codeBlock->currentCodeSize();
}

context->m_canSkipCopyToRegister = directBefore;
}
#endif

virtual void iterateChildrenIdentifier(const std::function<void(AtomicString name, bool isAssignment)>& fn) override
{
Expand Down
23 changes: 20 additions & 3 deletions src/parser/ast/SequenceExpressionNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,33 @@ class SequenceExpressionNode : public ExpressionNode {

virtual void generateExpressionByteCode(ByteCodeBlock* codeBlock, ByteCodeGenerateContext* context, ByteCodeRegisterIndex dstRegister) override
{
ASSERT(m_expressions.size());
ByteCodeRegisterIndex r = 0;
for (SentinelNode* expression = m_expressions.begin(); expression != m_expressions.end(); expression = expression->next()) {
for (SentinelNode* expression = m_expressions.begin(); expression != m_expressions.back(); expression = expression->next()) {
r = expression->astNode()->getRegister(codeBlock, context);
expression->astNode()->generateExpressionByteCode(codeBlock, context, r);
context->giveUpRegister();
}
if (r != dstRegister) {
codeBlock->pushCode(Move(ByteCodeLOC(m_loc.index), r, dstRegister), context, this->m_loc.index);

// directly store the result of the last expression on to dstRegister
m_expressions.back()->astNode()->generateExpressionByteCode(codeBlock, context, dstRegister);
}

#if defined(ENABLE_TCO)
virtual void generateTCOExpressionByteCode(ByteCodeBlock* codeBlock, ByteCodeGenerateContext* context, ByteCodeRegisterIndex dstRegister, bool& isTailCall) override
{
ASSERT(m_expressions.size());
ByteCodeRegisterIndex r = 0;
for (SentinelNode* expression = m_expressions.begin(); expression != m_expressions.back(); expression = expression->next()) {
r = expression->astNode()->getRegister(codeBlock, context);
expression->astNode()->generateExpressionByteCode(codeBlock, context, r);
context->giveUpRegister();
}

// directly store the result of the last expression on to dstRegister
m_expressions.back()->astNode()->generateTCOExpressionByteCode(codeBlock, context, dstRegister, isTailCall);
}
#endif

virtual void iterateChildrenIdentifier(const std::function<void(AtomicString name, bool isAssignment)>& fn) override
{
Expand Down
2 changes: 1 addition & 1 deletion src/parser/ast/WhileStatementNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class WhileStatementNode : public StatementNode {
size_t whileStart = codeBlock->currentCodeSize();
size_t testPos = SIZE_MAX;
ExecutionState stateForTest(codeBlock->m_codeBlock->context());
if (m_test->isLiteral() && m_test->asLiteral()->value().isPrimitive() && m_test->asLiteral()->value().toBoolean(stateForTest)) {
if (m_test->isLiteral() && m_test->asLiteral()->value().toBoolean(stateForTest)) {
// skip generate code
} else {
if (m_test->isRelationOperation()) {
Expand Down
3 changes: 0 additions & 3 deletions tools/test/test262/excludelist.orig.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5070,7 +5070,6 @@
<test id="language/expressions/class/scope-name-lex-open-heritage"><reason>TODO</reason></test>
<test id="language/expressions/coalesce/chainable-if-parenthesis-covered-logical-and"><reason>TODO</reason></test>
<test id="language/expressions/coalesce/chainable-if-parenthesis-covered-logical-or"><reason>TODO</reason></test>
<test id="language/expressions/comma/tco-final"><reason>TODO</reason></test>
<test id="language/expressions/compound-assignment/S11.13.2_A6.10_T1"><reason>TODO</reason></test>
<test id="language/expressions/compound-assignment/S11.13.2_A6.11_T1"><reason>TODO</reason></test>
<test id="language/expressions/compound-assignment/S11.13.2_A6.1_T1"><reason>TODO</reason></test>
Expand Down Expand Up @@ -5121,7 +5120,6 @@
<test id="language/expressions/generators/eval-var-scope-syntax-err"><reason>TODO</reason></test>
<test id="language/expressions/generators/generator-created-after-decl-inst"><reason>TODO</reason></test>
<test id="language/expressions/generators/yield-as-generator-expression-binding-identifier"><reason>TODO</reason></test>
<test id="language/expressions/logical-and/tco-right"><reason>TODO</reason></test>
<test id="language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-arrow-function"><reason>TODO</reason></test>
<test id="language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-class-expression"><reason>TODO</reason></test>
<test id="language/expressions/logical-assignment/lgcl-and-assignment-operator-namedevaluation-function"><reason>TODO</reason></test>
Expand All @@ -5131,7 +5129,6 @@
<test id="language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-arrow-function"><reason>TODO</reason></test>
<test id="language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-class-expression"><reason>TODO</reason></test>
<test id="language/expressions/logical-assignment/lgcl-or-assignment-operator-namedevaluation-function"><reason>TODO</reason></test>
<test id="language/expressions/logical-or/tco-right"><reason>TODO</reason></test>
<test id="language/expressions/object/__proto__-permitted-dup-shorthand"><reason>TODO</reason></test>
<test id="language/expressions/object/dstr/object-rest-proxy-get-not-called-on-dontenum-keys"><reason>TODO</reason></test>
<test id="language/expressions/object/dstr/object-rest-proxy-gopd-not-called-on-excluded-keys"><reason>TODO</reason></test>
Expand Down

0 comments on commit 7f7d8c3

Please sign in to comment.