Commit 875318ae authored by cwzwarich@webkit.org's avatar cwzwarich@webkit.org

2008-06-15 Cameron Zwarich <cwzwarich@uwaterloo.ca>

        Reviewed by Maciej.

        Bug 19484: More instructions needs to use temporary registers
        <https://bugs.webkit.org/show_bug.cgi?id=19484>

        Fix codegen for all binary operations so that temporaries are used if
        necessary. This was done by making BinaryOpNode and ReverseBinaryOpNode
        subclasses of ExpressionNode, and eliminating the custom emitCode()
        methods for the individual node classes.

        This only adds 3 new instructions to SunSpider code, and there is no
        difference in SunSpider execution time.

        JavaScriptCore:

        * VM/CodeGenerator.cpp:
        (KJS::CodeGenerator::emitBitNot):
        (KJS::CodeGenerator::emitBinaryOp):
        * VM/CodeGenerator.h:
        * kjs/grammar.y:
        * kjs/nodes.cpp:
        (KJS::PreIncResolveNode::emitCode):
        (KJS::PreDecResolveNode::emitCode):
        (KJS::BinaryOpNode::emitCode):
        (KJS::ReverseBinaryOpNode::emitCode):
        (KJS::emitReadModifyAssignment):
        (KJS::CaseBlockNode::emitCodeForBlock):
        * kjs/nodes.h:
        (KJS::BinaryOpNode::BinaryOpNode):
        (KJS::ReverseBinaryOpNode::ReverseBinaryOpNode):
        (KJS::MultNode::):
        (KJS::DivNode::):
        (KJS::DivNode::precedence):
        (KJS::ModNode::):
        (KJS::ModNode::precedence):
        (KJS::AddNode::):
        (KJS::AddNode::precedence):
        (KJS::SubNode::):
        (KJS::SubNode::precedence):
        (KJS::LeftShiftNode::):
        (KJS::LeftShiftNode::precedence):
        (KJS::RightShiftNode::):
        (KJS::RightShiftNode::precedence):
        (KJS::UnsignedRightShiftNode::):
        (KJS::UnsignedRightShiftNode::precedence):
        (KJS::LessNode::):
        (KJS::LessNode::precedence):
        (KJS::GreaterNode::):
        (KJS::GreaterNode::precedence):
        (KJS::LessEqNode::):
        (KJS::LessEqNode::precedence):
        (KJS::GreaterEqNode::):
        (KJS::GreaterEqNode::precedence):
        (KJS::InstanceOfNode::):
        (KJS::InstanceOfNode::precedence):
        (KJS::InNode::):
        (KJS::InNode::precedence):
        (KJS::EqualNode::):
        (KJS::EqualNode::precedence):
        (KJS::NotEqualNode::):
        (KJS::NotEqualNode::precedence):
        (KJS::StrictEqualNode::):
        (KJS::StrictEqualNode::precedence):
        (KJS::NotStrictEqualNode::):
        (KJS::NotStrictEqualNode::precedence):
        (KJS::BitAndNode::):
        (KJS::BitAndNode::precedence):
        (KJS::BitOrNode::):
        (KJS::BitOrNode::precedence):
        (KJS::BitXOrNode::):
        (KJS::BitXOrNode::precedence):
        * kjs/nodes2string.cpp:
        (KJS::LessNode::streamTo):
        (KJS::GreaterNode::streamTo):
        (KJS::LessEqNode::streamTo):
        (KJS::GreaterEqNode::streamTo):
        (KJS::InstanceOfNode::streamTo):
        (KJS::InNode::streamTo):
        (KJS::EqualNode::streamTo):
        (KJS::NotEqualNode::streamTo):
        (KJS::StrictEqualNode::streamTo):
        (KJS::NotStrictEqualNode::streamTo):
        (KJS::BitAndNode::streamTo):
        (KJS::BitXOrNode::streamTo):
        (KJS::BitOrNode::streamTo):

        LayoutTests:

        * fast/js/codegen-temporaries-expected.txt:
        * fast/js/resources/codegen-temporaries.js:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@34562 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 92aaa2a0
