+void BinaryOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
+{
+ TriState branchCondition;
+ ExpressionNode* branchExpression;
+ tryFoldToBranch(generator, branchCondition, branchExpression);
+
+ if (branchCondition == MixedTriState)
+ ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
+ else if (branchCondition == TrueTriState)
+ generator.emitNodeInConditionContext(branchExpression, trueTarget, falseTarget, fallThroughMode);
+ else
+ generator.emitNodeInConditionContext(branchExpression, falseTarget, trueTarget, invert(fallThroughMode));
+}
+
+static inline bool canFoldToBranch(OpcodeID opcodeID, ExpressionNode* branchExpression, JSValue constant)
+{
+ ResultType expressionType = branchExpression->resultDescriptor();
+
+ if (expressionType.definitelyIsBoolean() && constant.isBoolean())
+ return true;
+ else if (expressionType.definitelyIsBoolean() && constant.isInt32() && (constant.asInt32() == 0 || constant.asInt32() == 1))
+ return opcodeID == op_eq || opcodeID == op_neq; // Strict equality is false in the case of type mismatch.
+ else if (expressionType.isInt32() && constant.isInt32() && constant.asInt32() == 0)
+ return true;
+
+ return false;
+}
+
+void BinaryOpNode::tryFoldToBranch(BytecodeGenerator& generator, TriState& branchCondition, ExpressionNode*& branchExpression)
+{
+ branchCondition = MixedTriState;
+ branchExpression = 0;
+
+ ConstantNode* constant = 0;
+ if (m_expr1->isConstant()) {
+ constant = static_cast<ConstantNode*>(m_expr1);
+ branchExpression = m_expr2;
+ } else if (m_expr2->isConstant()) {
+ constant = static_cast<ConstantNode*>(m_expr2);
+ branchExpression = m_expr1;
+ }
+
+ if (!constant)
+ return;
+ ASSERT(branchExpression);
+
+ OpcodeID opcodeID = this->opcodeID();
+ JSValue value = constant->jsValue(generator);
+ bool canFoldToBranch = JSC::canFoldToBranch(opcodeID, branchExpression, value);
+ if (!canFoldToBranch)
+ return;
+
+ if (opcodeID == op_eq || opcodeID == op_stricteq)
+ branchCondition = triState(value.pureToBoolean());
+ else if (opcodeID == op_neq || opcodeID == op_nstricteq)
+ branchCondition = triState(!value.pureToBoolean());
+}
+