Changeset 148999 in webkit for trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
- Timestamp:
- Apr 23, 2013, 3:18:18 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r148696 r148999 93 93 } 94 94 95 // ------------------------------ NullNode ------------------------------------- 96 97 RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 95 // ------------------------------ ConstantNode ---------------------------------- 96 97 void ConstantNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode) 98 { 99 TriState value = jsValue(generator).pureToBoolean(); 100 if (value == MixedTriState) 101 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode); 102 else if (value == TrueTriState && fallThroughMode == FallThroughMeansFalse) 103 generator.emitJump(trueTarget); 104 else if (value == FalseTriState && fallThroughMode == FallThroughMeansTrue) 105 generator.emitJump(falseTarget); 106 107 // All other cases are unconditional fall-throughs, like "if (true)". 108 } 109 110 RegisterID* ConstantNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 98 111 { 99 112 if (dst == generator.ignoredResult()) 100 113 return 0; 101 return generator.emitLoad(dst, jsNull()); 102 } 103 104 // ------------------------------ BooleanNode ---------------------------------- 105 106 RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 107 { 108 if (dst == generator.ignoredResult()) 109 return 0; 110 return generator.emitLoad(dst, m_value); 111 } 112 113 // ------------------------------ NumberNode ----------------------------------- 114 115 RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 116 { 117 if (dst == generator.ignoredResult()) 118 return 0; 119 return generator.emitLoad(dst, m_value); 120 } 121 122 // ------------------------------ StringNode ----------------------------------- 123 124 RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 125 { 126 if (dst == generator.ignoredResult()) 127 return 0; 128 return generator.emitLoad(dst, m_value); 114 return generator.emitLoad(dst, jsValue(generator)); 115 } 116 117 JSValue StringNode::jsValue(BytecodeGenerator& generator) const 118 { 119 return generator.addStringConstant(m_value); 129 120 } 130 121 … … 1043 1034 } 1044 1035 1036 void BinaryOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode) 1037 { 1038 TriState branchCondition; 1039 ExpressionNode* branchExpression; 1040 tryFoldToBranch(generator, branchCondition, branchExpression); 1041 1042 if (branchCondition == MixedTriState) 1043 ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode); 1044 else if (branchCondition == TrueTriState) 1045 generator.emitNodeInConditionContext(branchExpression, trueTarget, falseTarget, fallThroughMode); 1046 else 1047 generator.emitNodeInConditionContext(branchExpression, falseTarget, trueTarget, invert(fallThroughMode)); 1048 } 1049 1050 static inline bool canFoldToBranch(OpcodeID opcodeID, ExpressionNode* branchExpression, JSValue constant) 1051 { 1052 ResultType expressionType = branchExpression->resultDescriptor(); 1053 1054 if (expressionType.definitelyIsBoolean() && constant.isBoolean()) 1055 return true; 1056 else if (expressionType.isInt32() && constant.isInt32() && (constant.asInt32() == 0 || constant.asInt32() == 1)) 1057 return true; 1058 else if (expressionType.definitelyIsBoolean() && constant.isInt32() && (constant.asInt32() == 0 || constant.asInt32() == 1)) 1059 return opcodeID == op_eq || opcodeID == op_neq; // Strict equality is false in the case of type mismatch, so we can't fold to a branch based on truthiness. 1060 1061 return false; 1062 } 1063 1064 void BinaryOpNode::tryFoldToBranch(BytecodeGenerator& generator, TriState& branchCondition, ExpressionNode*& branchExpression) 1065 { 1066 branchCondition = MixedTriState; 1067 branchExpression = 0; 1068 1069 ConstantNode* constant = 0; 1070 if (m_expr1->isConstant()) { 1071 constant = static_cast<ConstantNode*>(m_expr1); 1072 branchExpression = m_expr2; 1073 } else if (m_expr2->isConstant()) { 1074 constant = static_cast<ConstantNode*>(m_expr2); 1075 branchExpression = m_expr1; 1076 } 1077 1078 if (!constant) 1079 return; 1080 ASSERT(branchExpression); 1081 1082 OpcodeID opcodeID = this->opcodeID(); 1083 JSValue value = constant->jsValue(generator); 1084 bool canFoldToBranch = JSC::canFoldToBranch(opcodeID, branchExpression, value); 1085 if (!canFoldToBranch) 1086 return; 1087 1088 if (opcodeID == op_eq || opcodeID == op_stricteq) 1089 branchCondition = triState(value.pureToBoolean()); 1090 else if (opcodeID == op_neq || opcodeID == op_nstricteq) 1091 branchCondition = triState(!value.pureToBoolean()); 1092 } 1093 1045 1094 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1046 1095 { … … 1505 1554 } 1506 1555 1507 // ------------------------------ IfNode --------------------------------------- 1508 1509 void IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1556 // ------------------------------ IfElseNode --------------------------------------- 1557 1558 static inline StatementNode* singleStatement(StatementNode* statementNode) 1559 { 1560 if (statementNode->isBlock()) 1561 return static_cast<BlockNode*>(statementNode)->singleStatement(); 1562 return statementNode; 1563 } 1564 1565 bool IfElseNode::tryFoldBreakAndContinue(BytecodeGenerator& generator, StatementNode* ifBlock, 1566 Label*& trueTarget, FallThroughMode& fallThroughMode) 1567 { 1568 StatementNode* singleStatement = JSC::singleStatement(ifBlock); 1569 if (!singleStatement) 1570 return false; 1571 1572 if (singleStatement->isBreak()) { 1573 BreakNode* breakNode = static_cast<BreakNode*>(singleStatement); 1574 Label* target = breakNode->trivialTarget(generator); 1575 if (!target) 1576 return false; 1577 trueTarget = target; 1578 fallThroughMode = FallThroughMeansFalse; 1579 return true; 1580 } 1581 1582 if (singleStatement->isContinue()) { 1583 ContinueNode* continueNode = static_cast<ContinueNode*>(singleStatement); 1584 Label* target = continueNode->trivialTarget(generator); 1585 if (!target) 1586 return false; 1587 trueTarget = target; 1588 fallThroughMode = FallThroughMeansFalse; 1589 return true; 1590 } 1591 1592 return false; 1593 } 1594 1595 void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1510 1596 { 1511 1597 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition()); 1512 1598 1513 RefPtr<Label> afterThen = generator.newLabel();1514 1515 1599 RefPtr<Label> beforeThen = generator.newLabel(); 1516 generator.emitNodeInConditionContext(m_condition, beforeThen.get(), afterThen.get(), FallThroughMeansTrue);1517 generator.emitLabel(beforeThen.get());1518 1519 generator.emitNode(dst, m_ifBlock);1520 generator.emitLabel(afterThen.get());1521 }1522 1523 // ------------------------------ IfElseNode ---------------------------------------1524 1525 void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)1526 {1527 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());1528 1529 1600 RefPtr<Label> beforeElse = generator.newLabel(); 1530 1601 RefPtr<Label> afterElse = generator.newLabel(); 1531 1602 1532 RefPtr<Label> beforeThen = generator.newLabel(); 1533 generator.emitNodeInConditionContext(m_condition, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue); 1603 Label* trueTarget = beforeThen.get(); 1604 Label* falseTarget = beforeElse.get(); 1605 FallThroughMode fallThroughMode = FallThroughMeansTrue; 1606 bool didFoldIfBlock = tryFoldBreakAndContinue(generator, m_ifBlock, trueTarget, fallThroughMode); 1607 1608 generator.emitNodeInConditionContext(m_condition, trueTarget, falseTarget, fallThroughMode); 1534 1609 generator.emitLabel(beforeThen.get()); 1535 1610 1536 generator.emitNode(dst, m_ifBlock); 1537 generator.emitJump(afterElse.get()); 1611 if (!didFoldIfBlock) { 1612 generator.emitNode(dst, m_ifBlock); 1613 if (m_elseBlock) 1614 generator.emitJump(afterElse.get()); 1615 } 1538 1616 1539 1617 generator.emitLabel(beforeElse.get()); 1540 1618 1541 generator.emitNode(dst, m_elseBlock); 1619 if (m_elseBlock) 1620 generator.emitNode(dst, m_elseBlock); 1542 1621 1543 1622 generator.emitLabel(afterElse.get()); … … 1701 1780 // ------------------------------ ContinueNode --------------------------------- 1702 1781 1782 Label* ContinueNode::trivialTarget(BytecodeGenerator& generator) 1783 { 1784 if (generator.shouldEmitDebugHooks()) 1785 return 0; 1786 1787 LabelScope* scope = generator.continueTarget(m_ident); 1788 ASSERT(scope); 1789 1790 if (generator.scopeDepth() != scope->scopeDepth()) 1791 return 0; 1792 1793 return scope->continueTarget(); 1794 } 1795 1703 1796 void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 1704 1797 { … … 1713 1806 1714 1807 // ------------------------------ BreakNode ------------------------------------ 1808 1809 Label* BreakNode::trivialTarget(BytecodeGenerator& generator) 1810 { 1811 if (generator.shouldEmitDebugHooks()) 1812 return 0; 1813 1814 LabelScope* scope = generator.breakTarget(m_ident); 1815 ASSERT(scope); 1816 1817 if (generator.scopeDepth() != scope->scopeDepth()) 1818 return 0; 1819 1820 return scope->breakTarget(); 1821 } 1715 1822 1716 1823 void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
Note:
See TracChangeset
for help on using the changeset viewer.