aboutsummaryrefslogtreecommitdiffstats
path: root/moth
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2012-11-13 12:25:23 +0100
committerErik Verbruggen <erik.verbruggen@digia.com>2012-11-14 11:44:32 +0100
commit2049a3e9740970f3c2a5633fb9211f5d5865831f (patch)
tree849c79e38e328f8c3efdcc1cdefb5d99943757bd /moth
parent72c07ef0469838f5776824065faf9efda0261f9e (diff)
Remove the tempRegister from moth by loading/storing values directly.
Change-Id: I51982d5852db2e10234620d63c235484c5b8a573 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'moth')
-rw-r--r--moth/qv4instr_moth_p.h64
-rw-r--r--moth/qv4isel_moth.cpp140
-rw-r--r--moth/qv4isel_moth_p.h9
-rw-r--r--moth/qv4vme_moth.cpp94
4 files changed, 189 insertions, 118 deletions
diff --git a/moth/qv4instr_moth_p.h b/moth/qv4instr_moth_p.h
index 6fad95e083..e37f302f4c 100644
--- a/moth/qv4instr_moth_p.h
+++ b/moth/qv4instr_moth_p.h
@@ -6,15 +6,13 @@
#define FOR_EACH_MOTH_INSTR(F) \
F(Ret, ret) \
- F(LoadUndefined, common) \
- F(LoadNull, common) \
- F(LoadFalse, common) \
- F(LoadTrue, common) \
+ F(LoadUndefined, loadUndefined) \
+ F(LoadNull, loadNull) \
+ F(LoadFalse, loadFalse) \
+ F(LoadTrue, loadTrue) \
F(LoadNumber, loadNumber) \
F(LoadString, loadString) \
F(LoadClosure, loadClosure) \
- F(StoreTemp, storeTemp) \
- F(LoadTemp, loadTemp) \
F(MoveTemp, moveTemp) \
F(LoadName, loadName) \
F(StoreName, storeName) \
@@ -74,18 +72,27 @@ union Instr
struct instr_common {
MOTH_INSTR_HEADER
+ int tempIndex;
};
struct instr_ret {
MOTH_INSTR_HEADER
int tempIndex;
};
- struct instr_storeTemp {
+ struct instr_loadUndefined {
MOTH_INSTR_HEADER
- int tempIndex;
+ int targetTempIndex;
};
- struct instr_loadTemp {
+ struct instr_loadNull {
MOTH_INSTR_HEADER
- int tempIndex;
+ int targetTempIndex;
+ };
+ struct instr_loadFalse {
+ MOTH_INSTR_HEADER
+ int targetTempIndex;
+ };
+ struct instr_loadTrue {
+ MOTH_INSTR_HEADER
+ int targetTempIndex;
};
struct instr_moveTemp {
MOTH_INSTR_HEADER
@@ -95,30 +102,37 @@ union Instr
struct instr_loadNumber {
MOTH_INSTR_HEADER
double value;
+ int targetTempIndex;
};
struct instr_loadString {
MOTH_INSTR_HEADER
VM::String *value;
- };
+ int targetTempIndex;
+ };
struct instr_loadClosure {
MOTH_INSTR_HEADER
IR::Function *value;
+ int targetTempIndex;
};
struct instr_loadName {
MOTH_INSTR_HEADER
VM::String *name;
+ int targetTempIndex;
};
struct instr_storeName {
MOTH_INSTR_HEADER
VM::String *name;
+ int sourceTemp;
};
struct instr_loadProperty {
MOTH_INSTR_HEADER
int baseTemp;
+ int targetTempIndex;
VM::String *name;
};
struct instr_storeProperty {
MOTH_INSTR_HEADER
+ int sourceTemp;
int baseTemp;
VM::String *name;
};
@@ -126,9 +140,11 @@ union Instr
MOTH_INSTR_HEADER
int base;
int index;
+ int targetTempIndex;
};
struct instr_storeElement {
MOTH_INSTR_HEADER
+ int sourceTemp;
int base;
int index;
};
@@ -140,12 +156,16 @@ union Instr
MOTH_INSTR_HEADER
quint32 argc;
quint32 args;
+ int destIndex;
+ int targetTempIndex;
};
struct instr_callProperty {
MOTH_INSTR_HEADER
VM::String *name;
+ int baseTemp;
quint32 argc;
quint32 args;
+ int targetTempIndex;
};
struct instr_callBuiltin {
MOTH_INSTR_HEADER
@@ -160,30 +180,36 @@ union Instr
} builtin;
quint32 argc;
quint32 args;
+ int targetTempIndex;
};
struct instr_callBuiltinDeleteMember {
MOTH_INSTR_HEADER
int base;
VM::String *member;
+ int targetTempIndex;
};
struct instr_callBuiltinDeleteSubscript {
MOTH_INSTR_HEADER
int base;
int index;
+ int targetTempIndex;
};
struct instr_callBuiltinDeleteName {
MOTH_INSTR_HEADER
VM::String *name;
+ int targetTempIndex;
};
struct instr_callBuiltinDeleteValue {
MOTH_INSTR_HEADER
int tempIndex;
+ int targetTempIndex;
};
struct instr_createValue {
MOTH_INSTR_HEADER
int func;
quint32 argc;
quint32 args;
+ int targetTempIndex;
};
struct instr_createProperty {
MOTH_INSTR_HEADER
@@ -191,32 +217,38 @@ union Instr
VM::String *name;
quint32 argc;
quint32 args;
+ int targetTempIndex;
};
struct instr_createActivationProperty {
MOTH_INSTR_HEADER
VM::String *name;
quint32 argc;
quint32 args;
+ int targetTempIndex;
};
struct instr_jump {
MOTH_INSTR_HEADER
ptrdiff_t offset;
+ int tempIndex;
};
struct instr_unop {
MOTH_INSTR_HEADER
- int e;
VM::Value (*alu)(const VM::Value value, VM::Context *ctx);
+ int e;
+ int targetTempIndex;
};
struct instr_binop {
MOTH_INSTR_HEADER
+ VM::Value (*alu)(const VM::Value , const VM::Value, VM::Context *);
+ int targetTempIndex;
ValueOrTemp lhs;
ValueOrTemp rhs;
unsigned lhsIsTemp:1;
unsigned rhsIsTemp:1;
- VM::Value (*alu)(const VM::Value , const VM::Value, VM::Context *);
};
struct instr_loadThis {
MOTH_INSTR_HEADER
+ int targetTempIndex;
};
struct instr_inplaceElementOp {
MOTH_INSTR_HEADER
@@ -241,8 +273,10 @@ union Instr
instr_common common;
instr_ret ret;
- instr_storeTemp storeTemp;
- instr_loadTemp loadTemp;
+ instr_loadUndefined loadUndefined;
+ instr_loadNull loadNull;
+ instr_loadFalse loadFalse;
+ instr_loadTrue loadTrue;
instr_moveTemp moveTemp;
instr_loadNumber loadNumber;
instr_loadString loadString;
diff --git a/moth/qv4isel_moth.cpp b/moth/qv4isel_moth.cpp
index 94116580b0..9550bb6f8e 100644
--- a/moth/qv4isel_moth.cpp
+++ b/moth/qv4isel_moth.cpp
@@ -41,7 +41,7 @@ void InstructionSelection::operator()(IR::Function *function)
_function->code = VME::exec;
_function->codeData = _ccode;
- int locals = _function->tempCount - _function->locals.size() + _function->maxNumberOfArguments;
+ int locals = _function->tempCount - _function->locals.size() + _function->maxNumberOfArguments + 1;
assert(locals >= 0);
Instruction::Push push;
@@ -72,19 +72,24 @@ void InstructionSelection::operator()(IR::Function *function)
qSwap(_function, function);
}
-void InstructionSelection::callActivationProperty(IR::Call *c)
+void InstructionSelection::callActivationProperty(IR::Call *c, int targetTempIndex)
{
IR::Name *baseName = c->base->asName();
Q_ASSERT(baseName);
switch (baseName->builtin) {
case IR::Name::builtin_invalid: {
+ const int scratchIndex = scratchTempIndex();
+
Instruction::LoadName load;
load.name = _engine->newString(*baseName->id);
+ load.targetTempIndex = scratchIndex;
addInstruction(load);
Instruction::CallValue call;
prepareCallArgs(c->args, call.argc, call.args);
+ call.destIndex = scratchIndex;
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
} break;
@@ -95,6 +100,7 @@ void InstructionSelection::callActivationProperty(IR::Call *c)
Instruction::CallBuiltin call;
call.builtin = Instruction::CallBuiltin::builtin_typeof;
prepareCallArgs(c->args, call.argc, call.args);
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
} break;
@@ -105,24 +111,28 @@ void InstructionSelection::callActivationProperty(IR::Call *c)
Instruction::CallBuiltin call;
call.builtin = Instruction::CallBuiltin::builtin_throw;
prepareCallArgs(c->args, call.argc, call.args);
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
} break;
case IR::Name::builtin_create_exception_handler: {
Instruction::CallBuiltin call;
call.builtin = Instruction::CallBuiltin::builtin_create_exception_handler;
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
} break;
case IR::Name::builtin_delete_exception_handler: {
Instruction::CallBuiltin call;
call.builtin = Instruction::CallBuiltin::builtin_delete_exception_handler;
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
} break;
case IR::Name::builtin_get_exception: {
Instruction::CallBuiltin call;
call.builtin = Instruction::CallBuiltin::builtin_get_exception;
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
} break;
@@ -130,6 +140,7 @@ void InstructionSelection::callActivationProperty(IR::Call *c)
Instruction::CallBuiltin call;
call.builtin = Instruction::CallBuiltin::builtin_foreach_iterator_object;
prepareCallArgs(c->args, call.argc, call.args);
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
} break;
@@ -137,6 +148,7 @@ void InstructionSelection::callActivationProperty(IR::Call *c)
Instruction::CallBuiltin call;
call.builtin = Instruction::CallBuiltin::builtin_foreach_next_property_name;
prepareCallArgs(c->args, call.argc, call.args);
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
} break;
@@ -145,19 +157,23 @@ void InstructionSelection::callActivationProperty(IR::Call *c)
Instruction::CallBuiltinDeleteMember call;
call.base = m->base->asTemp()->index;
call.member = _engine->newString(*m->name);
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
} else if (IR::Subscript *ss = c->args->expr->asSubscript()) {
Instruction::CallBuiltinDeleteSubscript call;
call.base = m->base->asTemp()->index;
call.index = ss->index->asTemp()->index;
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
} else if (IR::Name *n = c->args->expr->asName()) {
Instruction::CallBuiltinDeleteName call;
call.name = _engine->newString(*n->id);
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
} else {
Instruction::CallBuiltinDeleteValue call;
call.tempIndex = c->args->expr->asTemp()->index;
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
}
} break;
@@ -168,43 +184,39 @@ void InstructionSelection::callActivationProperty(IR::Call *c)
}
}
-void InstructionSelection::callValue(IR::Call *c)
+void InstructionSelection::callValue(IR::Call *c, int targetTempIndex)
{
IR::Temp *t = c->base->asTemp();
Q_ASSERT(t);
- Instruction::LoadTemp load;
- load.tempIndex = t->index;
- addInstruction(load);
-
Instruction::CallValue call;
prepareCallArgs(c->args, call.argc, call.args);
+ call.destIndex = t->index;
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
}
-void InstructionSelection::callProperty(IR::Call *c)
+void InstructionSelection::callProperty(IR::Call *c, int targetTempIndex)
{
IR::Member *m = c->base->asMember();
Q_ASSERT(m);
- // load the base
- Instruction::LoadTemp load;
- load.tempIndex = m->base->asTemp()->index;
- addInstruction(load);
-
// call the property on the loaded base
Instruction::CallProperty call;
+ call.baseTemp = m->base->asTemp()->index;
call.name = _engine->newString(*m->name);
prepareCallArgs(c->args, call.argc, call.args);
+ call.targetTempIndex = targetTempIndex;
addInstruction(call);
}
-void InstructionSelection::construct(IR::New *ctor)
+void InstructionSelection::construct(IR::New *ctor, int targetTempIndex)
{
if (IR::Name *baseName = ctor->base->asName()) {
Instruction::CreateActivationProperty create;
create.name = _engine->newString(*baseName->id);
prepareCallArgs(ctor->args, create.argc, create.args);
+ create.targetTempIndex = targetTempIndex;
addInstruction(create);
} else if (IR::Member *member = ctor->base->asMember()) {
IR::Temp *base = member->base->asTemp();
@@ -214,11 +226,13 @@ void InstructionSelection::construct(IR::New *ctor)
create.base = base->index;
create.name = _engine->newString(*member->name);
prepareCallArgs(ctor->args, create.argc, create.args);
+ create.targetTempIndex = targetTempIndex;
addInstruction(create);
} else if (IR::Temp *baseTemp = ctor->base->asTemp()) {
Instruction::CreateValue create;
create.func = baseTemp->index;
prepareCallArgs(ctor->args, create.argc, create.args);
+ create.targetTempIndex = targetTempIndex;
addInstruction(create);
} else {
qWarning(" NEW");
@@ -230,13 +244,15 @@ void InstructionSelection::prepareCallArgs(IR::ExprList *e, quint32 &argc, quint
argc = 0;
args = 0;
+ /*
int locals = _function->tempCount - _function->locals.size() + _function->maxNumberOfArguments;
+ The condition for this case is wrong: the locals check is incorrect:
if (e && e->next == 0 && e->expr->asTemp()->index >= 0 && e->expr->asTemp()->index < locals) {
// We pass single arguments as references to the stack
argc = 1;
args = e->expr->asTemp()->index;
- } else if (e) {
+ } else */if (e) {
// We need to move all the temps into the function arg array
int argLocation = _function->tempCount - _function->locals.size();
assert(argLocation >= 0);
@@ -256,17 +272,17 @@ void InstructionSelection::prepareCallArgs(IR::ExprList *e, quint32 &argc, quint
void InstructionSelection::visitExp(IR::Exp *s)
{
if (IR::Call *c = s->expr->asCall()) {
+ // These are calls where the result is ignored.
+ const int targetTempIndex = scratchTempIndex();
if (c->base->asName()) {
- callActivationProperty(c);
+ callActivationProperty(c, targetTempIndex);
} else if (c->base->asTemp()) {
- callValue(c);
+ callValue(c, targetTempIndex);
} else if (c->base->asMember()) {
- callProperty(c);
+ callProperty(c, targetTempIndex);
} else {
Q_UNREACHABLE();
}
-
- // TODO: check if we should store the return value ?
} else {
Q_UNREACHABLE();
}
@@ -355,57 +371,77 @@ static inline ALUFunction aluOpFunction(IR::AluOp op)
void InstructionSelection::visitMove(IR::Move *s)
{
if (IR::Temp *t = s->target->asTemp()) {
+ const int targetTempIndex = t->index;
// Check what kind of load it is, and generate the instruction for that.
// The store to the temp (the target) is done afterwards.
if (IR::Name *n = s->source->asName()) {
Q_UNUSED(n);
if (*n->id == QStringLiteral("this")) { // ### `this' should be a builtin.
- addInstruction(Instruction::LoadThis());
+ Instruction::LoadThis load;
+ load.targetTempIndex = targetTempIndex;
+ addInstruction(load);
} else {
Instruction::LoadName load;
load.name = _engine->newString(*n->id);
+ load.targetTempIndex = targetTempIndex;
addInstruction(load);
}
} else if (IR::Const *c = s->source->asConst()) {
switch (c->type) {
- case IR::UndefinedType:
- addInstruction(Instruction::LoadUndefined());
- break;
- case IR::NullType:
- addInstruction(Instruction::LoadNull());
- break;
+ case IR::UndefinedType: {
+ Instruction::LoadUndefined load;
+ load.targetTempIndex = targetTempIndex;
+ addInstruction(load);
+ } break;
+ case IR::NullType: {
+ Instruction::LoadNull load;
+ load.targetTempIndex = targetTempIndex;
+ addInstruction(load);
+ } break;
case IR::BoolType:
- if (c->value) addInstruction(Instruction::LoadTrue());
- else addInstruction(Instruction::LoadFalse());
+ if (c->value) {
+ Instruction::LoadTrue load;
+ load.targetTempIndex = targetTempIndex;
+ addInstruction(load);
+ } else {
+ Instruction::LoadFalse load;
+ load.targetTempIndex = targetTempIndex;
+ addInstruction(load);
+ }
break;
case IR::NumberType: {
Instruction::LoadNumber load;
load.value = c->value;
+ load.targetTempIndex = targetTempIndex;
addInstruction(load);
- } break;
+ } break;
default:
Q_UNREACHABLE();
break;
}
} else if (IR::Temp *t2 = s->source->asTemp()) {
- Instruction::LoadTemp load;
- load.tempIndex = t2->index;
- addInstruction(load);
+ Instruction::MoveTemp move;
+ move.fromTempIndex = t2->index;
+ move.toTempIndex = targetTempIndex;
+ addInstruction(move);
} else if (IR::String *str = s->source->asString()) {
Instruction::LoadString load;
load.value = _engine->newString(*str->value);
+ load.targetTempIndex = targetTempIndex;
addInstruction(load);
} else if (IR::Closure *clos = s->source->asClosure()) {
Instruction::LoadClosure load;
load.value = clos->value;
+ load.targetTempIndex = targetTempIndex;
addInstruction(load);
} else if (IR::New *ctor = s->source->asNew()) {
- construct(ctor);
+ construct(ctor, targetTempIndex);
} else if (IR::Member *m = s->source->asMember()) {
if (IR::Temp *base = m->base->asTemp()) {
Instruction::LoadProperty load;
load.baseTemp = base->index;
load.name = _engine->newString(*m->name);
+ load.targetTempIndex = targetTempIndex;
addInstruction(load);
} else {
qWarning(" MEMBER");
@@ -414,6 +450,7 @@ void InstructionSelection::visitMove(IR::Move *s)
Instruction::LoadElement load;
load.base = ss->base->asTemp()->index;
load.index = ss->index->asTemp()->index;
+ load.targetTempIndex = targetTempIndex;
addInstruction(load);
} else if (IR::Unop *u = s->source->asUnop()) {
if (IR::Temp *e = u->expr->asTemp()) {
@@ -431,6 +468,7 @@ void InstructionSelection::visitMove(IR::Move *s)
Instruction::Unop unop;
unop.alu = op;
unop.e = e->index;
+ unop.targetTempIndex = targetTempIndex;
addInstruction(unop);
} else {
qWarning(" UNOP1");
@@ -445,22 +483,19 @@ void InstructionSelection::visitMove(IR::Move *s)
binop.alu = aluOpFunction(b->op);
binop.lhsIsTemp = toValueOrTemp(b->left, binop.lhs);
binop.rhsIsTemp = toValueOrTemp(b->right, binop.rhs);
+ binop.targetTempIndex = targetTempIndex;
addInstruction(binop);
} else if (IR::Call *c = s->source->asCall()) {
if (c->base->asName()) {
- callActivationProperty(c);
+ callActivationProperty(c, targetTempIndex);
} else if (c->base->asMember()) {
- callProperty(c);
+ callProperty(c, targetTempIndex);
} else if (c->base->asTemp()) {
- callValue(c);
+ callValue(c, targetTempIndex);
} else {
Q_UNREACHABLE();
}
}
-
- Instruction::StoreTemp st;
- st.tempIndex = t->index;
- addInstruction(st);
return;
} else if (IR::Name *n = s->target->asName()) {
if (IR::Temp *t = s->source->asTemp()) {
@@ -488,11 +523,8 @@ void InstructionSelection::visitMove(IR::Move *s)
addInstruction(ieo);
return;
} else if (s->op == IR::OpInvalid) {
- Instruction::LoadTemp load;
- load.tempIndex = t->index;
- addInstruction(load);
-
Instruction::StoreName store;
+ store.sourceTemp = t->index;
store.name = _engine->newString(*n->id);
addInstruction(store);
return;
@@ -526,11 +558,8 @@ void InstructionSelection::visitMove(IR::Move *s)
addInstruction(ieo);
return;
} else if (s->op == IR::OpInvalid) {
- Instruction::LoadTemp load;
- load.tempIndex = t->index;
- addInstruction(load);
-
Instruction::StoreElement store;
+ store.sourceTemp = t->index;
store.base = ss->base->asTemp()->index;
store.index = ss->index->asTemp()->index;
addInstruction(store);
@@ -565,11 +594,8 @@ void InstructionSelection::visitMove(IR::Move *s)
addInstruction(imo);
return;
} else if (s->op == IR::OpInvalid) {
- Instruction::LoadTemp load;
- load.tempIndex = t->index;
- addInstruction(load);
-
Instruction::StoreProperty store;
+ store.sourceTemp = t->index;
store.baseTemp = m->base->asTemp()->index;
store.name = _engine->newString(*m->name);
addInstruction(store);
@@ -596,15 +622,16 @@ void InstructionSelection::visitJump(IR::Jump *s)
void InstructionSelection::visitCJump(IR::CJump *s)
{
+ int tempIndex;
if (IR::Temp *t = s->cond->asTemp()) {
- Instruction::LoadTemp load;
- load.tempIndex = t->index;
- addInstruction(load);
+ tempIndex = t->index;
} else if (IR::Binop *b = s->cond->asBinop()) {
+ tempIndex = scratchTempIndex();
Instruction::Binop binop;
binop.alu = aluOpFunction(b->op);
binop.lhsIsTemp = toValueOrTemp(b->left, binop.lhs);
binop.rhsIsTemp = toValueOrTemp(b->right, binop.rhs);
+ binop.targetTempIndex = tempIndex;
addInstruction(binop);
} else {
Q_UNREACHABLE();
@@ -612,6 +639,7 @@ void InstructionSelection::visitCJump(IR::CJump *s)
Instruction::CJump jump;
jump.offset = 0;
+ jump.tempIndex = tempIndex;
ptrdiff_t tl = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
_patches[s->iftrue].append(tl);
diff --git a/moth/qv4isel_moth_p.h b/moth/qv4isel_moth_p.h
index 6c92564bc7..bb024c58f3 100644
--- a/moth/qv4isel_moth_p.h
+++ b/moth/qv4isel_moth_p.h
@@ -35,11 +35,12 @@ private:
};
void simpleMove(IR::Move *);
- void callActivationProperty(IR::Call *c);
- void callValue(IR::Call *c);
- void callProperty(IR::Call *c);
- void construct(IR::New *ctor);
+ void callActivationProperty(IR::Call *c, int targetTempIndex);
+ void callValue(IR::Call *c, int targetTempIndex);
+ void callProperty(IR::Call *c, int targetTempIndex);
+ void construct(IR::New *ctor, int targetTempIndex);
void prepareCallArgs(IR::ExprList *, quint32 &, quint32 &);
+ int scratchTempIndex() { return _function->tempCount - _function->locals.size() + _function->maxNumberOfArguments; }
template <int Instr>
inline ptrdiff_t addInstruction(const InstrData<Instr> &data);
diff --git a/moth/qv4vme_moth.cpp b/moth/qv4vme_moth.cpp
index 9bd3bf8042..66df75f79e 100644
--- a/moth/qv4vme_moth.cpp
+++ b/moth/qv4vme_moth.cpp
@@ -49,7 +49,22 @@ using namespace QQmlJS::Moth;
static inline VM::Value *tempValue(QQmlJS::VM::Context *context, QVector<VM::Value> &stack, int index)
{
- TRACE(tempValue, "index = %d / arg = %d / local = %d, stack size = %d", index, (-index-1), index - stack.count(), stack.size());
+#ifdef DO_TRACE_INSTR
+ const char *kind;
+ int pos;
+ if (index < 0) {
+ kind = "arg";
+ pos = -index - 1;
+ } else if (index < (int) context->varCount) {
+ kind = "local";
+ pos = index;
+ } else {
+ kind = "temp";
+ pos = index - context->varCount;
+ }
+ fprintf(stderr, " tempValue: index = %d : %s = %d, stack size = %d\n",
+ index, kind, pos, stack.size());
+#endif // DO_TRACE_INSTR
if (index < 0) {
const int arg = -index - 1;
@@ -84,7 +99,6 @@ void VME::operator()(QQmlJS::VM::Context *context, const uchar *code
#endif
QVector<VM::Value> stack;
- VM::Value tempRegister;
#ifdef MOTH_THREADED_INTERPRETER
const Instr *genericInstr = reinterpret_cast<const Instr *>(code);
@@ -95,75 +109,68 @@ void VME::operator()(QQmlJS::VM::Context *context, const uchar *code
switch (genericInstr->common.instructionType) {
#endif
- MOTH_BEGIN_INSTR(StoreTemp)
- TEMP(instr.tempIndex) = tempRegister;
- MOTH_END_INSTR(StoreTemp)
-
- MOTH_BEGIN_INSTR(LoadTemp)
- tempRegister = TEMP(instr.tempIndex);
- MOTH_END_INSTR(LoadTemp)
-
MOTH_BEGIN_INSTR(MoveTemp)
- TEMP(instr.toTempIndex) = TEMP(instr.fromTempIndex);
+ VM::Value tmp = TEMP(instr.fromTempIndex);
+ TEMP(instr.toTempIndex) = tmp;
MOTH_END_INSTR(MoveTemp)
MOTH_BEGIN_INSTR(LoadUndefined)
- tempRegister = VM::Value::undefinedValue();
+ TEMP(instr.targetTempIndex) = VM::Value::undefinedValue();
MOTH_END_INSTR(LoadUndefined)
MOTH_BEGIN_INSTR(LoadNull)
- tempRegister = VM::Value::nullValue();
+ TEMP(instr.targetTempIndex) = VM::Value::nullValue();
MOTH_END_INSTR(LoadNull)
MOTH_BEGIN_INSTR(LoadTrue)
- tempRegister = VM::Value::fromBoolean(true);
+ TEMP(instr.targetTempIndex) = VM::Value::fromBoolean(true);
MOTH_END_INSTR(LoadTrue)
MOTH_BEGIN_INSTR(LoadFalse)
- tempRegister = VM::Value::fromBoolean(false);
+ TEMP(instr.targetTempIndex) = VM::Value::fromBoolean(false);
MOTH_END_INSTR(LoadFalse)
MOTH_BEGIN_INSTR(LoadNumber)
TRACE(inline, "number = %f", instr.value);
- tempRegister = VM::Value::fromDouble(instr.value);
+ TEMP(instr.targetTempIndex) = VM::Value::fromDouble(instr.value);
MOTH_END_INSTR(LoadNumber)
MOTH_BEGIN_INSTR(LoadString)
- tempRegister = VM::Value::fromString(instr.value);
+ TEMP(instr.targetTempIndex) = VM::Value::fromString(instr.value);
MOTH_END_INSTR(LoadString)
MOTH_BEGIN_INSTR(LoadClosure)
- tempRegister = __qmljs_init_closure(instr.value, context);
+ TEMP(instr.targetTempIndex) = __qmljs_init_closure(instr.value, context);
MOTH_END_INSTR(LoadClosure)
MOTH_BEGIN_INSTR(LoadName)
TRACE(inline, "property name = %s", instr.name->toQString().toUtf8().constData());
- tempRegister = __qmljs_get_activation_property(context, instr.name);
+ TEMP(instr.targetTempIndex) = __qmljs_get_activation_property(context, instr.name);
MOTH_END_INSTR(LoadName)
MOTH_BEGIN_INSTR(StoreName)
TRACE(inline, "property name = %s", instr.name->toQString().toUtf8().constData());
- __qmljs_set_activation_property(context, instr.name, tempRegister);
+ __qmljs_set_activation_property(context, instr.name, TEMP(instr.sourceTemp));
MOTH_END_INSTR(StoreName)
MOTH_BEGIN_INSTR(LoadElement)
- tempRegister = __qmljs_get_element(context, TEMP(instr.base), TEMP(instr.index));
+ TEMP(instr.targetTempIndex) = __qmljs_get_element(context, TEMP(instr.base), TEMP(instr.index));
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(StoreElement)
- __qmljs_set_element(context, TEMP(instr.base), TEMP(instr.index), tempRegister);
+ __qmljs_set_element(context, TEMP(instr.base), TEMP(instr.index), TEMP(instr.sourceTemp));
MOTH_END_INSTR(StoreElement)
MOTH_BEGIN_INSTR(LoadProperty)
TRACE(inline, "base temp = %d, property name = %s", instr.baseTemp, instr.name->toQString().toUtf8().constData());
VM::Value base = TEMP(instr.baseTemp);
- tempRegister = __qmljs_get_property(context, base, instr.name);
+ TEMP(instr.targetTempIndex) = __qmljs_get_property(context, base, instr.name);
MOTH_END_INSTR(LoadProperty)
MOTH_BEGIN_INSTR(StoreProperty)
TRACE(inline, "base temp = %d, property name = %s", instr.baseTemp, instr.name->toQString().toUtf8().constData());
VM::Value base = TEMP(instr.baseTemp);
- __qmljs_set_property(context, base, instr.name, tempRegister);
+ __qmljs_set_property(context, base, instr.name, TEMP(instr.sourceTemp));
MOTH_END_INSTR(StoreProperty)
MOTH_BEGIN_INSTR(Push)
@@ -172,13 +179,14 @@ void VME::operator()(QQmlJS::VM::Context *context, const uchar *code
MOTH_END_INSTR(Push)
MOTH_BEGIN_INSTR(CallValue)
+ TRACE(Call, "argStart = %d, argc = %d, result temp index = %d", instr.args, instr.argc, instr.targetTempIndex);
VM::Value *args = stack.data() + instr.args;
- tempRegister = __qmljs_call_value(context, VM::Value::undefinedValue(), tempRegister, args, instr.argc);
+ TEMP(instr.targetTempIndex) = __qmljs_call_value(context, VM::Value::undefinedValue(), TEMP(instr.destIndex), args, instr.argc);
MOTH_END_INSTR(CallValue)
MOTH_BEGIN_INSTR(CallProperty)
VM::Value *args = stack.data() + instr.args;
- tempRegister = __qmljs_call_property(context, tempRegister, instr.name, args, instr.argc);
+ TEMP(instr.targetTempIndex) = __qmljs_call_property(context, TEMP(instr.baseTemp), instr.name, args, instr.argc);
MOTH_END_INSTR(CallProperty)
MOTH_BEGIN_INSTR(CallBuiltin)
@@ -186,60 +194,60 @@ void VME::operator()(QQmlJS::VM::Context *context, const uchar *code
void *buf;
switch (instr.builtin) {
case Instr::instr_callBuiltin::builtin_typeof:
- tempRegister = __qmljs_builtin_typeof(args[0], context);
+ TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof(args[0], context);
break;
case Instr::instr_callBuiltin::builtin_throw:
- __qmljs_builtin_typeof(args[0], context);
+ TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof(args[0], context);
break;
case Instr::instr_callBuiltin::builtin_create_exception_handler:
buf = __qmljs_create_exception_handler(context);
- tempRegister = VM::Value::fromInt32(setjmp(* static_cast<jmp_buf *>(buf)));
+ TEMP(instr.targetTempIndex) = VM::Value::fromInt32(setjmp(* static_cast<jmp_buf *>(buf)));
break;
case Instr::instr_callBuiltin::builtin_delete_exception_handler:
__qmljs_delete_exception_handler(context);
break;
case Instr::instr_callBuiltin::builtin_get_exception:
- tempRegister = __qmljs_get_exception(context);
+ TEMP(instr.targetTempIndex) = __qmljs_get_exception(context);
break;
case Instr::instr_callBuiltin::builtin_foreach_iterator_object:
- tempRegister = __qmljs_foreach_iterator_object(args[0], context);
+ TEMP(instr.targetTempIndex) = __qmljs_foreach_iterator_object(args[0], context);
break;
case Instr::instr_callBuiltin::builtin_foreach_next_property_name:
- tempRegister = __qmljs_foreach_next_property_name(args[0]);
+ TEMP(instr.targetTempIndex) = __qmljs_foreach_next_property_name(args[0]);
break;
}
MOTH_END_INSTR(CallBuiltin)
MOTH_BEGIN_INSTR(CallBuiltinDeleteMember)
- tempRegister = __qmljs_delete_member(context, TEMP(instr.base), instr.member);
+ TEMP(instr.targetTempIndex) = __qmljs_delete_member(context, TEMP(instr.base), instr.member);
MOTH_END_INSTR(CallBuiltinDeleteMember)
MOTH_BEGIN_INSTR(CallBuiltinDeleteSubscript)
- tempRegister = __qmljs_delete_subscript(context, TEMP(instr.base), TEMP(instr.index));
+ TEMP(instr.targetTempIndex) = __qmljs_delete_subscript(context, TEMP(instr.base), TEMP(instr.index));
MOTH_END_INSTR(CallBuiltinDeleteSubscript)
MOTH_BEGIN_INSTR(CallBuiltinDeleteName)
- tempRegister = __qmljs_delete_property(context, instr.name);
+ TEMP(instr.targetTempIndex) = __qmljs_delete_property(context, instr.name);
MOTH_END_INSTR(CallBuiltinDeleteName)
MOTH_BEGIN_INSTR(CallBuiltinDeleteValue)
- tempRegister = __qmljs_delete_value(context, TEMP(instr.tempIndex));
+ TEMP(instr.targetTempIndex) = __qmljs_delete_value(context, TEMP(instr.tempIndex));
MOTH_END_INSTR(CallBuiltinDeleteValue)
MOTH_BEGIN_INSTR(CreateValue)
VM::Value *args = stack.data() + instr.args;
- tempRegister = __qmljs_construct_value(context, TEMP(instr.func), args, instr.argc);
+ TEMP(instr.targetTempIndex) = __qmljs_construct_value(context, TEMP(instr.func), args, instr.argc);
MOTH_END_INSTR(CreateValue)
MOTH_BEGIN_INSTR(CreateProperty)
VM::Value *args = stack.data() + instr.args;
- tempRegister = __qmljs_construct_property(context, TEMP(instr.base), instr.name, args, instr.argc);
+ TEMP(instr.targetTempIndex) = __qmljs_construct_property(context, TEMP(instr.base), instr.name, args, instr.argc);
MOTH_END_INSTR(CreateProperty)
MOTH_BEGIN_INSTR(CreateActivationProperty)
TRACE(inline, "property name = %s, argc = %d", instr.name->toQString().toUtf8().constData(), instr.argc);
VM::Value *args = stack.data() + instr.args;
- tempRegister = __qmljs_construct_activation_property(context, instr.name, args, instr.argc);
+ TEMP(instr.targetTempIndex) = __qmljs_construct_activation_property(context, instr.name, args, instr.argc);
MOTH_END_INSTR(CreateActivationProperty)
MOTH_BEGIN_INSTR(Jump)
@@ -247,18 +255,18 @@ void VME::operator()(QQmlJS::VM::Context *context, const uchar *code
MOTH_END_INSTR(Jump)
MOTH_BEGIN_INSTR(CJump)
- if (__qmljs_to_boolean(tempRegister, context))
+ if (__qmljs_to_boolean(TEMP(instr.tempIndex), context))
code = ((uchar *)&instr.offset) + instr.offset;
MOTH_END_INSTR(CJump)
MOTH_BEGIN_INSTR(Unop)
- tempRegister = instr.alu(TEMP(instr.e), context);
+ TEMP(instr.targetTempIndex) = instr.alu(TEMP(instr.e), context);
MOTH_END_INSTR(Unop)
MOTH_BEGIN_INSTR(Binop)
VM::Value lhs = instr.lhsIsTemp ? TEMP(instr.lhs.tempIndex) : instr.lhs.value;
VM::Value rhs = instr.rhsIsTemp ? TEMP(instr.rhs.tempIndex) : instr.rhs.value;
- tempRegister = instr.alu(lhs, rhs, context);
+ TEMP(instr.targetTempIndex) = instr.alu(lhs, rhs, context);
MOTH_END_INSTR(Binop)
MOTH_BEGIN_INSTR(Ret)
@@ -267,7 +275,7 @@ void VME::operator()(QQmlJS::VM::Context *context, const uchar *code
MOTH_END_INSTR(Ret)
MOTH_BEGIN_INSTR(LoadThis)
- tempRegister = __qmljs_get_thisObject(context);
+ TEMP(instr.targetTempIndex) = __qmljs_get_thisObject(context);
MOTH_END_INSTR(LoadThis)
MOTH_BEGIN_INSTR(InplaceElementOp)