aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qv4codegen.cpp22
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp9
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h14
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp51
4 files changed, 91 insertions, 5 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 379db2cd9c..5a7c12d0a2 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1064,19 +1064,33 @@ Codegen::Reference Codegen::jumpBinop(QSOperator::Op oper, Reference &left, Refe
jumpTarget = _expr.iffalse();
}
- if (right.isConst()) {
- if (right.constant == Encode::null() || right.constant == Encode::undefined()) {
+ 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) {
- left.loadInAccumulator();
Instruction::CmpJmpEqNull cjump;
bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
return Reference();
} else if (oper == QSOperator::NotEqual) {
- left.loadInAccumulator();
Instruction::CmpJmpNeNull cjump;
bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
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);
+ return Reference();
+ } else if (oper == QSOperator::NotEqual) {
+ Instruction::CmpJmpNeInt cjump;
+ cjump.lhs = c.int_32();
+ bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ return Reference();
+ }
+
}
}
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index c1d99162f5..f3da508266 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -398,6 +398,15 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals)
d << absoluteInstructionOffset(start, instr);
MOTH_END_INSTR(CmpJmpNeNull)
+ MOTH_BEGIN_INSTR(CmpJmpEqInt)
+ d << instr.lhs << ", " << absoluteInstructionOffset(start, instr);
+ MOTH_END_INSTR(CmpJmpEq)
+
+ MOTH_BEGIN_INSTR(CmpJmpNeInt)
+ d << instr.lhs << ", " << absoluteInstructionOffset(start, instr);
+ MOTH_END_INSTR(CmpJmpNe)
+
+
MOTH_BEGIN_INSTR(CmpJmpEq)
d << instr.lhs.dump(nFormals) << ", " << absoluteInstructionOffset(start, instr);
MOTH_END_INSTR(CmpJmpEq)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index cb55e84442..c7e999e2e1 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -142,6 +142,8 @@ QT_BEGIN_NAMESPACE
F(JumpNe, jumpNe) \
F(CmpJmpEqNull, cmpJmpEqNull) \
F(CmpJmpNeNull, cmpJmpNeNull) \
+ F(CmpJmpEqInt, cmpJmpEqInt) \
+ F(CmpJmpNeInt, cmpJmpNeInt) \
F(CmpJmpEq, cmpJmpEq) \
F(CmpJmpNe, cmpJmpNe) \
F(CmpJmpGt, cmpJmpGt) \
@@ -580,6 +582,16 @@ union Instr
MOTH_INSTR_HEADER
ptrdiff_t offset;
};
+ struct instr_cmpJmpEqInt {
+ MOTH_INSTR_HEADER
+ int lhs;
+ ptrdiff_t offset;
+ };
+ struct instr_cmpJmpNeInt {
+ MOTH_INSTR_HEADER
+ int lhs;
+ ptrdiff_t offset;
+ };
struct instr_cmpJmpEq {
MOTH_INSTR_HEADER
StackSlot lhs;
@@ -800,6 +812,8 @@ union Instr
instr_jumpNe jumpNe;
instr_cmpJmpEqNull cmpJmpEqNull;
instr_cmpJmpNeNull cmpJmpNeNull;
+ instr_cmpJmpEqInt cmpJmpEqInt;
+ instr_cmpJmpNeInt cmpJmpNeInt;
instr_cmpJmpEq cmpJmpEq;
instr_cmpJmpNe cmpJmpNe;
instr_cmpJmpGt cmpJmpGt;
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 69c53aa8b6..d8d900f2bd 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -400,6 +400,7 @@ static inline const QV4::Value &constant(Function *function, int index)
static bool compareEqual(Value lhs, Value rhs)
{
+ redo:
if (lhs.asReturnedValue() == rhs.asReturnedValue())
return !lhs.isNaN();
@@ -458,7 +459,7 @@ static bool compareEqual(Value lhs, Value rhs)
else
lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(lhs), PREFERREDTYPE_HINT));
}
- return compareEqual(lhs, rhs);
+ goto redo;
case Value::QT_Empty:
Q_UNREACHABLE();
case Value::QT_Null:
@@ -485,6 +486,36 @@ static bool compareEqual(Value lhs, Value rhs)
}
}
+static bool compareEqualInt(Value lhs, int rhs)
+{
+ redo:
+ switch (lhs.quickType()) {
+ case Value::QT_ManagedOrUndefined:
+ if (lhs.isUndefined())
+ return false;
+ Q_FALLTHROUGH();
+ case Value::QT_ManagedOrUndefined1:
+ case Value::QT_ManagedOrUndefined2:
+ case Value::QT_ManagedOrUndefined3:
+ // LHS: Managed
+ if (lhs.m()->vtable()->isString)
+ return RuntimeHelpers::toNumber(lhs) == rhs;
+ else
+ lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(lhs), PREFERREDTYPE_HINT));
+ goto redo;
+ case Value::QT_Empty:
+ Q_UNREACHABLE();
+ case Value::QT_Null:
+ return false;
+ case Value::QT_Bool:
+ case Value::QT_Int:
+ return lhs.int_32() == rhs;
+ default: // double
+ return lhs.doubleValue() == rhs;
+ }
+}
+
+
QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callData, Heap::ExecutionContext *context, QV4::Function *function)
{
qt_v4ResolvePendingBreakpointsHook();
@@ -906,6 +937,24 @@ QV4::ReturnedValue VME::exec(const FunctionObject *jsFunction, CallData *callDat
code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
MOTH_END_INSTR(CmpJmpNeNull)
+ MOTH_BEGIN_INSTR(CmpJmpEqInt)
+ if (accumulator.isIntOrBool()) {
+ if (accumulator.int_32() == instr.lhs)
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ } else if (compareEqualInt(accumulator, instr.lhs)) {
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ }
+ MOTH_END_INSTR(CmpJmpEqInt)
+
+ MOTH_BEGIN_INSTR(CmpJmpNeInt)
+ if (accumulator.isIntOrBool()) {
+ if (accumulator.int_32() != instr.lhs)
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ } else if (!compareEqualInt(accumulator, instr.lhs)) {
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ }
+ MOTH_END_INSTR(CmpJmpNeInt)
+
MOTH_BEGIN_INSTR(CmpJmpEq)
const Value lhs = STACK_VALUE(instr.lhs);
if (Q_LIKELY(lhs.asReturnedValue() == accumulator.asReturnedValue())) {