aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4vme_moth.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4vme_moth.cpp')
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp133
1 files changed, 75 insertions, 58 deletions
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 9d6540ebe9..df8e3632fb 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -41,7 +41,7 @@
#include "qv4vme_moth_p.h"
#include "qv4instr_moth_p.h"
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4debugging_p.h>
#include <private/qv4math_p.h>
#include <private/qv4scopedvalue_p.h>
@@ -64,8 +64,6 @@ using namespace QQmlJS::Moth;
#define MOTH_BEGIN_INSTR_COMMON(I) { \
const InstrMeta<(int)Instr::I>::DataType &instr = InstrMeta<(int)Instr::I>::data(*genericInstr); \
code += InstrMeta<(int)Instr::I>::Size; \
- if (debugger && (instr.breakPoint || debugger->pauseAtNextOpportunity())) \
- debugger->maybeBreakAtInstruction(code, instr.breakPoint); \
Q_UNUSED(instr); \
TRACE_INSTR(I)
@@ -74,11 +72,6 @@ using namespace QQmlJS::Moth;
# define MOTH_BEGIN_INSTR(I) op_##I: \
MOTH_BEGIN_INSTR_COMMON(I)
-# define MOTH_NEXT_INSTR(I) { \
- genericInstr = reinterpret_cast<const Instr *>(code); \
- goto *genericInstr->common.code; \
- }
-
# define MOTH_END_INSTR(I) } \
genericInstr = reinterpret_cast<const Instr *>(code); \
goto *genericInstr->common.code; \
@@ -89,10 +82,6 @@ using namespace QQmlJS::Moth;
case Instr::I: \
MOTH_BEGIN_INSTR_COMMON(I)
-# define MOTH_NEXT_INSTR(I) { \
- continue; \
- }
-
# define MOTH_END_INSTR(I) } \
continue;
@@ -161,16 +150,15 @@ Param traceParam(const Param &param)
#define STOREVALUE(param, value) { \
QV4::ReturnedValue tmp = (value); \
- if (context->engine->hasException) \
+ if (engine->hasException) \
goto catchException; \
VALUE(param) = tmp; \
}
#define CHECK_EXCEPTION \
- if (context->engine->hasException) \
+ if (engine->hasException) \
goto catchException
-QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
- QV4::SafeValue *stack, unsigned stackSize
+QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
#ifdef MOTH_THREADED_INTERPRETER
, void ***storeJumpTable
#endif
@@ -192,15 +180,18 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
}
#endif
+ QV4::Value *stack = 0;
+ unsigned stackSize = 0;
+
const uchar *exceptionHandler = 0;
- QV4::Debugging::Debugger *debugger = context->engine->debugger;
+ QV4::ExecutionEngine *engine = context->engine;
#ifdef DO_TRACE_INSTR
qDebug("Starting VME with context=%p and code=%p", context, code);
#endif // DO_TRACE_INSTR
- QV4::SafeString * const runtimeStrings = context->compilationUnit->runtimeStrings;
+ QV4::StringValue * const runtimeStrings = context->compilationUnit->runtimeStrings;
context->interpreterInstructionPointer = &code;
// setup lookup scopes
@@ -213,9 +204,9 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
}
}
- QV4::SafeValue **scopes = static_cast<QV4::SafeValue **>(alloca(sizeof(QV4::SafeValue *)*(2 + 2*scopeDepth)));
+ QV4::Value **scopes = static_cast<QV4::Value **>(alloca(sizeof(QV4::Value *)*(2 + 2*scopeDepth)));
{
- scopes[0] = const_cast<QV4::SafeValue *>(context->compilationUnit->data->constants());
+ scopes[0] = const_cast<QV4::Value *>(context->compilationUnit->data->constants());
// stack gets setup in push instruction
scopes[1] = 0;
QV4::ExecutionContext *scope = context;
@@ -247,6 +238,10 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
VALUE(instr.result) = VALUE(instr.source);
MOTH_END_INSTR(Move)
+ MOTH_BEGIN_INSTR(MoveConst)
+ VALUE(instr.result) = instr.source;
+ MOTH_END_INSTR(MoveConst)
+
MOTH_BEGIN_INSTR(SwapTemps)
qSwap(VALUE(instr.left), VALUE(instr.right));
MOTH_END_INSTR(MoveTemp)
@@ -286,11 +281,22 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
STOREVALUE(instr.result, __qmljs_get_element(context, VALUEPTR(instr.base), VALUEPTR(instr.index)));
MOTH_END_INSTR(LoadElement)
+ MOTH_BEGIN_INSTR(LoadElementLookup)
+ QV4::Lookup *l = context->lookups + instr.lookup;
+ STOREVALUE(instr.result, l->indexedGetter(l, VALUEPTR(instr.base), VALUEPTR(instr.index)));
+ MOTH_END_INSTR(LoadElementLookup)
+
MOTH_BEGIN_INSTR(StoreElement)
__qmljs_set_element(context, VALUEPTR(instr.base), VALUEPTR(instr.index), VALUEPTR(instr.source));
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreElement)
+ MOTH_BEGIN_INSTR(StoreElementLookup)
+ QV4::Lookup *l = context->lookups + instr.lookup;
+ l->indexedSetter(l, VALUEPTR(instr.base), VALUEPTR(instr.index), VALUEPTR(instr.source));
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(StoreElementLookup)
+
MOTH_BEGIN_INSTR(LoadProperty)
STOREVALUE(instr.result, __qmljs_get_property(context, VALUEPTR(instr.base), runtimeStrings[instr.name]));
MOTH_END_INSTR(LoadProperty)
@@ -328,7 +334,9 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
TRACE(inline, "stack size: %u", instr.value);
stackSize = instr.value;
stack = context->engine->stackPush(stackSize);
- memset(stack, 0, stackSize * sizeof(QV4::SafeValue));
+#ifndef QT_NO_DEBUG
+ memset(stack, 0, stackSize * sizeof(QV4::Value));
+#endif
scopes[1] = stack;
MOTH_END_INSTR(Push)
@@ -343,7 +351,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
}
}
#endif // DO_TRACE_INSTR
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -353,7 +361,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CallProperty)
TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -363,7 +371,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CallPropertyLookup)
TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -372,7 +380,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_END_INSTR(CallPropertyLookup)
MOTH_BEGIN_INSTR(CallElement)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -382,7 +390,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CallActivationProperty)
TRACE(args, "starting at %d, length %d", instr.args, instr.argc);
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -392,7 +400,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CallGlobalLookup)
TRACE(args, "starting at %d, length %d", instr.args, instr.argc);
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -475,12 +483,12 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CallBuiltinDefineArray)
Q_ASSERT(instr.args + instr.argc <= stackSize);
- QV4::SafeValue *args = stack + instr.args;
+ QV4::Value *args = stack + instr.args;
STOREVALUE(instr.result, __qmljs_builtin_define_array(context, args, instr.argc));
MOTH_END_INSTR(CallBuiltinDefineArray)
MOTH_BEGIN_INSTR(CallBuiltinDefineObjectLiteral)
- QV4::SafeValue *args = stack + instr.args;
+ QV4::Value *args = stack + instr.args;
STOREVALUE(instr.result, __qmljs_builtin_define_object_literal(context, args, instr.internalClassId));
MOTH_END_INSTR(CallBuiltinDefineObjectLiteral)
@@ -494,7 +502,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_END_INSTR(CallBuiltinConvertThisToObject)
MOTH_BEGIN_INSTR(CreateValue)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -503,7 +511,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_END_INSTR(CreateValue)
MOTH_BEGIN_INSTR(CreateProperty)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -512,7 +520,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_END_INSTR(CreateProperty)
MOTH_BEGIN_INSTR(ConstructPropertyLookup)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -522,7 +530,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CreateActivationProperty)
TRACE(inline, "property name = %s, args = %d, argc = %d", runtimeStrings[instr.name]->toQString().toUtf8().constData(), instr.args, instr.argc);
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -532,7 +540,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(ConstructGlobalLookup)
TRACE(inline, "property name = %s, args = %d, argc = %d", runtimeStrings[instr.name]->toQString().toUtf8().constData(), instr.args, instr.argc);
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -544,14 +552,19 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
code = ((uchar *)&instr.offset) + instr.offset;
MOTH_END_INSTR(Jump)
- MOTH_BEGIN_INSTR(CJump)
- uint cond = __qmljs_to_boolean(VALUEPTR(instr.condition));
+ MOTH_BEGIN_INSTR(JumpEq)
+ bool cond = VALUEPTR(instr.condition)->toBoolean();
TRACE(condition, "%s", cond ? "TRUE" : "FALSE");
- if (instr.invert)
- cond = !cond;
if (cond)
code = ((uchar *)&instr.offset) + instr.offset;
- MOTH_END_INSTR(CJump)
+ MOTH_END_INSTR(JumpEq)
+
+ MOTH_BEGIN_INSTR(JumpNe)
+ bool cond = VALUEPTR(instr.condition)->toBoolean();
+ TRACE(condition, "%s", cond ? "TRUE" : "FALSE");
+ if (!cond)
+ code = ((uchar *)&instr.offset) + instr.offset;
+ MOTH_END_INSTR(JumpNe)
MOTH_BEGIN_INSTR(UNot)
STOREVALUE(instr.result, __qmljs_not(VALUEPTR(instr.source)));
@@ -606,6 +619,14 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
STOREVALUE(instr.result, __qmljs_bit_xor(VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)));
MOTH_END_INSTR(BitXor)
+ MOTH_BEGIN_INSTR(Shr)
+ STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() >> (VALUEPTR(instr.rhs)->toInt32() & 0x1f))));
+ MOTH_END_INSTR(Shr)
+
+ MOTH_BEGIN_INSTR(Shl)
+ STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() << (VALUEPTR(instr.rhs)->toInt32() & 0x1f))));
+ MOTH_END_INSTR(Shl)
+
MOTH_BEGIN_INSTR(BitAndConst)
int lhs = VALUEPTR(instr.lhs)->toInt32();
STOREVALUE(instr.result, QV4::Encode((int)(lhs & instr.rhs)));
@@ -621,6 +642,14 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
STOREVALUE(instr.result, QV4::Encode((int)(lhs ^ instr.rhs)));
MOTH_END_INSTR(BitXor)
+ MOTH_BEGIN_INSTR(ShrConst)
+ STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() >> instr.rhs)));
+ MOTH_END_INSTR(ShrConst)
+
+ MOTH_BEGIN_INSTR(ShlConst)
+ STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() << instr.rhs)));
+ MOTH_END_INSTR(ShlConst)
+
MOTH_BEGIN_INSTR(Mul)
STOREVALUE(instr.result, __qmljs_mul(VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)));
MOTH_END_INSTR(Mul)
@@ -633,30 +662,18 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
STOREVALUE(instr.result, instr.alu(context, VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)));
MOTH_END_INSTR(BinopContext)
- MOTH_BEGIN_INSTR(AddNumberParams)
- double lhs = VALUE(instr.lhs).asDouble();
- double rhs = VALUE(instr.rhs).asDouble();
- VALUEPTR(instr.result)->setDouble(lhs + rhs);
- MOTH_END_INSTR(AddNumberParams)
-
- MOTH_BEGIN_INSTR(MulNumberParams)
- double lhs = VALUE(instr.lhs).asDouble();
- double rhs = VALUE(instr.rhs).asDouble();
- VALUEPTR(instr.result)->setDouble(lhs * rhs);
- MOTH_END_INSTR(MulNumberParams)
-
- MOTH_BEGIN_INSTR(SubNumberParams)
- double lhs = VALUE(instr.lhs).asDouble();
- double rhs = VALUE(instr.rhs).asDouble();
- VALUEPTR(instr.result)->setDouble(lhs - rhs);
- MOTH_END_INSTR(SubNumberParams)
-
MOTH_BEGIN_INSTR(Ret)
context->engine->stackPop(stackSize);
// TRACE(Ret, "returning value %s", result.toString(context)->toQString().toUtf8().constData());
return VALUE(instr.result).asReturnedValue();
MOTH_END_INSTR(Ret)
+ MOTH_BEGIN_INSTR(Debug)
+ QV4::Debugging::Debugger *debugger = context->engine->debugger;
+ if (debugger && (instr.breakPoint || debugger->pauseAtNextOpportunity()))
+ debugger->maybeBreakAtInstruction(code, instr.breakPoint);
+ MOTH_END_INSTR(Debug)
+
MOTH_BEGIN_INSTR(LoadThis)
VALUE(instr.result) = context->callData->thisObject;
MOTH_END_INSTR(LoadThis)
@@ -709,7 +726,7 @@ void **VME::instructionJumpTable()
static void **jumpTable = 0;
if (!jumpTable) {
const uchar *code = 0;
- VME().run(0, code, 0, 0, &jumpTable);
+ VME().run(0, code, &jumpTable);
}
return jumpTable;
}