aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qv4codegen.cpp109
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp30
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h18
-rw-r--r--src/qml/jsruntime/qv4value_p.h7
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp49
5 files changed, 115 insertions, 98 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index eac107fc16..0bf043d3fc 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -67,54 +67,6 @@ using namespace QV4;
using namespace QV4::Compiler;
using namespace QQmlJS::AST;
-static inline QV4::Runtime::RuntimeMethods aluOpFunction(QSOperator::Op op)
-{
- switch (op) {
- case QSOperator::Invalid:
- return QV4::Runtime::InvalidRuntimeMethod;
- case QSOperator::Add:
- return QV4::Runtime::InvalidRuntimeMethod;
- case QSOperator::Sub:
- return QV4::Runtime::sub;
- case QSOperator::Mul:
- return QV4::Runtime::mul;
- case QSOperator::Div:
- return QV4::Runtime::div;
- case QSOperator::Mod:
- return QV4::Runtime::mod;
- case QSOperator::LShift:
- return QV4::Runtime::shl;
- case QSOperator::RShift:
- return QV4::Runtime::shr;
- case QSOperator::URShift:
- return QV4::Runtime::ushr;
- case QSOperator::Gt:
- return QV4::Runtime::greaterThan;
- case QSOperator::Lt:
- return QV4::Runtime::lessThan;
- case QSOperator::Ge:
- return QV4::Runtime::greaterEqual;
- case QSOperator::Le:
- return QV4::Runtime::lessEqual;
- case QSOperator::Equal:
- return QV4::Runtime::equal;
- case QSOperator::NotEqual:
- return QV4::Runtime::notEqual;
- case QSOperator::StrictEqual:
- return QV4::Runtime::strictEqual;
- case QSOperator::StrictNotEqual:
- return QV4::Runtime::strictNotEqual;
- case QSOperator::BitAnd:
- case QSOperator::BitOr:
- case QSOperator::BitXor:
- Q_UNREACHABLE();
- // fall through
- default:
- Q_ASSERT(!"Unknown AluOp");
- return QV4::Runtime::InvalidRuntimeMethod;
- }
-};
-
Codegen::Codegen(QV4::Compiler::JSUnitGenerator *jsUnitGenerator, bool strict)
: _module(0)
, _returnAddress(0)
@@ -931,6 +883,22 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
bytecodeGenerator->addInstruction(mul);
break;
}
+ case QSOperator::Div: {
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ Instruction::Div div;
+ div.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(div);
+ break;
+ }
+ case QSOperator::Mod: {
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ Instruction::Mod mod;
+ mod.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(mod);
+ break;
+ }
case QSOperator::BitAnd:
if (right.isConst()) {
int rightAsInt = Primitive::fromReturnedValue(right.constant).toInt32();
@@ -985,6 +953,19 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
bytecodeGenerator->addInstruction(bitXor);
}
break;
+ case QSOperator::URShift:
+ if (right.isConst()) {
+ left.loadInAccumulator();
+ Instruction::UShrConst ushr;
+ ushr.rhs = Primitive::fromReturnedValue(right.constant).toInt32() & 0x1f;
+ bytecodeGenerator->addInstruction(ushr);
+ } else {
+ right.loadInAccumulator();
+ Instruction::UShr ushr;
+ ushr.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(ushr);
+ }
+ break;
case QSOperator::RShift:
if (right.isConst()) {
left.loadInAccumulator();
@@ -1011,14 +992,16 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
bytecodeGenerator->addInstruction(shl);
}
break;
- case QSOperator::InstanceOf:
+ case QSOperator::InstanceOf: {
+ Instruction::CmpInstanceOf binop;
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ binop.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(binop);
+ break;
+ }
case QSOperator::In: {
- Instruction::BinopContext binop;
- if (oper == QSOperator::InstanceOf)
- binop.alu = QV4::Runtime::instanceof;
- else
- binop.alu = QV4::Runtime::in;
- Q_ASSERT(binop.alu != QV4::Runtime::InvalidRuntimeMethod);
+ Instruction::CmpIn binop;
left = left.storeOnStack();
right.loadInAccumulator();
binop.lhs = left.stackSlot();
@@ -1112,17 +1095,8 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
cmp.lhs = left.stackSlot();
bytecodeGenerator->addInstruction(cmp);
break;
- default: {
- auto binopFunc = aluOpFunction(oper);
- Q_ASSERT(binopFunc != QV4::Runtime::InvalidRuntimeMethod);
- left = left.storeOnStack();
- right.loadInAccumulator();
- Instruction::Binop binop;
- binop.alu = binopFunc;
- binop.lhs = left.stackSlot();
- bytecodeGenerator->addInstruction(binop);
- break;
- }
+ default:
+ Q_UNREACHABLE();
}
return Reference::fromAccumulator(this);
@@ -1244,7 +1218,8 @@ Codegen::Reference Codegen::jumpBinop(QSOperator::Op oper, Reference &left, Refe
addCJump();
break;
}
- default: Q_UNIMPLEMENTED(); Q_UNREACHABLE();
+ default:
+ Q_UNREACHABLE();
}
return Reference();
}
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 6e29c97927..ea19233a3d 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -530,10 +530,6 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_BEGIN_INSTR(Decrement)
MOTH_END_INSTR(PreDecrement)
- MOTH_BEGIN_INSTR(Binop)
- d << alu << ", " << dumpRegister(lhs, nFormals) << ", acc";
- MOTH_END_INSTR(Binop)
-
MOTH_BEGIN_INSTR(Add)
d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(Add)
@@ -550,6 +546,10 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(BitXor)
+ MOTH_BEGIN_INSTR(UShr)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(UShr)
+
MOTH_BEGIN_INSTR(Shr)
d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(Shr)
@@ -570,6 +570,10 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << "acc, " << rhs;
MOTH_END_INSTR(BitXor)
+ MOTH_BEGIN_INSTR(UShrConst)
+ d << "acc, " << rhs;
+ MOTH_END_INSTR(UShrConst)
+
MOTH_BEGIN_INSTR(ShrConst)
d << "acc, " << rhs;
MOTH_END_INSTR(ShrConst)
@@ -582,13 +586,25 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(Mul)
+ MOTH_BEGIN_INSTR(Div)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(Div)
+
+ MOTH_BEGIN_INSTR(Mod)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(Mod)
+
MOTH_BEGIN_INSTR(Sub)
d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(Sub)
- MOTH_BEGIN_INSTR(BinopContext)
- d << alu << " " << dumpRegister(lhs, nFormals) << ", acc";
- MOTH_END_INSTR(BinopContext)
+ MOTH_BEGIN_INSTR(CmpIn)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(CmpIn)
+
+ MOTH_BEGIN_INSTR(CmpInstanceOf)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(CmpInstanceOf)
MOTH_BEGIN_INSTR(Ret)
MOTH_END_INSTR(Ret)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 398970b60f..d81762f25b 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -154,6 +154,8 @@ QT_BEGIN_NAMESPACE
#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_CmpIn(op) INSTRUCTION(op, CmpIn, 1, lhs)
+#define INSTR_CmpInstanceOf(op) INSTRUCTION(op, CmpInstanceOf, 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)
@@ -162,23 +164,23 @@ QT_BEGIN_NAMESPACE
#define INSTR_UCompl(op) INSTRUCTION(op, UCompl, 0)
#define INSTR_Increment(op) INSTRUCTION(op, Increment, 0)
#define INSTR_Decrement(op) INSTRUCTION(op, Decrement, 0)
-// alu is QV4::Runtime::RuntimeMethods enum value
-#define INSTR_Binop(op) INSTRUCTION(op, Binop, 2, alu, lhs)
#define INSTR_Add(op) INSTRUCTION(op, Add, 1, lhs)
#define INSTR_BitAnd(op) INSTRUCTION(op, BitAnd, 1, lhs)
#define INSTR_BitOr(op) INSTRUCTION(op, BitOr, 1, lhs)
#define INSTR_BitXor(op) INSTRUCTION(op, BitXor, 1, lhs)
+#define INSTR_UShr(op) INSTRUCTION(op, UShr, 1, lhs)
#define INSTR_Shr(op) INSTRUCTION(op, Shr, 1, lhs)
#define INSTR_Shl(op) INSTRUCTION(op, Shl, 1, lhs)
#define INSTR_BitAndConst(op) INSTRUCTION(op, BitAndConst, 1, rhs)
#define INSTR_BitOrConst(op) INSTRUCTION(op, BitOrConst, 1, rhs)
#define INSTR_BitXorConst(op) INSTRUCTION(op, BitXorConst, 1, rhs)
+#define INSTR_UShrConst(op) INSTRUCTION(op, UShrConst, 1, rhs)
#define INSTR_ShrConst(op) INSTRUCTION(op, ShrConst, 1, rhs)
#define INSTR_ShlConst(op) INSTRUCTION(op, ShlConst, 1, rhs)
#define INSTR_Mul(op) INSTRUCTION(op, Mul, 1, lhs)
+#define INSTR_Div(op) INSTRUCTION(op, Div, 1, lhs)
+#define INSTR_Mod(op) INSTRUCTION(op, Mod, 1, lhs)
#define INSTR_Sub(op) INSTRUCTION(op, Sub, 1, lhs)
-// alu is offset inside the runtime methods
-#define INSTR_BinopContext(op) INSTRUCTION(op, BinopContext, 2, alu, lhs)
#define INSTR_LoadQmlContext(op) INSTRUCTION(op, LoadQmlContext, 1, result)
#define INSTR_LoadQmlImportedScripts(op) INSTRUCTION(op, LoadQmlImportedScripts, 1, result)
#define INSTR_LoadQmlSingleton(op) INSTRUCTION(op, LoadQmlSingleton, 1, name)
@@ -267,6 +269,8 @@ QT_BEGIN_NAMESPACE
F(CmpLe) \
F(CmpStrictEqual) \
F(CmpStrictNotEqual) \
+ F(CmpIn) \
+ F(CmpInstanceOf) \
F(JumpStrictEqualStackSlotInt) \
F(JumpStrictNotEqualStackSlotInt) \
F(UNot) \
@@ -275,21 +279,23 @@ QT_BEGIN_NAMESPACE
F(UCompl) \
F(Increment) \
F(Decrement) \
- F(Binop) \
F(Add) \
F(BitAnd) \
F(BitOr) \
F(BitXor) \
+ F(UShr) \
F(Shr) \
F(Shl) \
F(BitAndConst) \
F(BitOrConst) \
F(BitXorConst) \
+ F(UShrConst) \
F(ShrConst) \
F(ShlConst) \
F(Mul) \
+ F(Div) \
+ F(Mod) \
F(Sub) \
- F(BinopContext) \
F(LoadQmlContext) \
F(LoadQmlImportedScripts) \
F(LoadQmlSingleton)
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 63433b7955..8497d47800 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -788,12 +788,13 @@ ReturnedValue value_convert(ExecutionEngine *e, const Value &v);
inline int Value::toInt32() const
{
- if (integerCompatible())
+ if (Q_LIKELY(integerCompatible()))
return int_32();
- double d = isDouble() ? doubleValue() : toNumberImpl();
+ if (Q_LIKELY(isDouble()))
+ return Double::toInt32(doubleValue());
- return Double::toInt32(d);
+ return Double::toInt32(toNumberImpl());
}
inline unsigned int Value::toUInt32() const
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 4abd3582dd..6823cf0000 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -496,7 +496,6 @@ static bool compareEqualInt(Value &accumulator, Value lhs, int rhs)
} \
} while (false)
-
QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
{
qt_v4ResolvePendingBreakpointsHook();
@@ -1091,6 +1090,18 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
}
MOTH_END_INSTR(CmpStrictNotEqual)
+ MOTH_BEGIN_INSTR(CmpIn)
+ STORE_ACC();
+ acc = Runtime::method_in(engine, STACK_VALUE(lhs), accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(CmpIn)
+
+ MOTH_BEGIN_INSTR(CmpInstanceOf)
+ STORE_ACC();
+ acc = Runtime::method_instanceof(engine, STACK_VALUE(lhs), accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(CmpInstanceOf)
+
MOTH_BEGIN_INSTR(JumpStrictNotEqualStackSlotInt)
if (STACK_VALUE(lhs).int_32() != rhs || STACK_VALUE(lhs).isUndefined())
code += offset;
@@ -1159,13 +1170,6 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
}
MOTH_END_INSTR(Decrement)
- MOTH_BEGIN_INSTR(Binop)
- QV4::Runtime::BinaryOperation op = *reinterpret_cast<QV4::Runtime::BinaryOperation *>(reinterpret_cast<char *>(&engine->runtime.runtimeMethods[alu]));
- STORE_ACC();
- acc = op(STACK_VALUE(lhs), accumulator);
- CHECK_EXCEPTION;
- MOTH_END_INSTR(Binop)
-
MOTH_BEGIN_INSTR(Add)
const Value left = STACK_VALUE(lhs);
if (Q_LIKELY(Value::integerCompatible(left, ACC))) {
@@ -1205,6 +1209,18 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
}
MOTH_END_INSTR(Mul)
+ MOTH_BEGIN_INSTR(Div)
+ STORE_ACC();
+ acc = Runtime::method_div(STACK_VALUE(lhs), accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(Div)
+
+ MOTH_BEGIN_INSTR(Mod)
+ STORE_ACC();
+ acc = Runtime::method_mod(STACK_VALUE(lhs), accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(Mod)
+
MOTH_BEGIN_INSTR(BitAnd)
VALUE_TO_INT(l, STACK_VALUE(lhs));
VALUE_TO_INT(a, ACC);
@@ -1223,6 +1239,12 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
acc = Encode(l ^ a);
MOTH_END_INSTR(BitXor)
+ MOTH_BEGIN_INSTR(UShr)
+ uint l = STACK_VALUE(lhs).toUInt32();
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(l >> uint(a & 0x1f));
+ MOTH_END_INSTR(UShr)
+
MOTH_BEGIN_INSTR(Shr)
VALUE_TO_INT(l, STACK_VALUE(lhs));
VALUE_TO_INT(a, ACC);
@@ -1251,6 +1273,10 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
acc = Encode(a ^ rhs);
MOTH_END_INSTR(BitXorConst)
+ MOTH_BEGIN_INSTR(UShrConst)
+ acc = Encode(ACC.toUInt32() >> uint(rhs));
+ MOTH_END_INSTR(UShrConst)
+
MOTH_BEGIN_INSTR(ShrConst)
VALUE_TO_INT(a, ACC);
acc = Encode(a >> rhs);
@@ -1261,13 +1287,6 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
acc = Encode(a << rhs);
MOTH_END_INSTR(ShlConst)
- MOTH_BEGIN_INSTR(BinopContext)
- STORE_ACC();
- QV4::Runtime::BinaryOperationContext op = *reinterpret_cast<QV4::Runtime::BinaryOperationContext *>(reinterpret_cast<char *>(&engine->runtime.runtimeMethods[alu]));
- acc = op(engine, STACK_VALUE(lhs), accumulator);
- CHECK_EXCEPTION;
- MOTH_END_INSTR(BinopContext)
-
MOTH_BEGIN_INSTR(Ret)
goto functionExit;
MOTH_END_INSTR(Ret)