Changeset 149158 in webkit for trunk/Source/JavaScriptCore/bytecompiler
- Timestamp:
- Apr 25, 2013, 5:40:27 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore/bytecompiler
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r148999 r149158 1629 1629 if (length) { 1630 1630 for (ElementNode* n = elements; n; n = n->next()) { 1631 if (!n->value()->is Constant()) {1631 if (!n->value()->isNumber() && !n->value()->isString()) { 1632 1632 hadVariableExpression = true; 1633 1633 break; … … 1645 1645 unsigned index = 0; 1646 1646 for (ElementNode* n = elements; index < length; n = n->next()) { 1647 ASSERT(n->value()->isConstant()); 1648 constantBuffer[index++] = static_cast<ConstantNode*>(n->value())->jsValue(*this); 1647 if (n->value()->isNumber()) 1648 constantBuffer[index++] = jsNumber(static_cast<NumberNode*>(n->value())->value()); 1649 else { 1650 ASSERT(n->value()->isString()); 1651 constantBuffer[index++] = addStringConstant(static_cast<StringNode*>(n->value())->value()); 1652 } 1649 1653 } 1650 1654 emitOpcode(op_new_array_buffer); … … 2362 2366 { 2363 2367 emitOpcode(op_throw_static_error); 2364 instructions().append(addConstantValue( addStringConstant(Identifier(m_vm, message)))->index());2368 instructions().append(addConstantValue(jsString(vm(), message))->index()); 2365 2369 instructions().append(true); 2366 2370 } … … 2520 2524 return; 2521 2525 emitOpcode(op_throw_static_error); 2522 instructions().append(addConstantValue( addStringConstant(Identifier(m_vm, StrictModeReadonlyPropertyWriteError)))->index());2526 instructions().append(addConstantValue(jsString(vm(), StrictModeReadonlyPropertyWriteError))->index()); 2523 2527 instructions().append(false); 2524 2528 } -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r148999 r149158 554 554 555 555 bool shouldEmitProfileHooks() { return m_shouldEmitProfileHooks; } 556 bool shouldEmitDebugHooks() { return m_shouldEmitDebugHooks; }557 556 558 557 bool isStrictMode() const { return m_codeBlock->isStrictMode(); } … … 648 647 } 649 648 649 JSString* addStringConstant(const Identifier&); 650 650 651 void addLineInfo(unsigned lineNo) 651 652 { … … 656 657 657 658 public: 658 JSString* addStringConstant(const Identifier&);659 660 659 Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>& instructions() { return m_instructions; } 661 660 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r148999 r149158 93 93 } 94 94 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) 95 // ------------------------------ NullNode ------------------------------------- 96 97 RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 111 98 { 112 99 if (dst == generator.ignoredResult()) 113 100 return 0; 114 return generator.emitLoad(dst, jsValue(generator)); 115 } 116 117 JSValue StringNode::jsValue(BytecodeGenerator& generator) const 118 { 119 return generator.addStringConstant(m_value); 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); 120 129 } 121 130 … … 1034 1043 } 1035 1044 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 else1047 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 1094 1045 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1095 1046 { … … 1554 1505 } 1555 1506 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) 1507 // ------------------------------ IfNode --------------------------------------- 1508 1509 void IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1596 1510 { 1597 1511 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition()); 1598 1512 1513 RefPtr<Label> afterThen = generator.newLabel(); 1514 1599 1515 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 1600 1529 RefPtr<Label> beforeElse = generator.newLabel(); 1601 1530 RefPtr<Label> afterElse = generator.newLabel(); 1602 1531 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); 1532 RefPtr<Label> beforeThen = generator.newLabel(); 1533 generator.emitNodeInConditionContext(m_condition, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue); 1609 1534 generator.emitLabel(beforeThen.get()); 1610 1535 1611 if (!didFoldIfBlock) { 1612 generator.emitNode(dst, m_ifBlock); 1613 if (m_elseBlock) 1614 generator.emitJump(afterElse.get()); 1615 } 1536 generator.emitNode(dst, m_ifBlock); 1537 generator.emitJump(afterElse.get()); 1616 1538 1617 1539 generator.emitLabel(beforeElse.get()); 1618 1540 1619 if (m_elseBlock) 1620 generator.emitNode(dst, m_elseBlock); 1541 generator.emitNode(dst, m_elseBlock); 1621 1542 1622 1543 generator.emitLabel(afterElse.get()); … … 1780 1701 // ------------------------------ ContinueNode --------------------------------- 1781 1702 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 1796 1703 void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 1797 1704 { … … 1806 1713 1807 1714 // ------------------------------ 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 }1822 1715 1823 1716 void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
Note:
See TracChangeset
for help on using the changeset viewer.