2008-06-15 Cameron Zwarich <cwzwarich@uwaterloo.ca>
Reviewed by Maciej.
Bug 19484: More instructions needs to use temporary registers
<https://bugs.webkit.org/show_bug.cgi?id=19484>
Fix codegen for all binary operations so that temporaries are used if
necessary. This was done by making BinaryOpNode and ReverseBinaryOpNode
subclasses of ExpressionNode, and eliminating the custom emitCode()
methods for the individual node classes.
This only adds 3 new instructions to SunSpider code, and there is no
difference in SunSpider execution time.
* VM/CodeGenerator.cpp:
(KJS::CodeGenerator::emitBitNot):
(KJS::CodeGenerator::emitBinaryOp):
* VM/CodeGenerator.h:
* kjs/grammar.y:
* kjs/nodes.cpp:
(KJS::PreIncResolveNode::emitCode):
(KJS::PreDecResolveNode::emitCode):
(KJS::BinaryOpNode::emitCode):
(KJS::ReverseBinaryOpNode::emitCode):
(KJS::emitReadModifyAssignment):
(KJS::CaseBlockNode::emitCodeForBlock):
* kjs/nodes.h:
(KJS::BinaryOpNode::BinaryOpNode):
(KJS::ReverseBinaryOpNode::ReverseBinaryOpNode):
(KJS::MultNode::):
(KJS::DivNode::):
(KJS::DivNode::precedence):
(KJS::ModNode::):
(KJS::ModNode::precedence):
(KJS::AddNode::):
(KJS::AddNode::precedence):
(KJS::SubNode::):
(KJS::SubNode::precedence):
(KJS::LeftShiftNode::):
(KJS::LeftShiftNode::precedence):
(KJS::RightShiftNode::):
(KJS::RightShiftNode::precedence):
(KJS::UnsignedRightShiftNode::):
(KJS::UnsignedRightShiftNode::precedence):
(KJS::LessNode::):
(KJS::LessNode::precedence):
(KJS::GreaterNode::):
(KJS::GreaterNode::precedence):
(KJS::LessEqNode::):
(KJS::LessEqNode::precedence):
(KJS::GreaterEqNode::):
(KJS::GreaterEqNode::precedence):
(KJS::InstanceOfNode::):
(KJS::InstanceOfNode::precedence):
(KJS::InNode::):
(KJS::InNode::precedence):
(KJS::EqualNode::):
(KJS::EqualNode::precedence):
(KJS::NotEqualNode::):
(KJS::NotEqualNode::precedence):
(KJS::StrictEqualNode::):
(KJS::StrictEqualNode::precedence):
(KJS::NotStrictEqualNode::):
(KJS::NotStrictEqualNode::precedence):
(KJS::BitAndNode::):
(KJS::BitAndNode::precedence):
(KJS::BitOrNode::):
(KJS::BitOrNode::precedence):
(KJS::BitXOrNode::):
(KJS::BitXOrNode::precedence):
* kjs/nodes2string.cpp:
(KJS::LessNode::streamTo):
(KJS::GreaterNode::streamTo):
(KJS::LessEqNode::streamTo):
(KJS::GreaterEqNode::streamTo):
(KJS::InstanceOfNode::streamTo):
(KJS::InNode::streamTo):
(KJS::EqualNode::streamTo):
(KJS::NotEqualNode::streamTo):
(KJS::StrictEqualNode::streamTo):
(KJS::NotStrictEqualNode::streamTo):
(KJS::BitAndNode::streamTo):
(KJS::BitXOrNode::streamTo):
(KJS::BitOrNode::streamTo):
2008-06-14 Darin Adler <darin@apple.com>
Rubber stamped by Sam.
......
......@@ -517,60 +517,6 @@ RegisterID* CodeGenerator::emitNot(RegisterID* dst, RegisterID* src)
return dst;
}
RegisterID* CodeGenerator::emitEqual(RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
emitOpcode(op_eq);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
RegisterID* CodeGenerator::emitNotEqual(RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
emitOpcode(op_neq);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
RegisterID* CodeGenerator::emitStrictEqual(RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
emitOpcode(op_stricteq);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
RegisterID* CodeGenerator::emitNotStrictEqual(RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
emitOpcode(op_nstricteq);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
RegisterID* CodeGenerator::emitLess(RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
emitOpcode(op_less);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
RegisterID* CodeGenerator::emitLessEq(RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
emitOpcode(op_lesseq);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
RegisterID* CodeGenerator::emitPreInc(RegisterID* srcDst)
{
emitOpcode(op_pre_inc);
......@@ -617,113 +563,23 @@ RegisterID* CodeGenerator::emitNegate(RegisterID* dst, RegisterID* src)
return dst;
}
RegisterID* CodeGenerator::emitAdd(RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
emitOpcode(op_add);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
RegisterID* CodeGenerator::emitMul(RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
emitOpcode(op_mul);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
RegisterID* CodeGenerator::emitDiv(RegisterID* dst, RegisterID* dividend, RegisterID* divisor)
{
emitOpcode(op_div);
instructions().append(dst->index());
instructions().append(dividend->index());
instructions().append(divisor->index());
return dst;
}
RegisterID* CodeGenerator::emitMod(RegisterID* dst, RegisterID* dividend, RegisterID* divisor)
{
emitOpcode(op_mod);
instructions().append(dst->index());
instructions().append(dividend->index());
instructions().append(divisor->index());
return dst;
}
RegisterID* CodeGenerator::emitSub(RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
emitOpcode(op_sub);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
RegisterID* CodeGenerator::emitLeftShift(RegisterID* dst, RegisterID* val, RegisterID* shift)
{
emitOpcode(op_lshift);
instructions().append(dst->index());
instructions().append(val->index());
instructions().append(shift->index());
return dst;
}
RegisterID* CodeGenerator::emitRightShift(RegisterID* dst, RegisterID* val, RegisterID* shift)
{
emitOpcode(op_rshift);
instructions().append(dst->index());
instructions().append(val->index());
instructions().append(shift->index());
return dst;
}
RegisterID* CodeGenerator::emitUnsignedRightShift(RegisterID* dst, RegisterID* val, RegisterID* shift)
{
emitOpcode(op_urshift);
instructions().append(dst->index());
instructions().append(val->index());
instructions().append(shift->index());
return dst;
}
RegisterID* CodeGenerator::emitBitAnd(RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
emitOpcode(op_bitand);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
RegisterID* CodeGenerator::emitBitXOr(RegisterID* dst, RegisterID* src1, RegisterID* src2)
RegisterID* CodeGenerator::emitBitNot(RegisterID* dst, RegisterID* src)
{
emitOpcode(op_bitxor);
emitOpcode(op_bitnot);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
instructions().append(src->index());
return dst;
}
RegisterID* CodeGenerator::emitBitOr(RegisterID* dst, RegisterID* src1, RegisterID* src2)
RegisterID* CodeGenerator::emitBinaryOp(OpcodeID opcode, RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
emitOpcode(op_bitor);
emitOpcode(opcode);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
RegisterID* CodeGenerator::emitBitNot(RegisterID* dst, RegisterID* src)
{
emitOpcode(op_bitnot);
instructions().append(dst->index());
instructions().append(src->index());
return dst;
}
RegisterID* CodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base)
{
emitOpcode(op_instanceof);
......
......@@ -202,12 +202,7 @@ namespace KJS {
RegisterID* emitMove(RegisterID* dst, RegisterID* src);
RegisterID* emitNot(RegisterID* dst, RegisterID* src);
RegisterID* emitEqual(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitNotEqual(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitStrictEqual(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitNotStrictEqual(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitLess(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitLessEq(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitBitNot(RegisterID* dst, RegisterID* src);
RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src);
RegisterID* emitNegate(RegisterID* dst, RegisterID* src);
......@@ -215,20 +210,8 @@ namespace KJS {
RegisterID* emitPreDec(RegisterID* srcDst);
RegisterID* emitPostInc(RegisterID* dst, RegisterID* srcDst);
RegisterID* emitPostDec(RegisterID* dst, RegisterID* srcDst);
RegisterID* emitAdd(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitMul(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitDiv(RegisterID* dst, RegisterID* dividend, RegisterID* divisor);
RegisterID* emitMod(RegisterID* dst, RegisterID* dividend, RegisterID* divisor);
RegisterID* emitSub(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitLeftShift(RegisterID* dst, RegisterID* val, RegisterID* shift);
RegisterID* emitRightShift(RegisterID* dst, RegisterID* val, RegisterID* shift);
RegisterID* emitUnsignedRightShift(RegisterID* dst, RegisterID* val, RegisterID* shift);
RegisterID* emitBitAnd(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitBitXOr(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitBitOr(RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitBitNot(RegisterID* dst, RegisterID* src);
RegisterID* emitBinaryOp(OpcodeID opcode, RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base);
RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src);
......
......@@ -458,19 +458,19 @@ UnaryExprNoBF:
MultiplicativeExpr:
UnaryExpr
| MultiplicativeExpr '*' UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new MultNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| MultiplicativeExpr '/' UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new DivNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| MultiplicativeExpr '%' UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new ModNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| MultiplicativeExpr '*' UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new MultNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| MultiplicativeExpr '/' UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new DivNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| MultiplicativeExpr '%' UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new ModNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
MultiplicativeExprNoBF:
UnaryExprNoBF
| MultiplicativeExprNoBF '*' UnaryExpr
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new MultNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new MultNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| MultiplicativeExprNoBF '/' UnaryExpr
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new DivNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new DivNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| MultiplicativeExprNoBF '%' UnaryExpr
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new ModNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new ModNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
AdditiveExpr:
......@@ -489,128 +489,128 @@ AdditiveExprNoBF:
ShiftExpr:
AdditiveExpr
| ShiftExpr LSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LeftShiftNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| ShiftExpr RSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new RightShiftNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| ShiftExpr URSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new UnsignedRightShiftNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| ShiftExpr LSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LeftShiftNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| ShiftExpr RSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new RightShiftNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| ShiftExpr URSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new UnsignedRightShiftNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
ShiftExprNoBF:
AdditiveExprNoBF
| ShiftExprNoBF LSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LeftShiftNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| ShiftExprNoBF RSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new RightShiftNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| ShiftExprNoBF URSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new UnsignedRightShiftNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| ShiftExprNoBF LSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LeftShiftNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| ShiftExprNoBF RSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new RightShiftNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| ShiftExprNoBF URSHIFT AdditiveExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new UnsignedRightShiftNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
RelationalExpr:
ShiftExpr
| RelationalExpr '<' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExpr '>' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExpr LE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessEqNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExpr GE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterEqNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExpr INSTANCEOF ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new InstanceOfNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExpr INTOKEN ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new InNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExpr '<' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExpr '>' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExpr LE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessEqNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExpr GE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterEqNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExpr INSTANCEOF ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new InstanceOfNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExpr INTOKEN ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new InNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
RelationalExprNoIn:
ShiftExpr
| RelationalExprNoIn '<' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoIn '>' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoIn LE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessEqNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoIn GE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterEqNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoIn '<' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoIn '>' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoIn LE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessEqNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoIn GE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterEqNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoIn INSTANCEOF ShiftExpr
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new InstanceOfNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new InstanceOfNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
RelationalExprNoBF:
ShiftExprNoBF
| RelationalExprNoBF '<' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoBF '>' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoBF LE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessEqNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoBF GE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterEqNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoBF '<' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoBF '>' ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoBF LE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new LessEqNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoBF GE ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new GreaterEqNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoBF INSTANCEOF ShiftExpr
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new InstanceOfNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoBF INTOKEN ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new InNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new InstanceOfNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| RelationalExprNoBF INTOKEN ShiftExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new InNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
EqualityExpr:
RelationalExpr
| EqualityExpr EQEQ RelationalExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new EqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExpr NE RelationalExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new NotEqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExpr STREQ RelationalExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new StrictEqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExpr STRNEQ RelationalExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new NotStrictEqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExpr EQEQ RelationalExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new EqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExpr NE RelationalExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new NotEqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExpr STREQ RelationalExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new StrictEqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExpr STRNEQ RelationalExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new NotStrictEqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
EqualityExprNoIn:
RelationalExprNoIn
| EqualityExprNoIn EQEQ RelationalExprNoIn
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new EqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new EqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExprNoIn NE RelationalExprNoIn
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new NotEqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new NotEqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExprNoIn STREQ RelationalExprNoIn
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new StrictEqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new StrictEqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExprNoIn STRNEQ RelationalExprNoIn
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new NotStrictEqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new NotStrictEqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
EqualityExprNoBF:
RelationalExprNoBF
| EqualityExprNoBF EQEQ RelationalExpr
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new EqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExprNoBF NE RelationalExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new NotEqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new EqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExprNoBF NE RelationalExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new NotEqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExprNoBF STREQ RelationalExpr
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new StrictEqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new StrictEqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
| EqualityExprNoBF STRNEQ RelationalExpr
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new NotStrictEqualNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new NotStrictEqualNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
BitwiseANDExpr:
EqualityExpr
| BitwiseANDExpr '&' EqualityExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new BitAndNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| BitwiseANDExpr '&' EqualityExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new BitAndNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
BitwiseANDExprNoIn:
EqualityExprNoIn
| BitwiseANDExprNoIn '&' EqualityExprNoIn
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new BitAndNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new BitAndNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
BitwiseANDExprNoBF:
EqualityExprNoBF
| BitwiseANDExprNoBF '&' EqualityExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new BitAndNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| BitwiseANDExprNoBF '&' EqualityExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new BitAndNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
BitwiseXORExpr:
BitwiseANDExpr
| BitwiseXORExpr '^' BitwiseANDExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new BitXOrNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| BitwiseXORExpr '^' BitwiseANDExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new BitXOrNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
BitwiseXORExprNoIn:
BitwiseANDExprNoIn
| BitwiseXORExprNoIn '^' BitwiseANDExprNoIn
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new BitXOrNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new BitXOrNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
BitwiseXORExprNoBF:
BitwiseANDExprNoBF
| BitwiseXORExprNoBF '^' BitwiseANDExpr
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new BitXOrNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new BitXOrNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
BitwiseORExpr:
BitwiseXORExpr
| BitwiseORExpr '|' BitwiseXORExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new BitOrNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
| BitwiseORExpr '|' BitwiseXORExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new BitOrNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
BitwiseORExprNoIn:
BitwiseXORExprNoIn
| BitwiseORExprNoIn '|' BitwiseXORExprNoIn
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new BitOrNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new BitOrNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
BitwiseORExprNoBF:
BitwiseXORExprNoBF
| BitwiseORExprNoBF '|' BitwiseXORExpr
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new BitOrNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
{ $$ = createNodeFeatureInfo<ExpressionNode*>(new BitOrNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
;
LogicalANDExpr:
......
......@@ -664,7 +664,7 @@ RegisterID* PreIncResolveNode::emitCode(CodeGenerator& generator, RegisterID* ds
if (RegisterID* local = generator.registerForLocal(m_ident)) {
if (generator.isLocalConstant(m_ident)) {
RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), 1.0);
return generator.emitAdd(r0.get(), local, r0.get());
return generator.emitBinaryOp(op_add, r0.get(), local, r0.get());
}
generator.emitPreInc(local);
......@@ -692,7 +692,7 @@ RegisterID* PreDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* ds
if (RegisterID* local = generator.registerForLocal(m_ident)) {
if (generator.isLocalConstant(m_ident)) {
RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), -1.0);
return generator.emitAdd(r0.get(), local, r0.get());
return generator.emitBinaryOp(op_add, r0.get(), local, r0.get());
}
generator.emitPreDec(local);
......@@ -801,163 +801,20 @@ RegisterID* LogicalNotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
return generator.emitNot(generator.finalDestination(dst), src);
}
// ------------------------------ Multiplicative Nodes -----------------------------------
// ------------------------------ Binary Operation Nodes -----------------------------------
RegisterID* MultNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
RegisterID* src2 = generator.emitNode(m_term2.get());
return generator.emitMul(generator.finalDestination(dst, src1.get()), src1.get(), src2);
}
RegisterID* DivNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> dividend = generator.emitNode(m_term1.get());
RegisterID* divisor = generator.emitNode(m_term2.get());
return generator.emitDiv(generator.finalDestination(dst, dividend.get()), dividend.get(), divisor);
}
RegisterID* ModNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> dividend = generator.emitNode(m_term1.get());
RegisterID* divisor = generator.emitNode(m_term2.get());
return generator.emitMod(generator.finalDestination(dst, dividend.get()), dividend.get(), divisor);
}
// ------------------------------ Additive Nodes --------------------------------------
RegisterID* AddNode::emitCode(CodeGenerator& generator, RegisterID* dst)
RegisterID* BinaryOpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_term1.get(), m_rightHasAssignments, m_term2->isPure(generator));
RegisterID* src2 = generator.emitNode(m_term2.get());
return generator.emitAdd(generator.finalDestination(dst, src1.get()), src1.get(), src2);
return generator.emitBinaryOp(opcode(), generator.finalDestination(dst, src1.get()), src1.get(), src2);
}
RegisterID* SubNode::emitCode(CodeGenerator& generator, RegisterID* dst)
RegisterID* ReverseBinaryOpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_term1.get(), m_rightHasAssignments, m_term2->isPure(generator));
RegisterID* src2 = generator.emitNode(m_term2.get());
return generator.emitSub(generator.finalDestination(dst, src1.get()), src1.get(), src2);
}
// ------------------------------ Shift Nodes ------------------------------------
RegisterID* LeftShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
RegisterID* shift = generator.emitNode(m_term2.get());
return generator.emitLeftShift(generator.finalDestination(dst, val.get()), val.get(), shift);
}
RegisterID* RightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
RegisterID* shift = generator.emitNode(m_term2.get());
return generator.emitRightShift(generator.finalDestination(dst, val.get()), val.get(), shift);
}
RegisterID* UnsignedRightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
RegisterID* shift = generator.emitNode(m_term2.get());
return generator.emitUnsignedRightShift(generator.finalDestination(dst, val.get()), val.get(), shift);
}
// ------------------------------ Relational Nodes -------------------------------
RegisterID* LessNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
RegisterID* src2 = generator.emitNode(m_expr2.get());
return generator.emitLess(generator.finalDestination(dst, src1.get()), src1.get(), src2);
}
RegisterID* GreaterNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
RegisterID* src2 = generator.emitNode(m_expr2.get());
return generator.emitLess(generator.finalDestination(dst, src1.get()), src2, src1.get());
}
RegisterID* LessEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
RegisterID* src2 = generator.emitNode(m_expr2.get());
return generator.emitLessEq(generator.finalDestination(dst, src1.get()), src1.get(), src2);
}
RegisterID* GreaterEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
RegisterID* src2 = generator.emitNode(m_expr2.get());
return generator.emitLessEq(generator.finalDestination(dst, src1.get()), src2, src1.get());