aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h34
-rw-r--r--src/qml/compiler/qv4codegen.cpp122
-rw-r--r--src/qml/compiler/qv4codegen_p.h2
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp85
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h56
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp154
6 files changed, 227 insertions, 226 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index d28d16ff5f..ece05b41ac 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -158,30 +158,32 @@ public:
return addJumpInstruction(data);
}
- Q_REQUIRED_RESULT Jump jumpEq()
+ Q_REQUIRED_RESULT Jump jumpTrue()
{
- Instruction::JumpEq data;
+ Instruction::JumpTrue data;
return addJumpInstruction(data);
}
- Q_REQUIRED_RESULT Jump jumpNe()
+ Q_REQUIRED_RESULT Jump jumpFalse()
{
- Instruction::JumpNe data;
+ Instruction::JumpFalse data;
return addJumpInstruction(data);
}
- Q_REQUIRED_RESULT Jump jumpStrictEqual(const StackSlot &lhs)
+ void jumpStrictEqual(const StackSlot &lhs, const Label &target)
{
- Instruction::JumpStrictEqual data;
- data.lhs = lhs;
- return addJumpInstruction(data);
+ Instruction::CmpStrictEqual cmp;
+ cmp.lhs = lhs;
+ addInstruction(cmp);
+ addJumpInstruction(Instruction::JumpTrue()).link(target);
}
- Q_REQUIRED_RESULT Jump jumpStrictNotEqual(const StackSlot &lhs)
+ void jumpStrictNotEqual(const StackSlot &lhs, const Label &target)
{
- Instruction::JumpStrictNotEqual data;
- data.lhs = lhs;
- return addJumpInstruction(data);
+ Instruction::CmpStrictNotEqual cmp;
+ cmp.lhs = lhs;
+ addInstruction(cmp);
+ addJumpInstruction(Instruction::JumpTrue()).link(target);
}
Q_REQUIRED_RESULT Jump jumpStrictEqualStackSlotInt(const StackSlot &lhs, int rhs)
@@ -231,6 +233,14 @@ public:
return Jump(this, addInstructionHelper(Moth::Instr::Type(InstrT), genericInstr, offsetof(InstrData<InstrT>, offset)));
}
+ void addCJumpInstruction(bool jumpOnFalse, const Label *trueLabel, const Label *falseLabel)
+ {
+ if (jumpOnFalse)
+ addJumpInstruction(Instruction::JumpFalse()).link(*falseLabel);
+ else
+ addJumpInstruction(Instruction::JumpTrue()).link(*trueLabel);
+ }
+
private:
friend struct Jump;
friend struct Label;
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 3146cbe55a..9c1cf5ce1d 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -267,6 +267,12 @@ Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr)
Q_UNREACHABLE();
}
+void Codegen::addCJump()
+{
+ bytecodeGenerator->addCJumpInstruction(_expr.trueBlockFollowsCondition(),
+ _expr.iftrue(), _expr.iffalse());
+}
+
void Codegen::accept(Node *node)
{
if (hasError)
@@ -316,9 +322,9 @@ void Codegen::condition(ExpressionNode *ast, const BytecodeGenerator::Label *ift
bytecodeGenerator->setLocation(ast->firstSourceLocation());
r.result().loadInAccumulator();
if (r.trueBlockFollowsCondition())
- bytecodeGenerator->jumpNe().link(*r.iffalse());
+ bytecodeGenerator->jumpFalse().link(*r.iffalse());
else
- bytecodeGenerator->jumpEq().link(*r.iftrue());
+ bytecodeGenerator->jumpTrue().link(*r.iftrue());
}
}
}
@@ -719,7 +725,7 @@ bool Codegen::visit(BinaryExpression *ast)
left.loadInAccumulator();
bytecodeGenerator->setLocation(ast->operatorToken);
- bytecodeGenerator->jumpNe().link(endif);
+ bytecodeGenerator->jumpFalse().link(endif);
iftrue.link();
Reference right = expression(ast->right);
@@ -748,7 +754,7 @@ bool Codegen::visit(BinaryExpression *ast)
left.loadInAccumulator();
bytecodeGenerator->setLocation(ast->operatorToken);
- bytecodeGenerator->jumpEq().link(endif);
+ bytecodeGenerator->jumpTrue().link(endif);
iffalse.link();
Reference right = expression(ast->right);
@@ -1021,21 +1027,6 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
return Reference::fromAccumulator(this);
}
-static QSOperator::Op invert(QSOperator::Op oper)
-{
- switch (oper) {
- case QSOperator::StrictEqual: return QSOperator::StrictNotEqual;
- case QSOperator::StrictNotEqual: return QSOperator::StrictEqual;
- case QSOperator::Equal: return QSOperator::NotEqual;
- case QSOperator::NotEqual: return QSOperator::Equal;
- case QSOperator::Gt: return QSOperator::Le;
- case QSOperator::Ge: return QSOperator::Lt;
- case QSOperator::Lt: return QSOperator::Ge;
- case QSOperator::Le: return QSOperator::Gt;
- default: Q_UNIMPLEMENTED(); return QSOperator::Invalid;
- }
-}
-
static QSOperator::Op operatorForSwappedOperands(QSOperator::Op oper)
{
switch (oper) {
@@ -1057,36 +1048,35 @@ Codegen::Reference Codegen::jumpBinop(QSOperator::Op oper, Reference &left, Refe
oper = operatorForSwappedOperands(oper);
qSwap(left, right);
}
- const BytecodeGenerator::Label *jumpTarget = _expr.iftrue();
- if (_expr.trueBlockFollowsCondition()) {
- oper = invert(oper);
- jumpTarget = _expr.iffalse();
- }
if (right.isConst() && (oper == QSOperator::Equal || oper == QSOperator::NotEqual)) {
Value c = Primitive::fromReturnedValue(right.constant);
if (c.isNull() || c.isUndefined()) {
left.loadInAccumulator();
if (oper == QSOperator::Equal) {
- Instruction::CmpJmpEqNull cjump;
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpEqNull cmp;
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
return Reference();
} else if (oper == QSOperator::NotEqual) {
- Instruction::CmpJmpNeNull cjump;
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpNeNull cmp;
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
return Reference();
}
} else if (c.isInt32()) {
left.loadInAccumulator();
if (oper == QSOperator::Equal) {
- Instruction::CmpJmpEqInt cjump;
- cjump.lhs = c.int_32();
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpEqInt cmp;
+ cmp.lhs = c.int_32();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
return Reference();
} else if (oper == QSOperator::NotEqual) {
- Instruction::CmpJmpNeInt cjump;
- cjump.lhs = c.int_32();
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpNeInt cmp;
+ cmp.lhs = c.int_32();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
return Reference();
}
@@ -1098,51 +1088,59 @@ Codegen::Reference Codegen::jumpBinop(QSOperator::Op oper, Reference &left, Refe
switch (oper) {
case QSOperator::StrictEqual: {
- Instruction::JumpStrictEqual cjump;
- cjump.lhs = left.stackSlot();
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpStrictEqual cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
break;
}
case QSOperator::StrictNotEqual: {
- Instruction::JumpStrictNotEqual cjump;
- cjump.lhs = left.stackSlot();
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpStrictNotEqual cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
break;
}
case QSOperator::Equal: {
- Instruction::CmpJmpEq cjump;
- cjump.lhs = left.stackSlot();
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpEq cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
break;
}
case QSOperator::NotEqual: {
- Instruction::CmpJmpNe cjump;
- cjump.lhs = left.stackSlot();
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpNe cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
break;
}
case QSOperator::Gt: {
- Instruction::CmpJmpGt cjump;
- cjump.lhs = left.stackSlot();
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpGt cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
break;
}
case QSOperator::Ge: {
- Instruction::CmpJmpGe cjump;
- cjump.lhs = left.stackSlot();
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpGe cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
break;
}
case QSOperator::Lt: {
- Instruction::CmpJmpLt cjump;
- cjump.lhs = left.stackSlot();
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpLt cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
break;
}
case QSOperator::Le: {
- Instruction::CmpJmpLe cjump;
- cjump.lhs = left.stackSlot();
- bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ Instruction::CmpLe cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
break;
}
default: Q_UNIMPLEMENTED(); Q_UNREACHABLE();
@@ -2242,7 +2240,7 @@ bool Codegen::visit(ForEachStatement *ast)
lhs = lhs.storeRetainAccumulator().storeOnStack();
Reference::fromConst(this, QV4::Encode::null()).loadInAccumulator();
- bytecodeGenerator->jumpStrictNotEqual(lhs.stackSlot()).link(body);
+ bytecodeGenerator->jumpStrictNotEqual(lhs.stackSlot(), body);
end.link();
@@ -2384,7 +2382,7 @@ bool Codegen::visit(LocalForEachStatement *ast)
auto lhs = it.storeRetainAccumulator().storeOnStack();
Reference::fromConst(this, QV4::Encode::null()).loadInAccumulator();
- bytecodeGenerator->jumpStrictNotEqual(lhs.stackSlot()).link(body);
+ bytecodeGenerator->jumpStrictNotEqual(lhs.stackSlot(), body);
end.link();
@@ -2483,7 +2481,7 @@ bool Codegen::visit(SwitchStatement *ast)
if (hasError)
return false;
rhs.loadInAccumulator();
- bytecodeGenerator->jumpStrictEqual(lhs.stackSlot()).link(blockMap.value(clause));
+ bytecodeGenerator->jumpStrictEqual(lhs.stackSlot(), blockMap.value(clause));
}
for (CaseClauses *it = ast->block->moreClauses; it; it = it->next) {
@@ -2492,7 +2490,7 @@ bool Codegen::visit(SwitchStatement *ast)
if (hasError)
return false;
rhs.loadInAccumulator();
- bytecodeGenerator->jumpStrictEqual(lhs.stackSlot()).link(blockMap.value(clause));
+ bytecodeGenerator->jumpStrictEqual(lhs.stackSlot(), blockMap.value(clause));
}
if (DefaultClause *defaultClause = ast->block->defaultClause)
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index 2ccf97d7a2..78f804013f 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -456,6 +456,8 @@ protected:
Reference unop(UnaryOperation op, const Reference &expr);
+ void addCJump();
+
int registerString(const QString &name) {
return jsUnitGenerator->registerString(name);
}
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index ee787c97c0..20917a5ee3 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -230,9 +230,9 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_BEGIN_INSTR(StoreLocal)
if (index < nLocals)
- d << ", " << "l" << index;
+ d << "l" << index;
else
- d << ", " << "a" << (index - nLocals);
+ d << "a" << (index - nLocals);
MOTH_END_INSTR(StoreLocal)
MOTH_BEGIN_INSTR(LoadScopedLocal)
@@ -449,62 +449,59 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << ABSOLUTE_OFFSET();
MOTH_END_INSTR(Jump)
- MOTH_BEGIN_INSTR(JumpEq)
- d << "acc " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(JumpEq)
-
- MOTH_BEGIN_INSTR(JumpNe)
- d << "acc " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(JumpNe)
-
- MOTH_BEGIN_INSTR(CmpJmpEqNull)
+ MOTH_BEGIN_INSTR(JumpTrue)
d << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(CmpJmpEqNull)
+ MOTH_END_INSTR(JumpTrue)
- MOTH_BEGIN_INSTR(CmpJmpNeNull)
+ MOTH_BEGIN_INSTR(JumpFalse)
d << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(CmpJmpNeNull)
+ MOTH_END_INSTR(JumpFalse)
+
+ MOTH_BEGIN_INSTR(CmpEqNull)
+ MOTH_END_INSTR(CmpEqNull)
- MOTH_BEGIN_INSTR(CmpJmpEqInt)
- d << lhs << ", " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(CmpJmpEq)
+ MOTH_BEGIN_INSTR(CmpNeNull)
+ MOTH_END_INSTR(CmpNeNull)
- MOTH_BEGIN_INSTR(CmpJmpNeInt)
- d << lhs << ", " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(CmpJmpNe)
+ MOTH_BEGIN_INSTR(CmpEqInt)
+ d << lhs;
+ MOTH_END_INSTR(CmpEq)
+ MOTH_BEGIN_INSTR(CmpNeInt)
+ d << lhs;
+ MOTH_END_INSTR(CmpNeInt)
- MOTH_BEGIN_INSTR(CmpJmpEq)
- d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(CmpJmpEq)
+ MOTH_BEGIN_INSTR(CmpEq)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpEq)
- MOTH_BEGIN_INSTR(CmpJmpNe)
- d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(CmpJmpNe)
+ MOTH_BEGIN_INSTR(CmpNe)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpNe)
- MOTH_BEGIN_INSTR(CmpJmpGt)
- d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(CmpJmpGt)
+ MOTH_BEGIN_INSTR(CmpGt)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpGt)
- MOTH_BEGIN_INSTR(CmpJmpGe)
- d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(CmpJmpGe)
+ MOTH_BEGIN_INSTR(CmpGe)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpGe)
- MOTH_BEGIN_INSTR(CmpJmpLt)
- d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(CmpJmpLt)
+ MOTH_BEGIN_INSTR(CmpLt)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpLt)
- MOTH_BEGIN_INSTR(CmpJmpLe)
- d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(CmpJmpLe)
+ MOTH_BEGIN_INSTR(CmpLe)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpLe)
- MOTH_BEGIN_INSTR(JumpStrictEqual)
- d << dumpRegister(lhs, nFormals) << " " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(JumpStrictEqual)
+ MOTH_BEGIN_INSTR(CmpStrictEqual)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpStrictEqual)
- MOTH_BEGIN_INSTR(JumpStrictNotEqual)
- d << dumpRegister(lhs, nFormals) << " " << ABSOLUTE_OFFSET();
- MOTH_END_INSTR(JumpStrictNotEqual)
+ MOTH_BEGIN_INSTR(CmpStrictNotEqual)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpStrictNotEqual)
MOTH_BEGIN_INSTR(JumpStrictEqualStackSlotInt)
d << dumpRegister(lhs, nFormals) << ", " << rhs << " " << ABSOLUTE_OFFSET();
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 44bd2c0db9..90ed2c804c 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -140,20 +140,20 @@ QT_BEGIN_NAMESPACE
#define INSTR_ConvertThisToObject(op) INSTRUCTION(op, ConvertThisToObject, 0)
#define INSTR_Construct(op) INSTRUCTION(op, Construct, 2, callData, func)
#define INSTR_Jump(op) INSTRUCTION(op, Jump, 1, offset)
-#define INSTR_JumpEq(op) INSTRUCTION(op, JumpEq, 1, offset)
-#define INSTR_JumpNe(op) INSTRUCTION(op, JumpNe, 1, offset)
-#define INSTR_CmpJmpEqNull(op) INSTRUCTION(op, CmpJmpEqNull, 1, offset)
-#define INSTR_CmpJmpNeNull(op) INSTRUCTION(op, CmpJmpNeNull, 1, offset)
-#define INSTR_CmpJmpEqInt(op) INSTRUCTION(op, CmpJmpEqInt, 2, lhs, offset)
-#define INSTR_CmpJmpNeInt(op) INSTRUCTION(op, CmpJmpNeInt, 2, lhs, offset)
-#define INSTR_CmpJmpEq(op) INSTRUCTION(op, CmpJmpEq, 2, lhs, offset)
-#define INSTR_CmpJmpNe(op) INSTRUCTION(op, CmpJmpNe, 2, lhs, offset)
-#define INSTR_CmpJmpGt(op) INSTRUCTION(op, CmpJmpGt, 2, lhs, offset)
-#define INSTR_CmpJmpGe(op) INSTRUCTION(op, CmpJmpGe, 2, lhs, offset)
-#define INSTR_CmpJmpLt(op) INSTRUCTION(op, CmpJmpLt, 2, lhs, offset)
-#define INSTR_CmpJmpLe(op) INSTRUCTION(op, CmpJmpLe, 2, lhs, offset)
-#define INSTR_JumpStrictEqual(op) INSTRUCTION(op, JumpStrictEqual, 2, lhs, offset)
-#define INSTR_JumpStrictNotEqual(op) INSTRUCTION(op, JumpStrictNotEqual, 2, lhs, offset)
+#define INSTR_JumpTrue(op) INSTRUCTION(op, JumpTrue, 1, offset)
+#define INSTR_JumpFalse(op) INSTRUCTION(op, JumpFalse, 1, offset)
+#define INSTR_CmpEqNull(op) INSTRUCTION(op, CmpEqNull, 0)
+#define INSTR_CmpNeNull(op) INSTRUCTION(op, CmpNeNull, 0)
+#define INSTR_CmpEqInt(op) INSTRUCTION(op, CmpEqInt, 1, lhs)
+#define INSTR_CmpNeInt(op) INSTRUCTION(op, CmpNeInt, 1, lhs)
+#define INSTR_CmpEq(op) INSTRUCTION(op, CmpEq, 1, lhs)
+#define INSTR_CmpNe(op) INSTRUCTION(op, CmpNe, 1, lhs)
+#define INSTR_CmpGt(op) INSTRUCTION(op, CmpGt, 1, lhs)
+#define INSTR_CmpGe(op) INSTRUCTION(op, CmpGe, 1, lhs)
+#define INSTR_CmpLt(op) INSTRUCTION(op, CmpLt, 1, lhs)
+#define INSTR_CmpLe(op) INSTRUCTION(op, CmpLe, 1, lhs)
+#define INSTR_CmpStrictEqual(op) INSTRUCTION(op, CmpStrictEqual, 1, lhs)
+#define INSTR_CmpStrictNotEqual(op) INSTRUCTION(op, CmpStrictNotEqual, 1, lhs)
#define INSTR_JumpStrictEqualStackSlotInt(op) INSTRUCTION(op, JumpStrictEqualStackSlotInt, 3, lhs, rhs, offset)
#define INSTR_JumpStrictNotEqualStackSlotInt(op) INSTRUCTION(op, JumpStrictNotEqualStackSlotInt, 3, lhs, rhs, offset)
#define INSTR_UNot(op) INSTRUCTION(op, UNot, 0)
@@ -253,20 +253,20 @@ QT_BEGIN_NAMESPACE
F(ConvertThisToObject) \
F(Construct) \
F(Jump) \
- F(JumpEq) \
- F(JumpNe) \
- F(CmpJmpEqNull) \
- F(CmpJmpNeNull) \
- F(CmpJmpEqInt) \
- F(CmpJmpNeInt) \
- F(CmpJmpEq) \
- F(CmpJmpNe) \
- F(CmpJmpGt) \
- F(CmpJmpGe) \
- F(CmpJmpLt) \
- F(CmpJmpLe) \
- F(JumpStrictEqual) \
- F(JumpStrictNotEqual) \
+ F(JumpTrue) \
+ F(JumpFalse) \
+ F(CmpEqNull) \
+ F(CmpNeNull) \
+ F(CmpEqInt) \
+ F(CmpNeInt) \
+ F(CmpEq) \
+ F(CmpNe) \
+ F(CmpGt) \
+ F(CmpGe) \
+ F(CmpLt) \
+ F(CmpLe) \
+ F(CmpStrictEqual) \
+ F(CmpStrictNotEqual) \
F(JumpStrictEqualStackSlotInt) \
F(JumpStrictNotEqualStackSlotInt) \
F(UNot) \
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index e4d29436c0..2e33764099 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -933,149 +933,143 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
code += offset;
MOTH_END_INSTR(Jump)
- MOTH_BEGIN_INSTR(JumpEq)
+ MOTH_BEGIN_INSTR(JumpTrue)
+ //### store a type hint, and if the input is a bool, do:
+ // ((acc & 1) == 1)
+ // because if(1) will end up here with an integer in the accumulator
if ((ACC.integerCompatible() && ACC.int_32()) || ACC.toBoolean())
code += offset;
- MOTH_END_INSTR(JumpEq)
+ MOTH_END_INSTR(JumpTrue)
- MOTH_BEGIN_INSTR(JumpNe)
+ MOTH_BEGIN_INSTR(JumpFalse)
+ //### see comment for JumpTrue
if ((ACC.integerCompatible() && !ACC.int_32()) || !ACC.toBoolean())
code += offset;
- MOTH_END_INSTR(JumpNe)
+ MOTH_END_INSTR(JumpFalse)
- MOTH_BEGIN_INSTR(CmpJmpEqNull)
- if (ACC.isNullOrUndefined())
- code += offset;
- MOTH_END_INSTR(CmpJmpEqNull)
+ MOTH_BEGIN_INSTR(CmpEqNull)
+ acc = Encode(ACC.isNullOrUndefined());
+ MOTH_END_INSTR(CmpEqNull)
- MOTH_BEGIN_INSTR(CmpJmpNeNull)
- if (!ACC.isNullOrUndefined())
- code += offset;
- MOTH_END_INSTR(CmpJmpNeNull)
+ MOTH_BEGIN_INSTR(CmpNeNull)
+ acc = Encode(!ACC.isNullOrUndefined());
+ MOTH_END_INSTR(CmpNeNull)
- MOTH_BEGIN_INSTR(CmpJmpEqInt)
+ MOTH_BEGIN_INSTR(CmpEqInt)
if (ACC.isIntOrBool()) {
- if (ACC.int_32() == lhs)
- code += offset;
+ acc = Encode(ACC.int_32() == lhs);
} else {
- if (compareEqualInt(accumulator, ACC, lhs))
- code += offset;
+ STORE_ACC();
+ acc = Encode(compareEqualInt(accumulator, ACC, lhs));
+ CHECK_EXCEPTION;
}
- MOTH_END_INSTR(CmpJmpEqInt)
+ MOTH_END_INSTR(CmpEqInt)
- MOTH_BEGIN_INSTR(CmpJmpNeInt)
+ MOTH_BEGIN_INSTR(CmpNeInt)
if (ACC.isIntOrBool()) {
- if (ACC.int_32() != lhs)
- code += offset;
+ acc = Encode(bool(ACC.int_32() != lhs));
} else {
- if (!compareEqualInt(accumulator, ACC, lhs))
- code += offset;
+ STORE_ACC();
+ acc = Encode(!compareEqualInt(accumulator, ACC, lhs));
+ CHECK_EXCEPTION;
}
- MOTH_END_INSTR(CmpJmpNeInt)
+ MOTH_END_INSTR(CmpNeInt)
- MOTH_BEGIN_INSTR(CmpJmpEq)
+ MOTH_BEGIN_INSTR(CmpEq)
const Value left = STACK_VALUE(lhs);
if (Q_LIKELY(left.asReturnedValue() == ACC.asReturnedValue())) {
- code += offset;
+ acc = Encode(!ACC.isNaN());
} else if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
- if (left.int_32() == ACC.int_32())
- code += offset;
+ acc = Encode(left.int_32() == ACC.int_32());
} else {
STORE_ACC();
- if (compareEqual(left, accumulator))
- code += offset;
+ acc = Encode(compareEqual(left, accumulator));
+ CHECK_EXCEPTION;
}
- MOTH_END_INSTR(CmpJmpEq)
+ MOTH_END_INSTR(CmpEq)
- MOTH_BEGIN_INSTR(CmpJmpNe)
+ MOTH_BEGIN_INSTR(CmpNe)
const Value left = STACK_VALUE(lhs);
if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
- if (left.int_32() != ACC.int_32())
- code += offset;
+ acc = Encode(bool(left.int_32() != ACC.int_32()));
} else {
STORE_ACC();
- if (!compareEqual(left, accumulator))
- code += offset;
+ acc = Encode(!compareEqual(left, accumulator));
+ CHECK_EXCEPTION;
}
- MOTH_END_INSTR(CmpJmpNe)
+ MOTH_END_INSTR(CmpNe)
- MOTH_BEGIN_INSTR(CmpJmpGt)
+ MOTH_BEGIN_INSTR(CmpGt)
const Value left = STACK_VALUE(lhs);
if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
- if (left.int_32() > ACC.int_32())
- code += offset;
+ acc = Encode(left.int_32() > ACC.int_32());
} else if (left.isNumber() && ACC.isNumber()) {
- if (left.asDouble() > ACC.asDouble())
- code += offset;
+ acc = Encode(left.asDouble() > ACC.asDouble());
} else {
STORE_ACC();
- if (Runtime::method_compareGreaterThan(left, accumulator))
- code += offset;
+ acc = Encode(bool(Runtime::method_compareGreaterThan(left, accumulator)));
+ CHECK_EXCEPTION;
}
- MOTH_END_INSTR(CmpJmpGt)
+ MOTH_END_INSTR(CmpGt)
- MOTH_BEGIN_INSTR(CmpJmpGe)
+ MOTH_BEGIN_INSTR(CmpGe)
const Value left = STACK_VALUE(lhs);
if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
- if (left.int_32() >= ACC.int_32())
- code += offset;
+ acc = Encode(left.int_32() >= ACC.int_32());
} else if (left.isNumber() && ACC.isNumber()) {
- if (left.asDouble() >= ACC.asDouble())
- code += offset;
+ acc = Encode(left.asDouble() >= ACC.asDouble());
} else {
STORE_ACC();
- if (Runtime::method_compareGreaterEqual(left, accumulator))
- code += offset;
+ acc = Encode(bool(Runtime::method_compareGreaterEqual(left, accumulator)));
+ CHECK_EXCEPTION;
}
- MOTH_END_INSTR(CmpJmpGe)
+ MOTH_END_INSTR(CmpGe)
- MOTH_BEGIN_INSTR(CmpJmpLt)
+ MOTH_BEGIN_INSTR(CmpLt)
const Value left = STACK_VALUE(lhs);
if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
- if (left.int_32() < ACC.int_32())
- code += offset;
+ acc = Encode(left.int_32() < ACC.int_32());
} else if (left.isNumber() && ACC.isNumber()) {
- if (left.asDouble() < ACC.asDouble())
- code += offset;
+ acc = Encode(left.asDouble() < ACC.asDouble());
} else {
STORE_ACC();
- if (Runtime::method_compareLessThan(left, accumulator))
- code += offset;
+ acc = Encode(bool(Runtime::method_compareLessThan(left, accumulator)));
+ CHECK_EXCEPTION;
}
- MOTH_END_INSTR(CmpJmpLt)
+ MOTH_END_INSTR(CmpLt)
- MOTH_BEGIN_INSTR(CmpJmpLe)
+ MOTH_BEGIN_INSTR(CmpLe)
const Value left = STACK_VALUE(lhs);
if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
- if (left.int_32() <= ACC.int_32())
- code += offset;
+ acc = Encode(left.int_32() <= ACC.int_32());
} else if (left.isNumber() && ACC.isNumber()) {
- if (left.asDouble() <= ACC.asDouble())
- code += offset;
+ acc = Encode(left.asDouble() <= ACC.asDouble());
} else {
STORE_ACC();
- if (Runtime::method_compareLessEqual(left, accumulator))
- code += offset;
+ acc = Encode(bool(Runtime::method_compareLessEqual(left, accumulator)));
+ CHECK_EXCEPTION;
}
- MOTH_END_INSTR(CmpJmpLe)
+ MOTH_END_INSTR(CmpLe)
- MOTH_BEGIN_INSTR(JumpStrictEqual)
- if (STACK_VALUE(lhs).rawValue() == ACC.rawValue() && !ACC.isNaN())
- code += offset;
- else {
+ MOTH_BEGIN_INSTR(CmpStrictEqual)
+ if (STACK_VALUE(lhs).rawValue() == ACC.rawValue() && !ACC.isNaN()) {
+ acc = Encode(true);
+ } else {
STORE_ACC();
- if (RuntimeHelpers::strictEqual(STACK_VALUE(lhs), accumulator))
- code += offset;
+ acc = Encode(bool(RuntimeHelpers::strictEqual(STACK_VALUE(lhs), accumulator)));
+ CHECK_EXCEPTION;
}
- MOTH_END_INSTR(JumpStrictEqual)
+ MOTH_END_INSTR(CmpStrictEqual)
- MOTH_BEGIN_INSTR(JumpStrictNotEqual)
+ MOTH_BEGIN_INSTR(CmpStrictNotEqual)
if (STACK_VALUE(lhs).rawValue() != ACC.rawValue() || ACC.isNaN()) {
STORE_ACC();
- if (!RuntimeHelpers::strictEqual(STACK_VALUE(lhs), accumulator))
- code += offset;
+ acc = Encode(!RuntimeHelpers::strictEqual(STACK_VALUE(lhs), accumulator));
+ CHECK_EXCEPTION;
+ } else {
+ acc = Encode(false);
}
- MOTH_END_INSTR(JumpStrictNotEqual)
+ MOTH_END_INSTR(CmpStrictNotEqual)
MOTH_BEGIN_INSTR(JumpStrictNotEqualStackSlotInt)
if (STACK_VALUE(lhs).int_32() != rhs || STACK_VALUE(lhs).isUndefined())