aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@qt.io>2017-07-18 15:48:21 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2017-08-02 13:56:35 +0000
commit3181e3dae0f01077ff209c4e8d9c83e901f20b0e (patch)
tree500b027e8f636916cbdad275dddf4f59eb290a9e /src/qml
parent49946ef87478fb34dc017a0ff7592ef9a0336d31 (diff)
Introduce an accumulator in the interpreter, and change instructions
This reduces the number of stores to the stack (for which we need a write-barrier in the future) by keeping the last calculated value in the accumulator register (which is a local variable). In the future we might want to collapse certain common instruction patterns into a super-sized instruction. Change-Id: I02ebed2db957765e994c8f939bf7585894881deb Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp14
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h12
-rw-r--r--src/qml/compiler/qv4codegen.cpp819
-rw-r--r--src/qml/compiler/qv4codegen_p.h80
-rw-r--r--src/qml/compiler/qv4compilercontrolflow_p.h38
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp186
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h168
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp44
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h6
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp238
10 files changed, 697 insertions, 908 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index cd85482cb3..27e9d3f417 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -2053,7 +2053,7 @@ void JSCodeGen::beginFunctionBodyHook()
#ifndef V4_BOOTSTRAP
Instruction::LoadQmlContext load;
- load.result = Reference::fromTemp(this, _qmlContextTemp).asLValue();
+ load.result = Reference::fromTemp(this, _qmlContextTemp).temp();
bytecodeGenerator->addInstruction(load);
#if 0
@@ -2065,7 +2065,7 @@ void JSCodeGen::beginFunctionBodyHook()
#endif
Instruction::LoadQmlImportedScripts loadScripts;
- loadScripts.result = Reference::fromTemp(this, _importedScriptsTemp).asLValue();
+ loadScripts.result = Reference::fromTemp(this, _importedScriptsTemp).temp();
bytecodeGenerator->addInstruction(loadScripts);
#endif
}
@@ -2093,11 +2093,11 @@ QV4::Compiler::Codegen::Reference JSCodeGen::fallbackNameLookup(const QString &n
if (_context->compilationMode == QV4::Compiler::QmlBinding)
_context->idObjectDependencies.insert(mapping.idIndex);
- Reference result = Reference::fromTemp(this);
Instruction::LoadIdObject load;
- load.base = Reference::fromTemp(this, _qmlContextTemp).asRValue();
+ load.base = Reference::fromTemp(this, _qmlContextTemp).temp();
load.index = mapping.idIndex;
- load.result = result.asLValue();
+
+ Reference result = Reference::fromAccumulator(this);
bytecodeGenerator->addInstruction(load);
result.isReadonly = true;
return result;
@@ -2112,12 +2112,10 @@ QV4::Compiler::Codegen::Reference JSCodeGen::fallbackNameLookup(const QString &n
return Reference::fromSubscript(imports, Reference::fromConst(this, QV4::Encode(r.scriptIndex)));
} else if (r.type) {
if (r.type->isCompositeSingleton()) {
- Reference result = Reference::fromTemp(this);
Instruction::LoadQmlSingleton load;
- load.result = result.asRValue();
load.name = registerString(name);
bytecodeGenerator->addInstruction(load);
- return result;
+ return Reference::fromAccumulator(this);
}
return Reference::fromName(this, name);
} else {
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index a2c4c20716..d66377fb34 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -150,33 +150,29 @@ public:
return addJumpInstruction(data);
}
- Q_REQUIRED_RESULT Jump jumpEq(const Temp &cond)
+ Q_REQUIRED_RESULT Jump jumpEq()
{
Instruction::JumpEq data;
- data.condition = cond;
return addJumpInstruction(data);
}
- Q_REQUIRED_RESULT Jump jumpNe(const Temp &cond)
+ Q_REQUIRED_RESULT Jump jumpNe()
{
Instruction::JumpNe data;
- data.condition = cond;
return addJumpInstruction(data);
}
- Q_REQUIRED_RESULT Jump jumpStrictEqual(const Temp &lhs, const Temp &rhs)
+ Q_REQUIRED_RESULT Jump jumpStrictEqual(const Temp &lhs)
{
Instruction::JumpStrictEqual data;
data.lhs = lhs;
- data.rhs = rhs;
return addJumpInstruction(data);
}
- Q_REQUIRED_RESULT Jump jumpStrictNotEqual(const Temp &lhs, const Temp &rhs)
+ Q_REQUIRED_RESULT Jump jumpStrictNotEqual(const Temp &lhs)
{
Instruction::JumpStrictNotEqual data;
data.lhs = lhs;
- data.rhs = rhs;
return addJumpInstruction(data);
}
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index d0cb692473..95d895ad28 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -170,7 +170,7 @@ Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr)
return _expr.result();
#ifndef V4_BOOTSTRAP
- if (expr.type == Reference::Const) {
+ if (expr.isConst()) {
auto v = Value::fromReturnedValue(expr.constant);
if (v.isNumber()) {
switch (op) {
@@ -189,66 +189,80 @@ Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr)
}
#endif // V4_BOOTSTRAP
- auto dest = Reference::fromTemp(this);
-
switch (op) {
case UMinus: {
+ expr.loadInAccumulator();
Instruction::UMinus uminus;
- uminus.source = expr.asRValue();
- uminus.result = dest.asLValue();
bytecodeGenerator->addInstruction(uminus);
- } break;
+ return Reference::fromAccumulator(this);
+ }
case UPlus: {
+ expr.loadInAccumulator();
Instruction::UPlus uplus;
- uplus.source = expr.asRValue();
- uplus.result = dest.asLValue();
bytecodeGenerator->addInstruction(uplus);
- } break;
+ return Reference::fromAccumulator(this);
+ }
case Not: {
+ expr.loadInAccumulator();
Instruction::UNot unot;
- unot.source = expr.asRValue();
- unot.result = dest.asLValue();
bytecodeGenerator->addInstruction(unot);
- } break;
+ return Reference::fromAccumulator(this);
+ }
case Compl: {
+ expr.loadInAccumulator();
Instruction::UCompl ucompl;
- ucompl.source = expr.asRValue();
- ucompl.result = dest.asLValue();
bytecodeGenerator->addInstruction(ucompl);
- } break;
+ return Reference::fromAccumulator(this);
+ }
+ case PostIncrement:
+ if (!_expr.accept(nx)) {
+ expr.loadInAccumulator();
+ Instruction::UPlus uplus;
+ bytecodeGenerator->addInstruction(uplus);
+ Reference originalValue = Reference::fromTemp(this).storeRetainAccumulator();
+ Instruction::Increment inc;
+ bytecodeGenerator->addInstruction(inc);
+ expr.storeConsumeAccumulator();
+ return originalValue;
+ } else {
+ // intentionally fall-through: the result is never used, so it's equivalent to
+ // "expr += 1", which is what a pre-increment does as well.
+ }
case PreIncrement: {
- Instruction::PreIncrement inc;
- inc.source = expr.asRValue();
- inc.result = dest.asLValue();
+ expr.loadInAccumulator();
+ Instruction::Increment inc;
bytecodeGenerator->addInstruction(inc);
- expr.store(dest);
- } break;
+ if (_expr.accept(nx))
+ return expr.storeConsumeAccumulator();
+ else
+ return expr.storeRetainAccumulator();
+ }
+ case PostDecrement:
+ if (!_expr.accept(nx)) {
+ expr.loadInAccumulator();
+ Instruction::UPlus uplus;
+ bytecodeGenerator->addInstruction(uplus);
+ Reference originalValue = Reference::fromTemp(this).storeRetainAccumulator();
+ Instruction::Decrement dec;
+ bytecodeGenerator->addInstruction(dec);
+ expr.storeConsumeAccumulator();
+ return originalValue;
+ } else {
+ // intentionally fall-through: the result is never used, so it's equivalent to
+ // "expr -= 1", which is what a pre-decrement does as well.
+ }
case PreDecrement: {
- Instruction::PreDecrement dec;
- dec.source = expr.asRValue();
- dec.result = dest.asLValue();
- bytecodeGenerator->addInstruction(dec);
- expr.store(dest);
- } break;
- case PostIncrement: {
- Instruction::PostIncrement inc;
- inc.source = expr.asRValue();
- inc.result = dest.asLValue();
- bytecodeGenerator->addInstruction(inc);
- expr.asLValue(); // mark expr as needsWriteBack
- expr.writeBack();
- } break;
- case PostDecrement: {
- Instruction::PostDecrement dec;
- dec.source = expr.asRValue();
- dec.result = dest.asLValue();
+ expr.loadInAccumulator();
+ Instruction::Decrement dec;
bytecodeGenerator->addInstruction(dec);
- expr.asLValue(); // mark expr as needsWriteBack
- expr.writeBack();
- } break;
+ if (_expr.accept(nx))
+ return expr.storeConsumeAccumulator();
+ else
+ return expr.storeRetainAccumulator();
+ }
}
- return dest;
+ Q_UNREACHABLE();
}
void Codegen::accept(Node *node)
@@ -281,19 +295,8 @@ void Codegen::statement(ExpressionNode *ast)
if (hasError)
return;
qSwap(_expr, r);
-// if (r.format == ex) {
-// if (r->asCall()) {
-// _block->EXP(*r); // the nest nx representation for calls is EXP(CALL(c..))
-// } else if (r->asTemp() || r->asArgLocal()) {
-// // there is nothing to do
-// } else {
-// unsigned t = bytecodeGenerator->newTemp();
-// move(_block->TEMP(t), *r);
-// }
-// }
-
- if (r.result().isValid() && !r.result().isTempLocalArg())
- r.result().asRValue(); // triggers side effects
+ if (r.result().loadTriggersSideEffect())
+ r.result().loadInAccumulator(); // triggers side effects
}
}
@@ -309,11 +312,11 @@ void Codegen::condition(ExpressionNode *ast, const BytecodeGenerator::Label *ift
Q_ASSERT(iftrue == r.iftrue());
Q_ASSERT(iffalse == r.iffalse());
bytecodeGenerator->setLocation(ast->firstSourceLocation());
- auto cond = r.result().asRValue();
+ r.result().loadInAccumulator();
if (r.trueBlockFollowsCondition())
- bytecodeGenerator->jumpNe(cond).link(*r.iffalse());
+ bytecodeGenerator->jumpNe().link(*r.iffalse());
else
- bytecodeGenerator->jumpEq(cond).link(*r.iftrue());
+ bytecodeGenerator->jumpEq().link(*r.iftrue());
}
}
}
@@ -371,8 +374,10 @@ void Codegen::variableDeclaration(VariableDeclaration *ast)
Reference rhs = expression(ast->expression);
if (hasError)
return;
+
Reference lhs = referenceForName(ast->name.toString(), true);
- lhs.storeConsume(rhs);
+ rhs.loadInAccumulator();
+ lhs.storeConsumeAccumulator();
}
void Codegen::variableDeclarationList(VariableDeclarationList *ast)
@@ -572,7 +577,6 @@ bool Codegen::visit(ArrayLiteral *ast)
if (hasError)
return false;
- auto result = Reference::fromTemp(this);
TempScope scope(this);
int argc = 0;
@@ -582,10 +586,11 @@ bool Codegen::visit(ArrayLiteral *ast)
if (args == -1)
args = temp;
if (!arg) {
- Reference::fromTemp(this, temp).store(Reference::fromConst(this, Primitive::emptyValue().asReturnedValue()));
+ auto c = Reference::fromConst(this, Primitive::emptyValue().asReturnedValue());
+ (void) c.storeInTemp(temp);
} else {
TempScope scope(this);
- Reference::fromTemp(this, temp).store(expression(arg));
+ (void) expression(arg).storeInTemp(temp);
}
++argc;
};
@@ -610,9 +615,8 @@ bool Codegen::visit(ArrayLiteral *ast)
Instruction::CallBuiltinDefineArray call;
call.argc = argc;
call.args = Moth::Temp::create(args);
- call.result = result.asLValue();
bytecodeGenerator->addInstruction(call);
- _expr.setResult(result);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -625,6 +629,7 @@ bool Codegen::visit(ArrayMemberExpression *ast)
Reference base = expression(ast->base);
if (hasError)
return false;
+ base = base.storeInTemp();
Reference index = expression(ast->expression);
_expr.setResult(Reference::fromSubscript(base, index));
return false;
@@ -663,26 +668,23 @@ bool Codegen::visit(BinaryExpression *ast)
auto iftrue = bytecodeGenerator->newLabel();
auto endif = bytecodeGenerator->newLabel();
- auto r = Reference::fromTemp(this);
-
- Reference lhs = expression(ast->left);
+ Reference left = expression(ast->left);
if (hasError)
return false;
-
- r.store(lhs);
+ left.loadInAccumulator();
bytecodeGenerator->setLocation(ast->operatorToken);
- bytecodeGenerator->jumpNe(r.asRValue()).link(endif);
+ bytecodeGenerator->jumpNe().link(endif);
iftrue.link();
- Reference rhs = expression(ast->right);
+ Reference right = expression(ast->right);
if (hasError)
return false;
+ right.loadInAccumulator();
- r.store(rhs);
endif.link();
- _expr.setResult(r);
+ _expr.setResult(Reference::fromAccumulator(this));
}
return false;
} else if (ast->op == QSOperator::Or) {
@@ -695,26 +697,23 @@ bool Codegen::visit(BinaryExpression *ast)
auto iffalse = bytecodeGenerator->newLabel();
auto endif = bytecodeGenerator->newLabel();
- auto r = Reference::fromTemp(this);
-
- Reference lhs = expression(ast->left);
+ Reference left = expression(ast->left);
if (hasError)
return false;
-
- r.store(lhs);
+ left.loadInAccumulator();
bytecodeGenerator->setLocation(ast->operatorToken);
- bytecodeGenerator->jumpEq(r.asRValue()).link(endif);
+ bytecodeGenerator->jumpEq().link(endif);
iffalse.link();
- Reference rhs = expression(ast->right);
+ Reference right = expression(ast->right);
if (hasError)
return false;
+ right.loadInAccumulator();
- r.store(rhs);
endif.link();
- _expr.setResult(r);
+ _expr.setResult(Reference::fromAccumulator(this));
}
return false;
}
@@ -732,7 +731,7 @@ bool Codegen::visit(BinaryExpression *ast)
case QSOperator::Assign: {
if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(left, ast->left->lastSourceLocation()))
return false;
- Reference right = expression(ast->right);
+ expression(ast->right).loadInAccumulator();
if (hasError)
return false;
if (!left.isLValue()) {
@@ -740,8 +739,7 @@ bool Codegen::visit(BinaryExpression *ast)
return false;
}
- left.storeConsume(right);
- _expr.setResult(left);
+ _expr.setResult(left.storeRetainAccumulator());
break;
}
@@ -764,18 +762,29 @@ bool Codegen::visit(BinaryExpression *ast)
return false;
}
+ Reference tempLeft = left.storeInTemp();
Reference right = expression(ast->right);
if (hasError)
return false;
- _expr.setResult(Reference::fromTemp(this));
- binopHelper(baseOp(ast->op), left, right, _expr.result());
- left.store(_expr.result());
+ binopHelper(baseOp(ast->op), tempLeft, right).loadInAccumulator();
+ _expr.setResult(left.storeRetainAccumulator());
break;
}
+ case QSOperator::BitAnd:
+ case QSOperator::BitOr:
+ case QSOperator::BitXor:
+ if (left.isConst()) {
+ Reference right = expression(ast->right);
+ if (hasError)
+ return false;
+ _expr.setResult(binopHelper(static_cast<QSOperator::Op>(ast->op), right, left));
+ break;
+ }
+ // intentional fall-through!
case QSOperator::In:
case QSOperator::InstanceOf:
case QSOperator::Equal:
@@ -787,28 +796,20 @@ bool Codegen::visit(BinaryExpression *ast)
case QSOperator::StrictEqual:
case QSOperator::StrictNotEqual:
case QSOperator::Add:
- case QSOperator::BitAnd:
- case QSOperator::BitOr:
- case QSOperator::BitXor:
case QSOperator::Div:
- case QSOperator::LShift:
case QSOperator::Mod:
case QSOperator::Mul:
- case QSOperator::RShift:
case QSOperator::Sub:
+ case QSOperator::LShift:
+ case QSOperator::RShift:
case QSOperator::URShift: {
- if (left.isConst()) {
- //### TODO: try constant folding?
- }
-
- left.asRValue(); // force any loads of the lhs, so the rhs won't clobber it
+ auto tempLeft = left.storeInTemp(); // force any loads of the lhs, so the rhs won't clobber it
Reference right = expression(ast->right);
if (hasError)
return false;
- _expr.setResult(Reference::fromTemp(this));
- binopHelper(static_cast<QSOperator::Op>(ast->op), left, right, _expr.result());
+ _expr.setResult(binopHelper(static_cast<QSOperator::Op>(ast->op), tempLeft, right));
break;
}
@@ -818,153 +819,121 @@ bool Codegen::visit(BinaryExpression *ast)
return false;
}
-QV4::Moth::Temp Codegen::binopHelper(QSOperator::Op oper, Reference &left, Reference &right,
- const Reference &dest)
+Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Reference &right)
{
- if (oper == QSOperator::Add) {
+ switch (oper) {
+ case QSOperator::Add: {
+ right.loadInAccumulator();
Instruction::Add add;
- add.lhs = left.asRValue();
- add.rhs = right.asRValue();
- add.result = dest.asLValue();
+ add.lhs = left.temp();
bytecodeGenerator->addInstruction(add);
- return add.result;
+ break;
}
- if (oper == QSOperator::Sub) {
+ case QSOperator::Sub: {
+ right.loadInAccumulator();
Instruction::Sub sub;
- sub.lhs = left.asRValue();
- sub.rhs = right.asRValue();
- sub.result = dest.asLValue();
+ sub.lhs = left.temp();
bytecodeGenerator->addInstruction(sub);
- return sub.result;
+ break;
}
- if (oper == QSOperator::Mul) {
+ case QSOperator::Mul: {
+ right.loadInAccumulator();
Instruction::Mul mul;
- mul.lhs = left.asRValue();
- mul.rhs = right.asRValue();
- mul.result = dest.asLValue();
+ mul.lhs = left.temp();
bytecodeGenerator->addInstruction(mul);
- return mul.result;
- }
- if (oper == QSOperator::BitAnd) {
- Reference *l = &left;
- Reference *r = &right;
- if (l->type == Reference::Const)
- std::swap(l, r);
- if (r->type == Reference::Const) {
+ break;
+ }
+ case QSOperator::BitAnd:
+ if (right.isConst()) {
+ left.loadInAccumulator();
Instruction::BitAndConst bitAnd;
- bitAnd.lhs = l->asRValue();
- bitAnd.rhs = Primitive::fromReturnedValue(r->constant).toInt32();
- bitAnd.result = dest.asLValue();
+ bitAnd.rhs = Primitive::fromReturnedValue(right.constant).toInt32();
+ bytecodeGenerator->addInstruction(bitAnd);
+ } else {
+ right.loadInAccumulator();
+ Instruction::BitAnd bitAnd;
+ bitAnd.lhs = left.temp();
bytecodeGenerator->addInstruction(bitAnd);
- return bitAnd.result;
}
- Instruction::BitAnd bitAnd;
- bitAnd.lhs = left.asRValue();
- bitAnd.rhs = right.asRValue();
- bitAnd.result = dest.asLValue();
- bytecodeGenerator->addInstruction(bitAnd);
- return bitAnd.result;
- }
- if (oper == QSOperator::BitOr) {
- Reference *l = &left;
- Reference *r = &right;
- if (l->type == Reference::Const)
- std::swap(l, r);
- if (r->type == Reference::Const) {
+ break;
+ case QSOperator::BitOr:
+ if (right.isConst()) {
+ left.loadInAccumulator();
Instruction::BitOrConst bitOr;
- bitOr.lhs = l->asRValue();
- bitOr.rhs = Primitive::fromReturnedValue(r->constant).toInt32();
- bitOr.result = dest.asLValue();
+ bitOr.rhs = Primitive::fromReturnedValue(right.constant).toInt32();
+ bytecodeGenerator->addInstruction(bitOr);
+ } else {
+ right.loadInAccumulator();
+ Instruction::BitOr bitOr;
+ bitOr.lhs = left.temp();
bytecodeGenerator->addInstruction(bitOr);
- return bitOr.result;
}
- Instruction::BitOr bitOr;
- bitOr.lhs = left.asRValue();
- bitOr.rhs = right.asRValue();
- bitOr.result = dest.asLValue();
- bytecodeGenerator->addInstruction(bitOr);
- return bitOr.result;
- }
- if (oper == QSOperator::BitXor) {
- Reference *l = &left;
- Reference *r = &right;
- if (l->type == Reference::Const)
- std::swap(l, r);
- if (r->type == Reference::Const) {
+ break;
+ case QSOperator::BitXor:
+ if (right.isConst()) {
+ left.loadInAccumulator();
Instruction::BitXorConst bitXor;
- bitXor.lhs = l->asRValue();
- bitXor.rhs = Primitive::fromReturnedValue(r->constant).toInt32();
- bitXor.result = dest.asLValue();
+ bitXor.rhs = Primitive::fromReturnedValue(right.constant).toInt32();
+ bytecodeGenerator->addInstruction(bitXor);
+ } else {
+ right.loadInAccumulator();
+ Instruction::BitXor bitXor;
+ bitXor.lhs = left.temp();
bytecodeGenerator->addInstruction(bitXor);
- return bitXor.result;
}
- Instruction::BitXor bitXor;
- bitXor.lhs = left.asRValue();
- bitXor.rhs = right.asRValue();
- bitXor.result = dest.asLValue();
- bytecodeGenerator->addInstruction(bitXor);
- return bitXor.result;
- }
- if (oper == QSOperator::RShift) {
- if (right.type == Reference::Const) {
+ break;
+ case QSOperator::RShift:
+ if (right.isConst()) {
+ left.loadInAccumulator();
Instruction::ShrConst shr;
- shr.lhs = left.asRValue();
shr.rhs = Primitive::fromReturnedValue(right.constant).toInt32() & 0x1f;
- shr.result = dest.asLValue();
bytecodeGenerator->addInstruction(shr);
- return shr.result;
+ } else {
+ right.loadInAccumulator();
+ Instruction::Shr shr;
+ shr.lhs = left.temp();
+ bytecodeGenerator->addInstruction(shr);
}
- Instruction::Shr shr;
- shr.lhs = left.asRValue();
- shr.rhs = right.asRValue();
- shr.result = dest.asLValue();
- bytecodeGenerator->addInstruction(shr);
- return shr.result;
- }
- if (oper == QSOperator::LShift) {
- if (right.type == Reference::Const) {
+ break;
+ case QSOperator::LShift:
+ if (right.isConst()) {
+ left.loadInAccumulator();
Instruction::ShlConst shl;
- shl.lhs = left.asRValue();
shl.rhs = Primitive::fromReturnedValue(right.constant).toInt32() & 0x1f;
- shl.result = dest.asLValue();
bytecodeGenerator->addInstruction(shl);
- return shl.result;
+ } else {
+ right.loadInAccumulator();
+ Instruction::Shl shl;
+ shl.lhs = left.temp();
+ bytecodeGenerator->addInstruction(shl);
}
- Instruction::Shl shl;
- shl.lhs = left.asRValue();
- shl.rhs = right.asRValue();
- shl.result = dest.asLValue();
- bytecodeGenerator->addInstruction(shl);
- return shl.result;
- }
-
- if (oper == QSOperator::InstanceOf || oper == QSOperator::In || oper == QSOperator::Add) {
+ break;
+ case QSOperator::InstanceOf:
+ case QSOperator::In: {
Instruction::BinopContext binop;
if (oper == QSOperator::InstanceOf)
binop.alu = QV4::Runtime::instanceof;
- else if (oper == QSOperator::In)
- binop.alu = QV4::Runtime::in;
else
- binop.alu = QV4::Runtime::add;
- binop.lhs = left.asRValue();
- binop.rhs = right.asRValue();
- binop.result = dest.asLValue();
+ binop.alu = QV4::Runtime::in;
Q_ASSERT(binop.alu != QV4::Runtime::InvalidRuntimeMethod);
+ right.loadInAccumulator();
+ binop.lhs = left.temp();
bytecodeGenerator->addInstruction(binop);
- return binop.result;
- } else {
+ break;
+ }
+ default: {
auto binopFunc = aluOpFunction(oper);
Q_ASSERT(binopFunc != QV4::Runtime::InvalidRuntimeMethod);
+ right.loadInAccumulator();
Instruction::Binop binop;
binop.alu = binopFunc;
- binop.lhs = left.asRValue();
- binop.rhs = right.asRValue();
- binop.result = dest.asLValue();
+ binop.lhs = left.temp();
bytecodeGenerator->addInstruction(binop);
- return binop.result;
+ break;
+ }
}
- Q_UNIMPLEMENTED();
+ return Reference::fromAccumulator(this);
}
bool Codegen::visit(CallExpression *ast)
@@ -972,54 +941,51 @@ bool Codegen::visit(CallExpression *ast)
if (hasError)
return false;
- Reference r = Reference::fromTemp(this);
-
TempScope scope(this);
Reference base = expression(ast->base);
if (hasError)
return false;
+ if (base.type != Reference::Member && base.type != Reference::Subscript &&
+ base.type != Reference::Name)
+ base = base.storeInTemp();
auto calldata = pushArgs(ast->arguments);
if (hasError)
return false;
+ //### Do we really need all these call instructions? can's we load the callee in a temp?
if (base.type == Reference::Member) {
Instruction::CallProperty call;
- call.base = base.base;
- call.name = base.nameIndex;
+ call.base = base.propertyBase;
+ call.name = base.propertyNameIndex;
call.callData = calldata;
- call.result = r.asLValue();
bytecodeGenerator->addInstruction(call);
} else if (base.type == Reference::Subscript) {
Instruction::CallElement call;
- call.base = base.base;
- call.index = base.subscript;
+ call.base = base.elementBase;
+ call.index = base.elementSubscript;
call.callData = calldata;
- call.result = r.asLValue();
bytecodeGenerator->addInstruction(call);
} else if (base.type == Reference::Name) {
if (useFastLookups && base.global) {
Instruction::CallGlobalLookup call;
- call.index = registerGlobalGetterLookup(base.nameIndex);
+ call.index = registerGlobalGetterLookup(base.unqualifiedNameIndex);
call.callData = calldata;
- call.result = r.asLValue();
bytecodeGenerator->addInstruction(call);
} else {
Instruction::CallActivationProperty call;
- call.name = base.nameIndex;
+ call.name = base.unqualifiedNameIndex;
call.callData = calldata;
- call.result = r.asLValue();
bytecodeGenerator->addInstruction(call);
}
} else {
Instruction::CallValue call;
- call.dest = base.asRValue();
+ call.dest = base.temp();
call.callData = calldata;
- call.result = r.asLValue();
bytecodeGenerator->addInstruction(call);
}
- _expr.setResult(r);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -1030,13 +996,16 @@ Moth::Temp Codegen::pushArgs(ArgumentList *args)
++argc;
int calldata = bytecodeGenerator->newTempArray(argc + 2); // 2 additional values for CallData
- Reference::fromTemp(this, calldata).store(Reference::fromConst(this, QV4::Encode(argc)));
- Reference::fromTemp(this, calldata + 1).store(Reference::fromConst(this, QV4::Encode::undefined()));
+ (void) Reference::fromConst(this, QV4::Encode(argc)).storeInTemp(calldata);
+ (void) Reference::fromConst(this, QV4::Encode::undefined()).storeInTemp(calldata + 1);
argc = 0;
for (ArgumentList *it = args; it; it = it->next) {
TempScope scope(this);
- Reference::fromTemp(this, calldata + 2 + argc).store(expression(it->expression));
+ Reference e = expression(it->expression);
+ if (hasError)
+ break;
+ (void) e.storeInTemp(calldata + 2 + argc);
++argc;
}
@@ -1048,9 +1017,6 @@ bool Codegen::visit(ConditionalExpression *ast)
if (hasError)
return true;
- const unsigned t = bytecodeGenerator->newTemp();
- _expr.setResult(Reference::fromTemp(this, t));
-
TempScope scope(this);
BytecodeGenerator::Label iftrue = bytecodeGenerator->newLabel();
@@ -1058,13 +1024,20 @@ bool Codegen::visit(ConditionalExpression *ast)
condition(ast->expression, &iftrue, &iffalse, true);
iftrue.link();
- _expr.result().store(expression(ast->ok));
+ Reference ok = expression(ast->ok);
+ if (hasError)
+ return false;
+ ok.loadInAccumulator();
BytecodeGenerator::Jump jump_endif = bytecodeGenerator->jump();
iffalse.link();
- _expr.result().store(expression(ast->ko));
+ Reference ko = expression(ast->ko);
+ if (hasError)
+ return false;
+ ko.loadInAccumulator();
jump_endif.link();
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -1097,29 +1070,26 @@ bool Codegen::visit(DeleteExpression *ast)
throwSyntaxError(ast->deleteToken, QStringLiteral("Delete of an unqualified identifier in strict mode."));
return false;
}
- _expr.setResult(Reference::fromTemp(this));
Instruction::CallBuiltinDeleteName del;
- del.name = expr.nameIndex;
- del.result = _expr.result().asLValue();
+ del.name = expr.unqualifiedNameIndex;
bytecodeGenerator->addInstruction(del);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
case Reference::Member: {
- _expr.setResult(Reference::fromTemp(this));
Instruction::CallBuiltinDeleteMember del;
- del.base = expr.base;
- del.member = expr.nameIndex;
- del.result = _expr.result().asLValue();
+ del.base = expr.propertyBase;
+ del.member = expr.propertyNameIndex;
bytecodeGenerator->addInstruction(del);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
case Reference::Subscript: {
- _expr.setResult(Reference::fromTemp(this));
Instruction::CallBuiltinDeleteSubscript del;
- del.base = expr.base;
- del.index = expr.subscript;
- del.result = _expr.result().asLValue();
+ del.base = expr.elementBase;
+ del.index = expr.elementSubscript;
bytecodeGenerator->addInstruction(del);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
default:
@@ -1241,21 +1211,21 @@ bool Codegen::visit(NewExpression *ast)
if (hasError)
return false;
- Reference r = Reference::fromTemp(this);
TempScope scope(this);
Reference base = expression(ast->expression);
if (hasError)
return false;
+ //### Maybe create a CreateValueA that takes an accumulator?
+ base = base.storeInTemp();
auto calldata = pushArgs(0);
Instruction::CreateValue create;
- create.func = base.asRValue();
+ create.func = base.temp();
create.callData = calldata;
- create.result = r.asLValue();
bytecodeGenerator->addInstruction(create);
- _expr.setResult(r);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -1264,23 +1234,22 @@ bool Codegen::visit(NewMemberExpression *ast)
if (hasError)
return false;
- Reference r = Reference::fromTemp(this);
TempScope scope(this);
Reference base = expression(ast->base);
if (hasError)
return false;
+ base = base.storeInTemp();
auto calldata = pushArgs(ast->arguments);
if (hasError)
return false;
Instruction::CreateValue create;
- create.func = base.asRValue();
+ create.func = base.temp();
create.callData = calldata;
- create.result = r.asRValue();
bytecodeGenerator->addInstruction(create);
- _expr.setResult(r);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -1322,7 +1291,6 @@ bool Codegen::visit(ObjectLiteral *ast)
QMap<QString, ObjectPropertyValue> valueMap;
- auto result = Reference::fromTemp(this);
TempScope scope(this);
for (PropertyAssignmentList *it = ast->properties; it; it = it->next) {
@@ -1339,9 +1307,7 @@ bool Codegen::visit(ObjectLiteral *ast)
return false;
}
- v.rvalue = value;
- if (v.rvalue.type != Reference::Const)
- v.rvalue.asRValue();
+ v.rvalue = value.storeInTemp();
} else if (PropertyGetterSetter *gs = AST::cast<AST::PropertyGetterSetter *>(it->assignment)) {
const int function = defineFunction(name, gs, gs->formals, gs->functionBody ? gs->functionBody->elements : 0);
ObjectPropertyValue &v = valueMap[name];
@@ -1386,7 +1352,7 @@ bool Codegen::visit(ObjectLiteral *ast)
int temp = bytecodeGenerator->newTemp();
if (args == -1)
args = temp;
- Reference::fromTemp(this, temp).store(arg);
+ (void) arg.storeInTemp(temp);
};
auto undefined = [this](){ return Reference::fromConst(this, Encode::undefined()); };
@@ -1438,10 +1404,9 @@ bool Codegen::visit(ObjectLiteral *ast)
call.arrayValueCount = arrayKeyWithValue.size();
call.arrayGetterSetterCountAndFlags = arrayGetterSetterCountAndFlags;
call.args = Moth::Temp::create(args);
- call.result = result.asLValue();
bytecodeGenerator->addInstruction(call);
- _expr.setResult(result);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -1526,12 +1491,11 @@ bool Codegen::visit(RegExpLiteral *ast)
if (hasError)
return false;
- auto r = Reference::fromTemp(this);
+ auto r = Reference::fromAccumulator(this);
r.isReadonly = true;
_expr.setResult(r);
Instruction::LoadRegExp instr;
- instr.result = r.asLValue();
instr.regExpId = jsUnitGenerator->registerRegExp(ast);
bytecodeGenerator->addInstruction(instr);
return false;
@@ -1542,12 +1506,11 @@ bool Codegen::visit(StringLiteral *ast)
if (hasError)
return false;
- auto r = Reference::fromTemp(this);
+ auto r = Reference::fromAccumulator(this);
r.isReadonly = true;
_expr.setResult(r);
Instruction::LoadRuntimeString instr;
- instr.result = r.asLValue();
instr.stringId = registerString(ast->value.toString());
bytecodeGenerator->addInstruction(instr);
return false;
@@ -1585,8 +1548,6 @@ bool Codegen::visit(TypeOfExpression *ast)
if (hasError)
return false;
- _expr.setResult(Reference::fromTemp(this));
-
TempScope scope(this);
Reference expr = expression(ast->expression);
@@ -1596,15 +1557,14 @@ bool Codegen::visit(TypeOfExpression *ast)
if (expr.type == Reference::Name) {
// special handling as typeof doesn't throw here
Instruction::CallBuiltinTypeofName instr;
- instr.name = expr.nameIndex;
- instr.result = _expr.result().asLValue();
+ instr.name = expr.unqualifiedNameIndex;
bytecodeGenerator->addInstruction(instr);
} else {
+ expr.loadInAccumulator();
Instruction::CallBuiltinTypeofValue instr;
- instr.value = expr.asRValue();
- instr.result = _expr.result().asLValue();
bytecodeGenerator->addInstruction(instr);
}
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -1647,9 +1607,8 @@ bool Codegen::visit(FunctionDeclaration * ast)
TempScope scope(this);
if (_context->compilationMode == QmlBinding) {
- Reference source = Reference::fromName(this, ast->name.toString());
- Reference target = Reference::fromTemp(this, _returnAddress);
- target.store(source);
+ Reference::fromName(this, ast->name.toString()).loadInAccumulator();
+ Reference::fromTemp(this, _returnAddress).storeConsumeAccumulator();
}
_expr.accept(nx);
return false;
@@ -1722,22 +1681,20 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
if (member.function) {
const int function = defineFunction(member.function->name.toString(), member.function, member.function->formals,
member.function->body ? member.function->body->elements : 0);
- auto func = Reference::fromClosure(this, function);
+ Reference::fromClosure(this, function).loadInAccumulator();
if (! _context->parent) {
- Reference name = Reference::fromName(this, member.function->name.toString());
- name.store(func);
+ Reference::fromName(this, member.function->name.toString()).storeConsumeAccumulator();
} else {
Q_ASSERT(member.index >= 0);
Reference local = member.canEscape ? Reference::fromLocal(this, member.index, 0) : Reference::fromTemp(this, member.index, true);
- local.store(func);
+ local.storeConsumeAccumulator();
}
}
}
if (_context->usesArgumentsObject == Context::ArgumentsObjectUsed) {
- auto args = referenceForName(QStringLiteral("arguments"), false);
Instruction::CallBuiltinSetupArgumentsObject setup;
- setup.result = args.asLValue();
bytecodeGenerator->addInstruction(setup);
+ referenceForName(QStringLiteral("arguments"), false).storeConsumeAccumulator();
}
if (_context->usesThis && !_context->isStrict) {
// make sure we convert this to an object
@@ -1754,7 +1711,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
{
Instruction::Ret ret;
- ret.result = Reference::fromTemp(this, _returnAddress).base;
+ ret.result = Reference::fromTemp(this, _returnAddress).temporary;
bytecodeGenerator->addInstruction(ret);
}
@@ -1903,8 +1860,8 @@ bool Codegen::visit(ExpressionStatement *ast)
Reference e = expression(ast->expression);
if (hasError)
return false;
- Reference retVal = Reference::fromTemp(this, _returnAddress);
- retVal.store(e);
+ e.loadInAccumulator();
+ Reference::fromTemp(this, _returnAddress).storeConsumeAccumulator();
} else {
statement(ast->expression);
}
@@ -1923,10 +1880,10 @@ bool Codegen::visit(ForEachStatement *ast)
if (hasError)
return true;
+ expr.loadInAccumulator();
Instruction::CallBuiltinForeachIteratorObject iteratorObjInstr;
- iteratorObjInstr.result = obj.asLValue();
- iteratorObjInstr.arg = expr.asRValue();
bytecodeGenerator->addInstruction(iteratorObjInstr);
+ obj.storeConsumeAccumulator();
BytecodeGenerator::Label in = bytecodeGenerator->newLabel();
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
@@ -1943,15 +1900,13 @@ bool Codegen::visit(ForEachStatement *ast)
Reference lhs = expression(ast->initialiser);
+ obj.loadInAccumulator();
Instruction::CallBuiltinForeachNextPropertyName nextPropInstr;
- nextPropInstr.result = lhs.asLValue();
- nextPropInstr.arg = obj.asRValue();
bytecodeGenerator->addInstruction(nextPropInstr);
+ lhs = lhs.storeRetainAccumulator().storeInTemp();
- lhs.writeBack();
-
- Reference null = Reference::fromConst(this, QV4::Encode::null());
- bytecodeGenerator->jumpStrictNotEqual(lhs.asRValue(), null.asRValue()).link(body);
+ Reference::fromConst(this, QV4::Encode::null()).loadInAccumulator();
+ bytecodeGenerator->jumpStrictNotEqual(lhs.temp()).link(body);
end.link();
@@ -2064,10 +2019,10 @@ bool Codegen::visit(LocalForEachStatement *ast)
variableDeclaration(ast->declaration);
+ expr.loadInAccumulator();
Instruction::CallBuiltinForeachIteratorObject iteratorObjInstr;
- iteratorObjInstr.result = obj.asLValue();
- iteratorObjInstr.arg = expr.asRValue();
bytecodeGenerator->addInstruction(iteratorObjInstr);
+ obj.storeConsumeAccumulator();
BytecodeGenerator::Label in = bytecodeGenerator->newLabel();
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
@@ -2082,15 +2037,13 @@ bool Codegen::visit(LocalForEachStatement *ast)
in.link();
+ obj.loadInAccumulator();
Instruction::CallBuiltinForeachNextPropertyName nextPropInstr;
- nextPropInstr.result = it.asLValue();
- nextPropInstr.arg = obj.asRValue();
bytecodeGenerator->addInstruction(nextPropInstr);
+ auto lhs = it.storeRetainAccumulator().storeInTemp();
- it.writeBack();
-
- Reference null = Reference::fromConst(this, QV4::Encode::null());
- bytecodeGenerator->jumpStrictNotEqual(it.asRValue(), null.asRValue()).link(body);
+ Reference::fromConst(this, QV4::Encode::null()).loadInAccumulator();
+ bytecodeGenerator->jumpStrictNotEqual(lhs.temp()).link(body);
end.link();
@@ -2137,7 +2090,10 @@ bool Codegen::visit(ReturnStatement *ast)
}
if (ast->expression) {
Reference expr = expression(ast->expression);
- Reference::fromTemp(this, _returnAddress).storeConsume(expr);
+ if (hasError)
+ return false;
+ expr.loadInAccumulator();
+ Reference::fromTemp(this, _returnAddress).storeConsumeAccumulator();
}
if (_context->controlFlow) {
@@ -2160,6 +2116,9 @@ bool Codegen::visit(SwitchStatement *ast)
BytecodeGenerator::Label switchEnd = bytecodeGenerator->newLabel();
Reference lhs = expression(ast->expression);
+ if (hasError)
+ return false;
+ lhs = lhs.storeInTemp();
// set up labels for all clauses
QHash<Node *, BytecodeGenerator::Label> blockMap;
@@ -2174,13 +2133,19 @@ bool Codegen::visit(SwitchStatement *ast)
for (CaseClauses *it = ast->block->clauses; it; it = it->next) {
CaseClause *clause = it->clause;
Reference rhs = expression(clause->expression);
- bytecodeGenerator->jumpStrictEqual(lhs.asRValue(), rhs.asRValue()).link(blockMap.value(clause));
+ if (hasError)
+ return false;
+ rhs.loadInAccumulator();
+ bytecodeGenerator->jumpStrictEqual(lhs.temp()).link(blockMap.value(clause));
}
for (CaseClauses *it = ast->block->moreClauses; it; it = it->next) {
CaseClause *clause = it->clause;
Reference rhs = expression(clause->expression);
- bytecodeGenerator->jumpStrictEqual(lhs.asRValue(), rhs.asRValue()).link(blockMap.value(clause));
+ if (hasError)
+ return false;
+ rhs.loadInAccumulator();
+ bytecodeGenerator->jumpStrictEqual(lhs.temp()).link(blockMap.value(clause));
}
if (DefaultClause *defaultClause = ast->block->defaultClause)
@@ -2224,17 +2189,19 @@ bool Codegen::visit(SwitchStatement *ast)
bool Codegen::visit(ThrowStatement *ast)
{
if (hasError)
- return true;
+ return false;
TempScope scope(this);
Reference expr = expression(ast->expression);
+ if (hasError)
+ return false;
if (_context->controlFlow) {
_context->controlFlow->handleThrow(expr);
} else {
+ expr.loadInAccumulator();
Instruction::CallBuiltinThrow instr;
- instr.arg = expr.asRValue();
bytecodeGenerator->addInstruction(instr);
}
return false;
@@ -2333,12 +2300,12 @@ bool Codegen::visit(WithStatement *ast)
Reference src = expression(ast->expression);
if (hasError)
return false;
- src.asRValue(); // trigger load before we setup the exception handler, so exceptions here go to the right place
+ src = src.storeInTemp(); // trigger load before we setup the exception handler, so exceptions here go to the right place
ControlFlowWith flow(this);
+ src.loadInAccumulator();
Instruction::CallBuiltinPushScope pushScope;
- pushScope.arg = src.asRValue();
bytecodeGenerator->addInstruction(pushScope);
statement(ast->statement);
@@ -2388,7 +2355,7 @@ bool Codegen::throwSyntaxErrorOnEvalOrArgumentsInStrictMode(const Reference &r,
return false;
bool isArgOrEval = false;
if (r.type == Reference::Name) {
- QString str = jsUnitGenerator->stringForIndex(r.nameIndex);
+ QString str = jsUnitGenerator->stringForIndex(r.unqualifiedNameIndex);
if (str == QLatin1String("eval") || str == QLatin1String("arguments")) {
isArgOrEval = true;
}
@@ -2487,15 +2454,14 @@ Codegen::Reference::Reference(const Codegen::Reference &other)
Codegen::Reference &Codegen::Reference::operator =(const Reference &other)
{
- other.writeBack();
-
type = other.type;
- base = other.base;
switch (type) {
case Invalid:
+ case Accumulator:
break;
case Temporary:
+ temporary = other.temporary;
break;
case Local:
case Argument:
@@ -2503,11 +2469,15 @@ Codegen::Reference &Codegen::Reference::operator =(const Reference &other)
scope = other.scope;
break;
case Name:
+ unqualifiedNameIndex = other.unqualifiedNameIndex;
+ break;
case Member:
- nameIndex = other.nameIndex;
+ propertyBase = other.propertyBase;
+ propertyNameIndex = other.propertyNameIndex;
break;
case Subscript:
- subscript = other.subscript;
+ elementBase = other.elementBase;
+ elementSubscript = other.elementSubscript;
break;
case Const:
constant = other.constant;
@@ -2517,6 +2487,7 @@ Codegen::Reference &Codegen::Reference::operator =(const Reference &other)
break;
case QmlScopeObject:
case QmlContextObject:
+ qmlBase = other.qmlBase;
qmlCoreIndex = other.qmlCoreIndex;
qmlNotifyIndex = other.qmlNotifyIndex;
captureRequired = other.captureRequired;
@@ -2526,8 +2497,6 @@ Codegen::Reference &Codegen::Reference::operator =(const Reference &other)
}
// keep loaded reference
- temp = other.temp;
- needsWriteBack = false;
isArgOrEval = other.isArgOrEval;
codegen = other.codegen;
isReadonly = other.isReadonly;
@@ -2536,28 +2505,25 @@ Codegen::Reference &Codegen::Reference::operator =(const Reference &other)
return *this;
}
-Codegen::Reference::~Reference()
-{
- writeBack();
-}
-
bool Codegen::Reference::operator==(const Codegen::Reference &other) const
{
if (type != other.type)
return false;
switch (type) {
case Invalid:
+ case Accumulator:
break;
case Temporary:
+ return temporary == other.temporary;
case Local:
case Argument:
- return base == other.base;
+ return index == other.index && scope == other.scope;
case Name:
- return nameIndex == other.nameIndex;
+ return unqualifiedNameIndex == other.unqualifiedNameIndex;
case Member:
- return base == other.base && nameIndex == other.nameIndex;
+ return propertyBase == other.propertyBase && propertyNameIndex == other.propertyNameIndex;
case Subscript:
- return base == other.base && subscript == other.subscript;
+ return elementBase == other.elementBase && elementSubscript == other.elementSubscript;
case Const:
return constant == other.constant;
case Closure:
@@ -2572,108 +2538,94 @@ bool Codegen::Reference::operator==(const Codegen::Reference &other) const
return true;
}
-void Codegen::Reference::storeConsume(Reference &source) const
+Codegen::Reference Codegen::Reference::storeConsumeAccumulator() const
{
- if (!isTemp() && !source.isTemp()) {
- source.asRValue(); // trigger load
-
- Q_ASSERT(source.temp.index >= 0);
- temp = source.temp;
- source.temp.index = -1;
- needsWriteBack = true;
- return;
- }
-
- store(source);
+ storeAccumulator(); // it doesn't matter what happens here, just do it.
+ return Reference::fromAccumulator(codegen);
}
-void Codegen::Reference::store(const Reference &source) const
+Codegen::Reference Codegen::Reference::storeInTemp(int tempIndex) const
{
- Q_ASSERT(type != Const);
- Q_ASSERT(!needsWriteBack);
-
- if (*this == source)
- return;
-
+ if (isTemp() && tempIndex == -1)
+ return *this;
- if (isTemp()) {
- if (source.temp.index != -1) {
- Instruction::Move move;
- move.source = source.asRValue();
- move.result = asLValue();
- codegen->bytecodeGenerator->addInstruction(move);
- return;
- } else {
- source.load(base);
- }
- return;
+ if (isTemp()) { // temp-to-temp move
+ Reference dest = Reference::fromTemp(codegen, tempIndex);
+ Instruction::MoveReg move;
+ move.srcReg = temp();
+ move.destReg = dest.temp();
+ codegen->bytecodeGenerator->addInstruction(move);
+ return dest;
}
- if (temp.index < 0)
- temp.index = codegen->bytecodeGenerator->newTemp();
- if (!source.isTemp() && source.temp.index == -1) {
- source.load(temp);
- needsWriteBack = true;
- return;
+ Reference temp = Reference::fromTemp(codegen, tempIndex);
+ if (isConst()) {
+ Instruction::MoveConst move;
+ move.constIndex = codegen->registerConstant(constant);
+ move.destTemp = temp.temp();
+ codegen->bytecodeGenerator->addInstruction(move);
+ } else {
+ loadInAccumulator();
+ temp.storeConsumeAccumulator();
}
- needsWriteBack = true;
-
- Moth::Temp x = source.asRValue();
- Q_ASSERT(temp != x);
- Instruction::Move move;
- move.source = x;
- move.result = temp;
- codegen->bytecodeGenerator->addInstruction(move);
+ return temp;
}
-Moth::Temp Codegen::Reference::asRValue() const
+Codegen::Reference Codegen::Reference::storeRetainAccumulator() const
{
- Q_ASSERT(!needsWriteBack);
-
- Q_ASSERT(type != Invalid);
- if (isTemp())
- return base;
-
- // need a temp to hold the value
- if (temp.index == -1) {
- temp.index = codegen->bytecodeGenerator->newTemp();
- load(temp);
+ if (storeWipesAccumulator()) {
+ // a store will
+ auto tmp = Reference::fromTemp(codegen);
+ tmp.storeAccumulator(); // this is safe, and won't destory the accumulator
+ storeAccumulator();
+ return tmp;
+ } else {
+ // ok, this is safe, just do the store.
+ storeAccumulator();
+ return *this;
}
- return temp;
}
-Moth::Temp Codegen::Reference::asLValue() const
+bool Codegen::Reference::storeWipesAccumulator() const
{
- Q_ASSERT(type <= LastLValue);
-
- if (isTemp())
- return base;
-
- if (temp.index == -1)
- temp.index = codegen->bytecodeGenerator->newTemp();
- needsWriteBack = true;
- return temp;
+ switch (type) {
+ default:
+ case Invalid:
+ case This:
+ case Const:
+ case Accumulator:
+ Q_UNREACHABLE();
+ return false;
+ case Temporary:
+ case Local:
+ case Argument:
+ return false;
+ case Name:
+ case Member:
+ case Subscript:
+ case Closure:
+ case QmlScopeObject:
+ case QmlContextObject:
+ return true;
+ }
}
-void Codegen::Reference::writeBack() const
+void Codegen::Reference::storeAccumulator() const
{
- if (!needsWriteBack)
- return;
-
- Q_ASSERT(!isTemp());
- Q_ASSERT(temp.index >= 0);
- needsWriteBack = false;
-
switch (type) {
+ case Temporary: {
+ Instruction::StoreReg store;
+ store.reg = temporary;
+ codegen->bytecodeGenerator->addInstruction(store);
+ return;
+ }
case Local:
if (scope == 0) {
Instruction::StoreLocal store;
- store.source = temp;
store.index = index;
codegen->bytecodeGenerator->addInstruction(store);
} else {
Instruction::StoreScopedLocal store;
- store.source = temp;
store.index = index;
store.scope = scope;
codegen->bytecodeGenerator->addInstruction(store);
@@ -2682,12 +2634,10 @@ void Codegen::Reference::writeBack() const
case Argument:
if (scope == 0) {
Instruction::StoreArg store;
- store.source = temp;
store.index = index;
codegen->bytecodeGenerator->addInstruction(store);
} else {
Instruction::StoreScopedArg store;
- store.source = temp;
store.index = index;
store.scope = scope;
codegen->bytecodeGenerator->addInstruction(store);
@@ -2695,48 +2645,42 @@ void Codegen::Reference::writeBack() const
return;
case Name: {
Instruction::StoreName store;
- store.source = temp;
- store.name = nameIndex;
+ store.name = unqualifiedNameIndex;
codegen->bytecodeGenerator->addInstruction(store);
} return;
case Member:
if (codegen->useFastLookups) {
Instruction::SetLookup store;
- store.base = base;
- store.index = codegen->registerSetterLookup(nameIndex);
- store.source = temp;
+ store.base = propertyBase;
+ store.index = codegen->registerSetterLookup(propertyNameIndex);
codegen->bytecodeGenerator->addInstruction(store);
} else {
Instruction::StoreProperty store;
- store.base = base;
- store.name = nameIndex;
- store.source = temp;
+ store.base = propertyBase;
+ store.name = propertyNameIndex;
codegen->bytecodeGenerator->addInstruction(store);
}
return;
case Subscript: {
Instruction::StoreElement store;
- store.base = base;
- store.index = subscript;
- store.source = temp;
+ store.base = elementBase;
+ store.index = elementSubscript;
codegen->bytecodeGenerator->addInstruction(store);
} return;
case QmlScopeObject: {
Instruction::StoreScopeObjectProperty store;
- store.base = base;
+ store.base = qmlBase;
store.propertyIndex = qmlCoreIndex;
- store.source = temp;
codegen->bytecodeGenerator->addInstruction(store);
} return;
case QmlContextObject: {
Instruction::StoreContextObjectProperty store;
- store.base = base;
+ store.base = qmlBase;
store.propertyIndex = qmlCoreIndex;
- store.source = temp;
codegen->bytecodeGenerator->addInstruction(store);
} return;
case Invalid:
- case Temporary:
+ case Accumulator:
case Closure:
case Const:
case This:
@@ -2747,26 +2691,30 @@ void Codegen::Reference::writeBack() const
Q_UNREACHABLE();
}
-void Codegen::Reference::load(Moth::Temp dest) const
+void Codegen::Reference::loadInAccumulator() const
{
switch (type) {
+ case Accumulator:
+ return;
case Const: {
Instruction::LoadConst load;
load.index = codegen->registerConstant(constant);
- load.result = dest;
+ codegen->bytecodeGenerator->addInstruction(load);
+ } return;
+ case Temporary: {
+ Instruction::LoadReg load;
+ load.reg = temp();
codegen->bytecodeGenerator->addInstruction(load);
} return;
case Local:
if (scope == 0) {
Instruction::LoadLocal load;
load.index = index;
- load.result = dest;
codegen->bytecodeGenerator->addInstruction(load);
} else {
Instruction::LoadScopedLocal load;
load.index = index;
load.scope = scope;
- load.result = dest;
codegen->bytecodeGenerator->addInstruction(load);
}
return;
@@ -2774,62 +2722,53 @@ void Codegen::Reference::load(Moth::Temp dest) const
if (scope == 0) {
Instruction::LoadArg load;
load.index = index;
- load.result = dest;
codegen->bytecodeGenerator->addInstruction(load);
} else {
Instruction::LoadScopedArg load;
load.index = index;
load.scope = scope;
- load.result = dest;
codegen->bytecodeGenerator->addInstruction(load);
}
return;
case Name:
if (codegen->useFastLookups && global) {
Instruction::GetGlobalLookup load;
- load.index = codegen->registerGlobalGetterLookup(nameIndex);
- load.result = dest;
+ load.index = codegen->registerGlobalGetterLookup(unqualifiedNameIndex);
codegen->bytecodeGenerator->addInstruction(load);
} else {
Instruction::LoadName load;
- load.name = nameIndex;
- load.result = dest;
+ load.name = unqualifiedNameIndex;
codegen->bytecodeGenerator->addInstruction(load);
}
return;
case Member:
if (codegen->useFastLookups) {
Instruction::GetLookup load;
- load.base = base;
- load.index = codegen->registerGetterLookup(nameIndex);
- load.result = dest;
+ load.base = propertyBase;
+ load.index = codegen->registerGetterLookup(propertyNameIndex);
codegen->bytecodeGenerator->addInstruction(load);
} else {
Instruction::LoadProperty load;
- load.base = base;
- load.name = nameIndex;
- load.result = dest;
+ load.base = propertyBase;
+ load.name = propertyNameIndex;
codegen->bytecodeGenerator->addInstruction(load);
}
return;
case Subscript: {
Instruction::LoadElement load;
- load.base = base;
- load.index = subscript;
- load.result = dest;
+ load.base = elementBase;
+ load.index = elementSubscript;
codegen->bytecodeGenerator->addInstruction(load);
} return;
case Closure: {
Instruction::LoadClosure load;
load.value = closureId;
- load.result = dest;
codegen->bytecodeGenerator->addInstruction(load);
} return;
case QmlScopeObject: {
Instruction::LoadScopeObjectProperty load;
- load.base = base;
+ load.base = qmlBase;
load.propertyIndex = qmlCoreIndex;
- load.result = dest;
load.captureRequired = captureRequired;
codegen->bytecodeGenerator->addInstruction(load);
if (!captureRequired)
@@ -2837,9 +2776,8 @@ void Codegen::Reference::load(Moth::Temp dest) const
} return;
case QmlContextObject: {
Instruction::LoadContextObjectProperty load;
- load.base = base;
+ load.base = qmlBase;
load.propertyIndex = qmlCoreIndex;
- load.result = dest;
load.captureRequired = captureRequired;
codegen->bytecodeGenerator->addInstruction(load);
if (!captureRequired)
@@ -2847,15 +2785,8 @@ void Codegen::Reference::load(Moth::Temp dest) const
} return;
case This: {
Instruction::LoadThis load;
- load.result = dest;
codegen->bytecodeGenerator->addInstruction(load);
} return;
- case Temporary: {
- Instruction::Move move;
- move.source = base;
- move.result = dest;
- codegen->bytecodeGenerator->addInstruction(move);
- } return;
case Invalid:
break;
}
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index a5eb4d35f1..198a5e1ac8 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -106,6 +106,7 @@ public:
struct Reference {
enum Type {
Invalid,
+ Accumulator,
Temporary,
Local,
Argument,
@@ -128,21 +129,34 @@ public:
, codegen(nullptr)
{}
Reference(const Reference &other);
- ~Reference();
Reference &operator =(const Reference &other);
bool operator==(const Reference &other) const;
bool isValid() const { return type != Invalid; }
- bool isTempLocalArg() const { return isValid() && type < Argument; }
+ bool loadTriggersSideEffect() const {
+ switch (type) {
+ case Name:
+ case Member:
+ case Subscript:
+ return true;
+ default:
+ return false;
+ }
+ }
bool isConst() const { return type == Const; }
+ bool isAccumulator() const { return type == Accumulator; }
+ bool isTemp() const { return type == Temporary; }
+ static Reference fromAccumulator(Codegen *cg) {
+ return Reference(cg, Accumulator);
+ }
static Reference fromTemp(Codegen *cg, int tempIndex = -1, bool isLocal = false) {
Reference r(cg, Temporary);
if (tempIndex == -1)
tempIndex = cg->bytecodeGenerator->newTemp();
- r.base = Moth::Temp::create(tempIndex);
+ r.temporary = Moth::Temp::create(tempIndex);
r.tempIsLocal = isLocal;
return r;
}
@@ -160,19 +174,22 @@ public:
}
static Reference fromName(Codegen *cg, const QString &name) {
Reference r(cg, Name);
- r.nameIndex = cg->registerString(name);
+ r.unqualifiedNameIndex = cg->registerString(name);
return r;
}
static Reference fromMember(const Reference &baseRef, const QString &name) {
Reference r(baseRef.codegen, Member);
- r.base = baseRef.asRValue();
- r.nameIndex = r.codegen->registerString(name);
+ //### Add a case where the base can be in the accumulator?
+ r.propertyBase = baseRef.storeInTemp().temp();
+ r.propertyNameIndex = r.codegen->registerString(name);
return r;
}
static Reference fromSubscript(const Reference &baseRef, const Reference &subscript) {
+ Q_ASSERT(baseRef.isTemp());
Reference r(baseRef.codegen, Subscript);
- r.base = baseRef.asRValue();
- r.subscript = subscript.asRValue();
+ r.elementBase = baseRef.temp();
+ //### Add a case where the subscript can be in the accumulator?
+ r.elementSubscript = subscript.storeInTemp().temp();
return r;
}
static Reference fromConst(Codegen *cg, QV4::ReturnedValue constant) {
@@ -188,7 +205,7 @@ public:
}
static Reference fromQmlScopeObject(const Reference &base, qint16 coreIndex, qint16 notifyIndex, bool captureRequired) {
Reference r(base.codegen, QmlScopeObject);
- r.base = base.asRValue();
+ r.qmlBase = base.storeInTemp().temp();
r.qmlCoreIndex = coreIndex;
r.qmlNotifyIndex = notifyIndex;
r.captureRequired = captureRequired;
@@ -196,7 +213,7 @@ public:
}
static Reference fromQmlContextObject(const Reference &base, qint16 coreIndex, qint16 notifyIndex, bool captureRequired) {
Reference r(base.codegen, QmlContextObject);
- r.base = base.asRValue();
+ r.qmlBase = base.storeInTemp().temp();
r.qmlCoreIndex = coreIndex;
r.qmlNotifyIndex = notifyIndex;
r.captureRequired = captureRequired;
@@ -220,43 +237,53 @@ public:
}
}
- bool isTemp() const {
- return type == Temporary;
- }
-
- void store(const Reference &source) const;
- void storeConsume(Reference &source) const;
+ static Reference storeConstInTemp(Codegen *cg, QV4::ReturnedValue constant, int tempIndex)
+ { return Reference::fromConst(cg, constant).storeInTemp(tempIndex); }
+ Q_REQUIRED_RESULT Reference storeInTemp(int tempIndex = -1) const;
+ Q_REQUIRED_RESULT Reference storeRetainAccumulator() const;
+ Reference storeConsumeAccumulator() const;
- Moth::Temp asRValue() const;
- Moth::Temp asLValue() const;
+ bool storeWipesAccumulator() const;
+ void loadInAccumulator() const;
- void writeBack() const;
- void load(Moth::Temp dest) const;
+ Moth::Temp temp() const {
+ if (Q_UNLIKELY(!isTemp()))
+ Q_UNREACHABLE();
+ return temporary;
+ }
- Moth::Temp base;
union {
+ Moth::Temp temporary;
QV4::ReturnedValue constant;
+ int unqualifiedNameIndex;
struct { // Argument/Local
int index;
int scope;
};
- uint nameIndex;
- Moth::Temp subscript;
+ struct {
+ Moth::Temp propertyBase;
+ int propertyNameIndex;
+ };
+ struct {
+ Moth::Temp elementBase;
+ Moth::Temp elementSubscript;
+ };
int closureId;
struct { // QML scope/context object case
+ Moth::Temp qmlBase;
qint16 qmlCoreIndex;
qint16 qmlNotifyIndex;
bool captureRequired;
};
};
- mutable Moth::Temp temp = Moth::Temp::create(-1);
- mutable bool needsWriteBack = false;
mutable bool isArgOrEval = false;
bool isReadonly = false;
bool tempIsLocal = false;
bool global = false;
Codegen *codegen;
+ private:
+ void storeAccumulator() const;
};
struct TempScope {
@@ -524,8 +551,7 @@ public:
QList<QQmlError> qmlErrors() const;
#endif
- Moth::Temp binopHelper(QSOperator::Op oper, Reference &left, Reference &right,
- const Reference &dest);
+ Reference binopHelper(QSOperator::Op oper, Reference &left, Reference &right);
Moth::Temp pushArgs(AST::ArgumentList *args);
void setUseFastLookups(bool b) { useFastLookups = b; }
diff --git a/src/qml/compiler/qv4compilercontrolflow_p.h b/src/qml/compiler/qv4compilercontrolflow_p.h
index ba0c4751c9..76063bc214 100644
--- a/src/qml/compiler/qv4compilercontrolflow_p.h
+++ b/src/qml/compiler/qv4compilercontrolflow_p.h
@@ -104,11 +104,8 @@ struct ControlFlow {
}
void jumpToHandler(const Handler &h) {
- if (h.tempIndex >= 0) {
- Reference val = Reference::fromConst(cg, QV4::Encode(h.value));
- Reference temp = Reference::fromTemp(cg, h.tempIndex);
- temp.store(val);
- }
+ if (h.tempIndex >= 0)
+ Reference::storeConstInTemp(cg, QV4::Encode(h.value), h.tempIndex);
cg->bytecodeGenerator->jump().link(h.linkLabel);
}
@@ -147,14 +144,14 @@ struct ControlFlow {
}
virtual void handleThrow(const Reference &expr) {
+ Reference e = expr;
Handler h = getHandler(ControlFlow::Throw);
if (h.tempIndex >= 0) {
- Reference val = Reference::fromConst(cg, QV4::Encode(h.value));
- Reference temp = Reference::fromTemp(cg, h.tempIndex);
- temp.store(val);
+ e = e.storeInTemp();
+ Reference::storeConstInTemp(cg, QV4::Encode(h.value), h.tempIndex);
}
+ e.loadInAccumulator();
Instruction::CallBuiltinThrow instr;
- instr.arg = expr.asRValue();
generator()->addInstruction(instr);
}
@@ -218,7 +215,7 @@ struct ControlFlowUnwind : public ControlFlow
{
Q_ASSERT(type != Loop);
controlFlowTemp = static_cast<int>(generator()->newTemp());
- Reference::fromTemp(cg, controlFlowTemp).store(Reference::fromConst(cg, QV4::Encode::undefined()));
+ Reference::storeConstInTemp(cg, QV4::Encode::undefined(), controlFlowTemp);
// we'll need at least a handler for throw
getHandler(Throw);
}
@@ -232,20 +229,18 @@ struct ControlFlowUnwind : public ControlFlow
Codegen::TempScope tempScope(cg);
Handler parentHandler = getParentHandler(h.type, h.label);
-
if (h.type == Throw || parentHandler.tempIndex >= 0) {
BytecodeGenerator::Label skip = generator()->newLabel();
- generator()->jumpStrictNotEqual(temp.asRValue(), Reference::fromConst(cg, QV4::Encode(h.value)).asRValue())
- .link(skip);
+ Reference::fromConst(cg, QV4::Encode(h.value)).loadInAccumulator();
+ generator()->jumpStrictNotEqual(temp.temp()).link(skip);
if (h.type == Throw)
emitForThrowHandling();
- Reference parentTemp = Reference::fromTemp(cg, parentHandler.tempIndex);
- parentTemp.store(Reference::fromConst(cg, QV4::Encode(parentHandler.value)));
+ Reference::storeConstInTemp(cg, QV4::Encode(parentHandler.value), parentHandler.tempIndex);
generator()->jump().link(parentHandler.linkLabel);
skip.link();
} else {
- generator()->jumpStrictEqual(temp.asRValue(), Reference::fromConst(cg, QV4::Encode(h.value)).asRValue())
- .link(parentHandler.linkLabel);
+ Reference::fromConst(cg, QV4::Encode(h.value)).loadInAccumulator();
+ generator()->jumpStrictEqual(temp.temp()).link(parentHandler.linkLabel);
}
}
}
@@ -339,10 +334,10 @@ struct ControlFlowCatch : public ControlFlowUnwind
exceptionLabel.link();
Reference name = Reference::fromName(cg, catchExpression->name.toString());
Instruction::CallBuiltinPushCatchScope pushCatchScope;
- pushCatchScope.name = name.nameIndex;
+ pushCatchScope.name = name.unqualifiedNameIndex;
generator()->addInstruction(pushCatchScope);
// clear the unwind temp for exceptions, we want to resume normal code flow afterwards
- Reference::fromTemp(cg, controlFlowTemp).store(Reference::fromConst(cg, QV4::Encode::undefined()));
+ Reference::storeConstInTemp(cg, QV4::Encode::undefined(), controlFlowTemp);
generator()->setExceptionHandler(&catchUnwindLabel);
cg->statement(catchExpression->statement);
@@ -396,10 +391,9 @@ struct ControlFlowFinally : public ControlFlowUnwind
insideFinally = true;
exceptionTemp = generator()->newTemp();
- Reference exception = Reference::fromTemp(cg, exceptionTemp);
Instruction::GetException instr;
- instr.result = exception.asLValue();
generator()->addInstruction(instr);
+ Reference::fromTemp(cg, exceptionTemp).storeConsumeAccumulator();
generator()->setExceptionHandler(parentExceptionHandler());
cg->statement(finally->statement);
@@ -410,9 +404,9 @@ struct ControlFlowFinally : public ControlFlowUnwind
virtual void emitForThrowHandling() {
// reset the exception flag, that got cleared before executing the statements in finally
+ Reference::fromTemp(cg, exceptionTemp).loadInAccumulator();
Instruction::SetException setException;
Q_ASSERT(exceptionTemp != -1);
- setException.exception = Reference::fromTemp(cg, exceptionTemp).asRValue();
generator()->addInstruction(setException);
}
};
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 3d1470da76..6a7fce577b 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -122,120 +122,132 @@ void dumpBytecode(const char *code, int len)
const Instr *genericInstr = reinterpret_cast<const Instr *>(code);
switch (genericInstr->common.instructionType) {
+ MOTH_BEGIN_INSTR(LoadReg)
+ d << instr.reg;
+ MOTH_END_INSTR(LoadReg)
+
+ MOTH_BEGIN_INSTR(StoreReg)
+ d << instr.reg;
+ MOTH_END_INSTR(StoreReg)
+
+ MOTH_BEGIN_INSTR(MoveReg)
+ d << instr.destReg << ", " << instr.srcReg;
+ MOTH_END_INSTR(MoveReg)
+
MOTH_BEGIN_INSTR(LoadConst)
- d << instr.result << ", " << "C" << instr.index;
+ d << "C" << instr.index;
MOTH_END_INSTR(LoadConst)
+ MOTH_BEGIN_INSTR(MoveConst)
+ d << instr.destTemp << ", C" << instr.constIndex;
+ MOTH_END_INSTR(MoveConst)
+
MOTH_BEGIN_INSTR(LoadLocal)
- d << instr.result << ", " << "$" << instr.index;
+ d << "$" << instr.index;
MOTH_END_INSTR(LoadLocal)
MOTH_BEGIN_INSTR(StoreLocal)
- d << "$" << instr.index << ", " << instr.source;
+ d << "$" << instr.index;
MOTH_END_INSTR(StoreLocal)
MOTH_BEGIN_INSTR(LoadArg)
- d << instr.result << ", " << "#" << instr.index;
+ d << "#" << instr.index;
MOTH_END_INSTR(LoadArg)
MOTH_BEGIN_INSTR(StoreArg)
- d << "#" << instr.index << ", " << instr.source;
+ d << "#" << instr.index;
MOTH_END_INSTR(StoreArg)
MOTH_BEGIN_INSTR(LoadScopedLocal)
- d << instr.result << ", " << "$" << instr.index << "@" << instr.scope;
+ d << "$" << instr.index << "@" << instr.scope;
MOTH_END_INSTR(LoadScopedLocal)
MOTH_BEGIN_INSTR(StoreScopedLocal)
- d << ", " << "$" << instr.index << "@" << instr.scope << ", " << instr.source;
+ d << ", " << "$" << instr.index << "@" << instr.scope;
MOTH_END_INSTR(StoreScopedLocal)
MOTH_BEGIN_INSTR(LoadScopedArg)
- d << instr.result << ", " << "#" << instr.index << "@" << instr.scope;
+ d << "#" << instr.index << "@" << instr.scope;
MOTH_END_INSTR(LoadScopedArg)
MOTH_BEGIN_INSTR(StoreScopedArg)
- d << "#" << instr.index << "@" << instr.scope << ", " << instr.source;
+ d << "#" << instr.index << "@" << instr.scope;
MOTH_END_INSTR(StoreScopedArg)
- MOTH_BEGIN_INSTR(Move)
- d << instr.result << ", " << instr.source;
- MOTH_END_INSTR(Move)
-
MOTH_BEGIN_INSTR(LoadRuntimeString)
- d << instr.result << ", " << instr.stringId;
+ d << instr.stringId;
MOTH_END_INSTR(LoadRuntimeString)
MOTH_BEGIN_INSTR(LoadRegExp)
- d << instr.result << ", " << instr.regExpId;
+ d << instr.regExpId;
MOTH_END_INSTR(LoadRegExp)
MOTH_BEGIN_INSTR(LoadClosure)
- d << instr.result << ", " << instr.value;
+ d << instr.value;
MOTH_END_INSTR(LoadClosure)
MOTH_BEGIN_INSTR(LoadName)
- d << instr.result << ", " << instr.name;
+ d << instr.name;
MOTH_END_INSTR(LoadName)
MOTH_BEGIN_INSTR(GetGlobalLookup)
- d << instr.result << ", " << instr.index;
+ d << instr.index;
MOTH_END_INSTR(GetGlobalLookup)
MOTH_BEGIN_INSTR(StoreName)
- d << instr.name << ", " << instr.source;
+ d << instr.name;
MOTH_END_INSTR(StoreName)
MOTH_BEGIN_INSTR(LoadElement)
- d << instr.result << ", " << instr.base << "[" << instr.index << "]";
+ d << instr.base << "[" << instr.index << "]";
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(LoadElementLookup)
- d << instr.result << ", " << instr.base << "[" << instr.index << "]";
+ d << instr.base << "[" << instr.index << "]";
MOTH_END_INSTR(LoadElementLookup)
MOTH_BEGIN_INSTR(StoreElement)
- d << instr.base << "[" << instr.index << "]" << ", " << instr.source;
+ d << instr.base << "[" << instr.index << "]";
MOTH_END_INSTR(StoreElement)
MOTH_BEGIN_INSTR(StoreElementLookup)
- d << instr.base << "[" << instr.index << "]" << ", " << instr.source;
+ d << instr.base << "[" << instr.index << "]";
MOTH_END_INSTR(StoreElementLookup)
MOTH_BEGIN_INSTR(LoadProperty)
- d << instr.result << ", " << instr.base << "[" << instr.name << "]";
+ d << instr.base << "[" << instr.name << "]";
MOTH_END_INSTR(LoadProperty)
MOTH_BEGIN_INSTR(GetLookup)
- d << instr.result << ", " << instr.base << "(" << instr.index << ")";
+ d << instr.base << "(" << instr.index << ")";
MOTH_END_INSTR(GetLookup)
MOTH_BEGIN_INSTR(StoreProperty)
- d << instr.base << "[" << instr.name<< "]" << ", " << instr.source;
+ d << instr.base << "[" << instr.name<< "]";
MOTH_END_INSTR(StoreProperty)
MOTH_BEGIN_INSTR(SetLookup)
- d << instr.base << ", " << instr.source;
+ d << instr.base;
MOTH_END_INSTR(SetLookup)
MOTH_BEGIN_INSTR(StoreScopeObjectProperty)
- d << instr.base << "[" << instr.propertyIndex << "]" << ", " << instr.source;
+ d << instr.base << "[" << instr.propertyIndex << "]";
MOTH_END_INSTR(StoreScopeObjectProperty)
MOTH_BEGIN_INSTR(LoadScopeObjectProperty)
- d << instr.result << ", " << instr.base << "[" << instr.propertyIndex << "]";
+ d << instr.base << "[" << instr.propertyIndex << "]";
MOTH_END_INSTR(LoadScopeObjectProperty)
MOTH_BEGIN_INSTR(StoreContextObjectProperty)
- d << instr.base << "[" << instr.propertyIndex << "]" << ", " << instr.source;
+ d << instr.base << "[" << instr.propertyIndex << "]";
MOTH_END_INSTR(StoreContextObjectProperty)
MOTH_BEGIN_INSTR(LoadContextObjectProperty)
- d << instr.result << ", " << instr.base << "[" << instr.propertyIndex << "]";
+ d << instr.base << "[" << instr.propertyIndex << "]";
MOTH_END_INSTR(LoadContextObjectProperty)
MOTH_BEGIN_INSTR(LoadIdObject)
- d << instr.result << ", " << instr.base << "[" << instr.index << "]";
+ d << instr.base << "[" << instr.index << "]";
MOTH_END_INSTR(LoadIdObject)
MOTH_BEGIN_INSTR(InitStackFrame)
@@ -243,27 +255,27 @@ void dumpBytecode(const char *code, int len)
MOTH_END_INSTR(InitStackFrame)
MOTH_BEGIN_INSTR(CallValue)
- d << instr.result << ", " << instr.dest << "(" << instr.callData << ")";
+ d << instr.dest << "(" << instr.callData << ")";
MOTH_END_INSTR(CallValue)
MOTH_BEGIN_INSTR(CallProperty)
- d << instr.result << ", " << instr.base<<"."<<instr.name << "(" << instr.callData << ")";
+ d << instr.base<<"."<<instr.name << "(" << instr.callData << ")";
MOTH_END_INSTR(CallProperty)
MOTH_BEGIN_INSTR(CallPropertyLookup)
- d << instr.result << ", " << instr.lookupIndex << "(" << instr.callData << ")";
+ d << instr.lookupIndex << "(" << instr.callData << ")";
MOTH_END_INSTR(CallPropertyLookup)
MOTH_BEGIN_INSTR(CallElement)
- d << instr.result << ", " << instr.base << "[" << instr.index << "]" << "(" << instr.callData << ")";
+ d << instr.base << "[" << instr.index << "]" << "(" << instr.callData << ")";
MOTH_END_INSTR(CallElement)
MOTH_BEGIN_INSTR(CallActivationProperty)
- d << instr.result << ", " << instr.name << "(" << instr.callData << ")";
+ d << instr.name << "(" << instr.callData << ")";
MOTH_END_INSTR(CallActivationProperty)
MOTH_BEGIN_INSTR(CallGlobalLookup)
- d << instr.result << ", " << instr.index << "(" << instr.callData << ")";
+ d << instr.index << "(" << instr.callData << ")";
MOTH_END_INSTR(CallGlobalLookup)
MOTH_BEGIN_INSTR(SetExceptionHandler)
@@ -274,19 +286,15 @@ void dumpBytecode(const char *code, int len)
MOTH_END_INSTR(SetExceptionHandler)
MOTH_BEGIN_INSTR(CallBuiltinThrow)
- d << instr.arg;
MOTH_END_INSTR(CallBuiltinThrow)
MOTH_BEGIN_INSTR(GetException)
- d << instr.result;
MOTH_END_INSTR(HasException)
MOTH_BEGIN_INSTR(SetException)
- d << instr.exception;
MOTH_END_INSTR(SetExceptionFlag)
MOTH_BEGIN_INSTR(CallBuiltinUnwindException)
- d << instr.result;
MOTH_END_INSTR(CallBuiltinUnwindException)
MOTH_BEGIN_INSTR(CallBuiltinPushCatchScope)
@@ -294,38 +302,34 @@ void dumpBytecode(const char *code, int len)
MOTH_END_INSTR(CallBuiltinPushCatchScope)
MOTH_BEGIN_INSTR(CallBuiltinPushScope)
- d << instr.arg;
MOTH_END_INSTR(CallBuiltinPushScope)
MOTH_BEGIN_INSTR(CallBuiltinPopScope)
MOTH_END_INSTR(CallBuiltinPopScope)
MOTH_BEGIN_INSTR(CallBuiltinForeachIteratorObject)
- d << instr.result;
MOTH_END_INSTR(CallBuiltinForeachIteratorObject)
MOTH_BEGIN_INSTR(CallBuiltinForeachNextPropertyName)
- d << instr.result << ", " << instr.arg;
MOTH_END_INSTR(CallBuiltinForeachNextPropertyName)
MOTH_BEGIN_INSTR(CallBuiltinDeleteMember)
- d << instr.result << ", " << instr.base << "[" << instr.member << "]";
+ d << instr.base << "[" << instr.member << "]";
MOTH_END_INSTR(CallBuiltinDeleteMember)
MOTH_BEGIN_INSTR(CallBuiltinDeleteSubscript)
- d << instr.result << ", " << instr.base << "[" << instr.index << "]";
+ d << instr.base << "[" << instr.index << "]";
MOTH_END_INSTR(CallBuiltinDeleteSubscript)
MOTH_BEGIN_INSTR(CallBuiltinDeleteName)
- d << instr.result << ", " << instr.name;
+ d << instr.name;
MOTH_END_INSTR(CallBuiltinDeleteName)
MOTH_BEGIN_INSTR(CallBuiltinTypeofName)
- d << instr.result << ", " << instr.name;
+ d << instr.name;
MOTH_END_INSTR(CallBuiltinTypeofName)
MOTH_BEGIN_INSTR(CallBuiltinTypeofValue)
- d << instr.result << ", " << instr.value;
MOTH_END_INSTR(CallBuiltinTypeofValue)
MOTH_BEGIN_INSTR(CallBuiltinDeclareVar)
@@ -333,41 +337,40 @@ void dumpBytecode(const char *code, int len)
MOTH_END_INSTR(CallBuiltinDeclareVar)
MOTH_BEGIN_INSTR(CallBuiltinDefineArray)
- d << instr.result << ", " << instr.args << ", " << instr.argc;
+ d << instr.args << ", " << instr.argc;
MOTH_END_INSTR(CallBuiltinDefineArray)
MOTH_BEGIN_INSTR(CallBuiltinDefineObjectLiteral)
- d << instr.result << ", " << instr.args
+ d << instr.args
<< ", " << instr.internalClassId
<< ", " << instr.arrayValueCount
<< ", " << instr.arrayGetterSetterCountAndFlags;
MOTH_END_INSTR(CallBuiltinDefineObjectLiteral)
MOTH_BEGIN_INSTR(CallBuiltinSetupArgumentsObject)
- d << instr.result;
MOTH_END_INSTR(CallBuiltinSetupArgumentsObject)
MOTH_BEGIN_INSTR(CallBuiltinConvertThisToObject)
MOTH_END_INSTR(CallBuiltinConvertThisToObject)
MOTH_BEGIN_INSTR(CreateValue)
- d << instr.result << ", new" << instr.func << "(" << instr.callData << ")";
+ d << "new" << instr.func << "(" << instr.callData << ")";
MOTH_END_INSTR(CreateValue)
MOTH_BEGIN_INSTR(CreateProperty)
- d << instr.result << ", new" << instr.name << "(" << instr.callData << instr.argc << ")";
+ d << "new" << instr.name << "(" << instr.callData << instr.argc << ")";
MOTH_END_INSTR(CreateProperty)
MOTH_BEGIN_INSTR(ConstructPropertyLookup)
- d << instr.result << ", new" << instr.index << "(" << instr.callData << instr.argc << ")";
+ d << "new" << instr.index << "(" << instr.callData << instr.argc << ")";
MOTH_END_INSTR(ConstructPropertyLookup)
MOTH_BEGIN_INSTR(CreateActivationProperty)
- d << instr.result << ", new" << instr.name << "(" << instr.callData << instr.argc << ")";
+ d << "new" << instr.name << "(" << instr.callData << instr.argc << ")";
MOTH_END_INSTR(CreateActivationProperty)
MOTH_BEGIN_INSTR(ConstructGlobalLookup)
- d << instr.result << ", new" << instr.index << "(" << instr.callData << instr.argc << ")";
+ d << "new" << instr.index << "(" << instr.callData << instr.argc << ")";
MOTH_END_INSTR(ConstructGlobalLookup)
MOTH_BEGIN_INSTR(Jump)
@@ -375,119 +378,103 @@ void dumpBytecode(const char *code, int len)
MOTH_END_INSTR(Jump)
MOTH_BEGIN_INSTR(JumpEq)
- d << instr.condition << " " << absoluteInstructionOffset(start, instr);
+ d << "acc " << absoluteInstructionOffset(start, instr);
MOTH_END_INSTR(JumpEq)
MOTH_BEGIN_INSTR(JumpNe)
- d << instr.condition << " " << absoluteInstructionOffset(start, instr);
+ d << "acc " << absoluteInstructionOffset(start, instr);
MOTH_END_INSTR(JumpNe)
MOTH_BEGIN_INSTR(JumpStrictEqual)
- d << instr.lhs<< ", " << instr.rhs << " " << absoluteInstructionOffset(start, instr);
+ d << instr.lhs << " " << absoluteInstructionOffset(start, instr);
MOTH_END_INSTR(JumpStrictEqual)
MOTH_BEGIN_INSTR(JumpStrictNotEqual)
- d << instr.lhs<< ", " << instr.rhs << " " << absoluteInstructionOffset(start, instr);
+ d << instr.lhs << " " << absoluteInstructionOffset(start, instr);
MOTH_END_INSTR(JumpStrictNotEqual)
MOTH_BEGIN_INSTR(UNot)
- d << instr.result << ", " << instr.source;
MOTH_END_INSTR(UNot)
MOTH_BEGIN_INSTR(UNotBool)
- d << instr.result << ", " << instr.source;
MOTH_END_INSTR(UNotBool)
MOTH_BEGIN_INSTR(UPlus)
- d << instr.result << ", " << instr.source;
MOTH_END_INSTR(UPlus)
MOTH_BEGIN_INSTR(UMinus)
- d << instr.result << ", " << instr.source;
MOTH_END_INSTR(UMinus)
MOTH_BEGIN_INSTR(UCompl)
- d << instr.result << ", " << instr.source;
MOTH_END_INSTR(UCompl)
MOTH_BEGIN_INSTR(UComplInt)
- d << instr.result << ", " << instr.source;
MOTH_END_INSTR(UComplInt)
- MOTH_BEGIN_INSTR(PreIncrement)
- d << instr.result << ", " << instr.source;
+ MOTH_BEGIN_INSTR(Increment)
MOTH_END_INSTR(PreIncrement)
- MOTH_BEGIN_INSTR(PreDecrement)
- d << instr.result << ", " << instr.source;
+ MOTH_BEGIN_INSTR(Decrement)
MOTH_END_INSTR(PreDecrement)
- MOTH_BEGIN_INSTR(PostIncrement)
- d << instr.result << ", " << instr.source;
- MOTH_END_INSTR(PostIncrement)
-
- MOTH_BEGIN_INSTR(PostDecrement)
- d << instr.result << ", " << instr.source;
- MOTH_END_INSTR(PostDecrement)
-
MOTH_BEGIN_INSTR(Binop)
- d << instr.alu << ", " << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << instr.alu << ", " << instr.lhs << ", acc";
MOTH_END_INSTR(Binop)
MOTH_BEGIN_INSTR(Add)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << instr.lhs;
MOTH_END_INSTR(Add)
MOTH_BEGIN_INSTR(BitAnd)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << instr.lhs << ", acc";
MOTH_END_INSTR(BitAnd)
MOTH_BEGIN_INSTR(BitOr)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << instr.lhs << ", acc";
MOTH_END_INSTR(BitOr)
MOTH_BEGIN_INSTR(BitXor)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << instr.lhs << ", acc";
MOTH_END_INSTR(BitXor)
MOTH_BEGIN_INSTR(Shr)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << instr.lhs << ", acc";
MOTH_END_INSTR(Shr)
MOTH_BEGIN_INSTR(Shl)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << instr.lhs << ", acc";
MOTH_END_INSTR(Shl)
MOTH_BEGIN_INSTR(BitAndConst)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
- MOTH_END_INSTR(BitAnd)
+ d << "acc, " << instr.rhs;
+ MOTH_END_INSTR(BitAndConst)
MOTH_BEGIN_INSTR(BitOrConst)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << "acc, " << instr.rhs;
MOTH_END_INSTR(BitOr)
MOTH_BEGIN_INSTR(BitXorConst)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << "acc, " << instr.rhs;
MOTH_END_INSTR(BitXor)
MOTH_BEGIN_INSTR(ShrConst)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << "acc, " << instr.rhs;
MOTH_END_INSTR(ShrConst)
MOTH_BEGIN_INSTR(ShlConst)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << "acc, " << instr.rhs;
MOTH_END_INSTR(ShlConst)
MOTH_BEGIN_INSTR(Mul)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << instr.lhs << ", acc";
MOTH_END_INSTR(Mul)
MOTH_BEGIN_INSTR(Sub)
- d << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << instr.lhs << ", acc";
MOTH_END_INSTR(Sub)
MOTH_BEGIN_INSTR(BinopContext)
- d << instr.alu << instr.result << ", " << instr.lhs << ", " << instr.rhs;
+ d << instr.alu << " " << instr.lhs << ", acc";
MOTH_END_INSTR(BinopContext)
MOTH_BEGIN_INSTR(Ret)
@@ -504,19 +491,18 @@ void dumpBytecode(const char *code, int len)
#endif // QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(LoadThis)
- d << instr.result;
MOTH_END_INSTR(LoadThis)
MOTH_BEGIN_INSTR(LoadQmlContext)
- d << instr.result;
+ d << instr.result;
MOTH_END_INSTR(LoadQmlContext)
MOTH_BEGIN_INSTR(LoadQmlImportedScripts)
- d << instr.result;
+ d << instr.result;
MOTH_END_INSTR(LoadQmlImportedScripts)
MOTH_BEGIN_INSTR(LoadQmlSingleton)
- d << instr.result << instr.name;
+ d << instr.name;
MOTH_END_INSTR(LoadQmlSingleton)
default:
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 82ba1d2ff0..b0bcb41de7 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -72,6 +72,10 @@ QT_BEGIN_NAMESPACE
F(Ret, ret) \
MOTH_DEBUG_INSTR(F) \
F(LoadConst, loadConst) \
+ F(MoveConst, moveConst) \
+ F(LoadReg, loadReg) \
+ F(StoreReg, storeReg) \
+ F(MoveReg, moveReg) \
F(LoadLocal, loadLocal) \
F(StoreLocal, storeLocal) \
F(LoadArg, loadArg) \
@@ -83,7 +87,6 @@ QT_BEGIN_NAMESPACE
F(LoadRuntimeString, loadRuntimeString) \
F(LoadRegExp, loadRegExp) \
F(LoadClosure, loadClosure) \
- F(Move, move) \
F(LoadName, loadName) \
F(GetGlobalLookup, getGlobalLookup) \
F(StoreName, storeName) \
@@ -143,10 +146,8 @@ QT_BEGIN_NAMESPACE
F(UMinus, uminus) \
F(UCompl, ucompl) \
F(UComplInt, ucomplInt) \
- F(PreIncrement, preIncrement) \
- F(PreDecrement, preDecrement) \
- F(PostIncrement, postIncrement) \
- F(PostDecrement, postDecrement) \
+ F(Increment, increment) \
+ F(Decrement, decrement) \
F(Binop, binop) \
F(Add, add) \
F(BitAnd, bitAnd) \
@@ -232,168 +233,153 @@ union Instr
struct instr_loadConst {
MOTH_INSTR_HEADER
int index;
- Temp result;
+ };
+ struct instr_moveConst {
+ MOTH_INSTR_HEADER
+ int constIndex;
+ Temp destTemp;
+ };
+ struct instr_loadReg {
+ MOTH_INSTR_HEADER
+ Temp reg;
+ };
+ struct instr_storeReg {
+ MOTH_INSTR_HEADER
+ Temp reg;
+ };
+ struct instr_moveReg {
+ MOTH_INSTR_HEADER
+ Temp srcReg;
+ Temp destReg;
};
struct instr_loadLocal {
MOTH_INSTR_HEADER
int index;
- Temp result;
};
struct instr_storeLocal {
MOTH_INSTR_HEADER
int index;
- Temp source;
};
struct instr_loadArg {
MOTH_INSTR_HEADER
int index;
- Temp result;
};
struct instr_storeArg {
MOTH_INSTR_HEADER
int index;
- Temp source;
};
struct instr_loadScopedLocal {
MOTH_INSTR_HEADER
unsigned scope : 12;
unsigned index : 20;
- Temp result;
};
struct instr_storeScopedLocal {
MOTH_INSTR_HEADER
unsigned scope : 12;
unsigned index : 20;
- Temp source;
};
struct instr_loadScopedArg {
MOTH_INSTR_HEADER
unsigned scope : 12;
unsigned index : 20;
- Temp result;
};
struct instr_storeScopedArg {
MOTH_INSTR_HEADER
unsigned scope : 12;
unsigned index : 20;
- Temp source;
};
struct instr_loadRuntimeString {
MOTH_INSTR_HEADER
int stringId;
- Temp result;
};
struct instr_loadRegExp {
MOTH_INSTR_HEADER
int regExpId;
- Temp result;
- };
- struct instr_move {
- MOTH_INSTR_HEADER
- Temp source;
- Temp result;
};
struct instr_loadClosure {
MOTH_INSTR_HEADER
int value;
- Temp result;
};
struct instr_loadName {
MOTH_INSTR_HEADER
int name;
- Temp result;
};
struct instr_getGlobalLookup {
MOTH_INSTR_HEADER
int index;
- Temp result;
};
struct instr_storeName {
MOTH_INSTR_HEADER
int name;
- Temp source;
};
struct instr_loadProperty {
MOTH_INSTR_HEADER
int name;
Temp base;
- Temp result;
};
struct instr_getLookup {
MOTH_INSTR_HEADER
int index;
Temp base;
- Temp result;
};
struct instr_loadScopeObjectProperty {
MOTH_INSTR_HEADER
int propertyIndex;
Temp base;
- Temp result;
bool captureRequired;
};
struct instr_loadContextObjectProperty {
MOTH_INSTR_HEADER
int propertyIndex;
Temp base;
- Temp result;
bool captureRequired;
};
struct instr_loadIdObject {
MOTH_INSTR_HEADER
int index;
Temp base;
- Temp result;
};
struct instr_storeProperty {
MOTH_INSTR_HEADER
int name;
Temp base;
- Temp source;
};
struct instr_setLookup {
MOTH_INSTR_HEADER
int index;
Temp base;
- Temp source;
};
struct instr_storeScopeObjectProperty {
MOTH_INSTR_HEADER
Temp base;
int propertyIndex;
- Temp source;
};
struct instr_storeContextObjectProperty {
MOTH_INSTR_HEADER
Temp base;
int propertyIndex;
- Temp source;
};
struct instr_loadElement {
MOTH_INSTR_HEADER
Temp base;
Temp index;
- Temp result;
};
struct instr_loadElementLookup {
MOTH_INSTR_HEADER
uint lookup;
Temp base;
Temp index;
- Temp result;
};
struct instr_storeElement {
MOTH_INSTR_HEADER
Temp base;
Temp index;
- Temp source;
};
struct instr_storeElementLookup {
MOTH_INSTR_HEADER
uint lookup;
Temp base;
Temp index;
- Temp source;
};
struct instr_initStackFrame {
MOTH_INSTR_HEADER
@@ -403,14 +389,12 @@ union Instr
MOTH_INSTR_HEADER
Temp callData;
Temp dest;
- Temp result;
};
struct instr_callProperty {
MOTH_INSTR_HEADER
int name;
Temp callData;
Temp base;
- Temp result;
};
struct instr_callPropertyLookup {
MOTH_INSTR_HEADER
@@ -418,26 +402,22 @@ union Instr
int argc;
Temp callData;
Temp base;
- Temp result;
};
struct instr_callElement {
MOTH_INSTR_HEADER
Temp base;
Temp index;
Temp callData;
- Temp result;
};
struct instr_callActivationProperty {
MOTH_INSTR_HEADER
int name;
Temp callData;
- Temp result;
};
struct instr_callGlobalLookup {
MOTH_INSTR_HEADER
int index;
Temp callData;
- Temp result;
};
struct instr_setExceptionHandler {
MOTH_INSTR_HEADER
@@ -445,19 +425,15 @@ union Instr
};
struct instr_callBuiltinThrow {
MOTH_INSTR_HEADER
- Temp arg;
};
struct instr_getException {
MOTH_INSTR_HEADER
- Temp result;
};
struct instr_setException {
MOTH_INSTR_HEADER
- Temp exception;
};
struct instr_callBuiltinUnwindException {
MOTH_INSTR_HEADER
- Temp result;
};
struct instr_callBuiltinPushCatchScope {
MOTH_INSTR_HEADER
@@ -465,47 +441,36 @@ union Instr
};
struct instr_callBuiltinPushScope {
MOTH_INSTR_HEADER
- Temp arg;
};
struct instr_callBuiltinPopScope {
MOTH_INSTR_HEADER
};
struct instr_callBuiltinForeachIteratorObject {
MOTH_INSTR_HEADER
- Temp arg;
- Temp result;
};
struct instr_callBuiltinForeachNextPropertyName {
MOTH_INSTR_HEADER
- Temp arg;
- Temp result;
};
struct instr_callBuiltinDeleteMember {
MOTH_INSTR_HEADER
int member;
Temp base;
- Temp result;
};
struct instr_callBuiltinDeleteSubscript {
MOTH_INSTR_HEADER
Temp base;
Temp index;
- Temp result;
};
struct instr_callBuiltinDeleteName {
MOTH_INSTR_HEADER
int name;
- Temp result;
};
struct instr_callBuiltinTypeofName {
MOTH_INSTR_HEADER
int name;
- Temp result;
};
struct instr_callBuiltinTypeofValue {
MOTH_INSTR_HEADER
- Temp value;
- Temp result;
};
struct instr_callBuiltinDeclareVar {
MOTH_INSTR_HEADER
@@ -516,7 +481,6 @@ union Instr
MOTH_INSTR_HEADER
uint argc;
Temp args;
- Temp result;
};
struct instr_callBuiltinDefineObjectLiteral {
MOTH_INSTR_HEADER
@@ -524,11 +488,9 @@ union Instr
int arrayValueCount;
int arrayGetterSetterCountAndFlags; // 30 bits for count, 1 bit for needsSparseArray boolean
Temp args;
- Temp result;
};
struct instr_callBuiltinSetupArgumentsObject {
MOTH_INSTR_HEADER
- Temp result;
};
struct instr_callBuiltinConvertThisToObject {
MOTH_INSTR_HEADER
@@ -537,7 +499,6 @@ union Instr
MOTH_INSTR_HEADER
Temp callData;
Temp func;
- Temp result;
};
struct instr_createProperty {
MOTH_INSTR_HEADER
@@ -545,7 +506,6 @@ union Instr
int argc;
Temp callData;
Temp base;
- Temp result;
};
struct instr_constructPropertyLookup {
MOTH_INSTR_HEADER
@@ -553,21 +513,18 @@ union Instr
int argc;
Temp callData;
Temp base;
- Temp result;
};
struct instr_createActivationProperty {
MOTH_INSTR_HEADER
int name;
int argc;
Temp callData;
- Temp result;
};
struct instr_constructGlobalLookup {
MOTH_INSTR_HEADER
int index;
int argc;
Temp callData;
- Temp result;
};
struct instr_jump {
MOTH_INSTR_HEADER
@@ -576,170 +533,109 @@ union Instr
struct instr_jumpEq {
MOTH_INSTR_HEADER
ptrdiff_t offset;
- Temp condition;
};
struct instr_jumpNe {
MOTH_INSTR_HEADER
ptrdiff_t offset;
- Temp condition;
};
struct instr_jumpStrictEqual {
MOTH_INSTR_HEADER
ptrdiff_t offset;
Temp lhs;
- Temp rhs;
};
struct instr_jumpStrictNotEqual {
MOTH_INSTR_HEADER
ptrdiff_t offset;
Temp lhs;
- Temp rhs;
};
struct instr_unot {
MOTH_INSTR_HEADER
- Temp source;
- Temp result;
};
struct instr_unotBool {
MOTH_INSTR_HEADER
- Temp source;
- Temp result;
};
struct instr_uplus {
MOTH_INSTR_HEADER
- Temp source;
- Temp result;
};
struct instr_uminus {
MOTH_INSTR_HEADER
- Temp source;
- Temp result;
};
struct instr_ucompl {
MOTH_INSTR_HEADER
- Temp source;
- Temp result;
};
struct instr_ucomplInt {
MOTH_INSTR_HEADER
- Temp source;
- Temp result;
};
- struct instr_preIncrement {
+ struct instr_increment {
MOTH_INSTR_HEADER
- Temp source;
- Temp result;
};
- struct instr_preDecrement {
+ struct instr_decrement {
MOTH_INSTR_HEADER
- Temp source;
- Temp result;
- };
- struct instr_postIncrement {
- MOTH_INSTR_HEADER
- Temp source;
- Temp result;
- };
- struct instr_postDecrement {
- MOTH_INSTR_HEADER
- Temp source;
- Temp result;
};
struct instr_binop {
MOTH_INSTR_HEADER
int alu; // QV4::Runtime::RuntimeMethods enum value
Temp lhs;
- Temp rhs;
- Temp result;
};
struct instr_add {
MOTH_INSTR_HEADER
Temp lhs;
- Temp rhs;
- Temp result;
};
struct instr_bitAnd {
MOTH_INSTR_HEADER
Temp lhs;
- Temp rhs;
- Temp result;
};
struct instr_bitOr {
MOTH_INSTR_HEADER
Temp lhs;
- Temp rhs;
- Temp result;
};
struct instr_bitXor {
MOTH_INSTR_HEADER
Temp lhs;
- Temp rhs;
- Temp result;
};
struct instr_shr {
MOTH_INSTR_HEADER
Temp lhs;
- Temp rhs;
- Temp result;
};
struct instr_shl {
MOTH_INSTR_HEADER
Temp lhs;
- Temp rhs;
- Temp result;
};
struct instr_bitAndConst {
MOTH_INSTR_HEADER
- Temp lhs;
int rhs;
- Temp result;
};
struct instr_bitOrConst {
MOTH_INSTR_HEADER
- Temp lhs;
int rhs;
- Temp result;
};
struct instr_bitXorConst {
MOTH_INSTR_HEADER
- Temp lhs;
int rhs;
- Temp result;
};
struct instr_shrConst {
MOTH_INSTR_HEADER
- Temp lhs;
int rhs;
- Temp result;
};
struct instr_shlConst {
MOTH_INSTR_HEADER
- Temp lhs;
int rhs;
- Temp result;
};
struct instr_mul {
MOTH_INSTR_HEADER
Temp lhs;
- Temp rhs;
- Temp result;
};
struct instr_sub {
MOTH_INSTR_HEADER
Temp lhs;
- Temp rhs;
- Temp result;
};
struct instr_binopContext {
MOTH_INSTR_HEADER
uint alu; // offset inside the runtime methods
Temp lhs;
- Temp rhs;
- Temp result;
};
struct instr_loadThis {
MOTH_INSTR_HEADER
- Temp result;
};
struct instr_loadQmlContext {
MOTH_INSTR_HEADER
@@ -751,7 +647,6 @@ union Instr
};
struct instr_loadQmlSingleton {
MOTH_INSTR_HEADER
- Temp result;
int name;
};
@@ -760,6 +655,10 @@ union Instr
instr_line line;
instr_debug debug;
instr_loadConst loadConst;
+ instr_moveConst moveConst;
+ instr_loadReg loadReg;
+ instr_storeReg storeReg;
+ instr_moveReg moveReg;
instr_loadLocal loadLocal;
instr_storeLocal storeLocal;
instr_loadArg loadArg;
@@ -770,7 +669,6 @@ union Instr
instr_storeScopedArg storeScopedArg;
instr_loadRuntimeString loadRuntimeString;
instr_loadRegExp loadRegExp;
- instr_move move;
instr_loadClosure loadClosure;
instr_loadName loadName;
instr_getGlobalLookup getGlobalLookup;
@@ -831,10 +729,8 @@ union Instr
instr_uminus uminus;
instr_ucompl ucompl;
instr_ucomplInt ucomplInt;
- instr_preIncrement preIncrement;
- instr_preDecrement preDecrement;
- instr_postIncrement postIncrement;
- instr_postDecrement postDecrement;
+ instr_increment increment;
+ instr_decrement decrement;
instr_binop binop;
instr_add add;
instr_bitAnd bitAnd;
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 81ec903d18..d474f45237 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1346,7 +1346,7 @@ QV4::ReturnedValue Runtime::method_setupArgumentsObject(ExecutionEngine *engine)
#endif // V4_BOOTSTRAP
-QV4::ReturnedValue Runtime::method_preIncrement(const Value &value)
+QV4::ReturnedValue Runtime::method_increment(const Value &value)
{
TRACE1(value);
@@ -1358,7 +1358,7 @@ QV4::ReturnedValue Runtime::method_preIncrement(const Value &value)
}
}
-QV4::ReturnedValue Runtime::method_preDecrement(const Value &value)
+QV4::ReturnedValue Runtime::method_decrement(const Value &value)
{
TRACE1(value);
@@ -1370,46 +1370,6 @@ QV4::ReturnedValue Runtime::method_preDecrement(const Value &value)
}
}
-QV4::ReturnedValue Runtime::method_postIncrement(Value *value)
-{
- TRACE1(value);
-
- if (value->isNumber()) {
- Value old = *value;
- if (value->isInteger() && value->integerValue() < INT_MAX) {
- *value = Primitive::fromInt32(value->integerValue() + 1);
- } else {
- *value = Primitive::fromDouble(value->doubleValue() + 1.0);
- }
- return old.asReturnedValue();
- }
-
- // ToNumber conversion needed:
- double d = value->toNumberImpl();
- *value = Primitive::fromDouble(d + 1.);
- return Encode(d);
-}
-
-QV4::ReturnedValue Runtime::method_postDecrement(Value *value)
-{
- TRACE1(value);
-
- if (value->isNumber()) {
- Value old = *value;
- if (value->isInteger() && value->integerValue() > INT_MIN) {
- *value = Primitive::fromInt32(value->integerValue() - 1);
- } else {
- *value = Primitive::fromDouble(value->doubleValue() - 1.0);
- }
- return old.asReturnedValue();
- }
-
- // ToNumber conversion needed:
- double d = value->toNumber();
- *value = Primitive::fromDouble(d - 1.);
- return Encode(d);
-}
-
ReturnedValue Runtime::method_toDouble(const Value &value)
{
TRACE1(value);
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index 736ad5dc6b..38e5d027ce 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -154,10 +154,8 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> {
F(ReturnedValue, uMinus, (const Value &value)) \
F(ReturnedValue, uNot, (const Value &value)) \
F(ReturnedValue, complement, (const Value &value)) \
- F(ReturnedValue, preIncrement, (const Value &value)) \
- F(ReturnedValue, preDecrement, (const Value &value)) \
- F(ReturnedValue, postIncrement, (Value *value)) \
- F(ReturnedValue, postDecrement, (Value *value)) \
+ F(ReturnedValue, increment, (const Value &value)) \
+ F(ReturnedValue, decrement, (const Value &value)) \
\
/* binary operators */ \
F(ReturnedValue, instanceof, (ExecutionEngine *engine, const Value &left, const Value &right)) \
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index aa5a44377f..e1199de8e5 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -429,6 +429,13 @@ Param traceParam(const Param &param)
#define TEMP_VALUEPTR(temp) VALUEPTR(Param::createTemp(temp.index))
#define STORE_TEMP_VALUE(temp, value) STOREVALUE(Param::createTemp(temp.index), value)
+#define STORE_ACCUMULATOR(value) { \
+ auto tmp = (value); \
+ if (engine->hasException) \
+ goto catchException; \
+ accumulator = tmp; \
+}
+
// qv4scopedvalue_p.h also defines a CHECK_EXCEPTION macro
#ifdef CHECK_EXCEPTION
#undef CHECK_EXCEPTION
@@ -453,7 +460,7 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
#undef MOTH_INSTR_ADDR
#endif
- QV4::ReturnedValue returnValue = Encode::undefined();
+ QV4::Value accumulator = Primitive::undefinedValue();
QV4::Value *stack = 0;
unsigned stackSize = 0;
@@ -517,133 +524,145 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
#endif
MOTH_BEGIN_INSTR(LoadConst)
- TEMP_VALUE(instr.result) = static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->constants[instr.index];
+ accumulator = static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->constants[instr.index];
MOTH_END_INSTR(LoadConst)
+ MOTH_BEGIN_INSTR(MoveConst)
+ accumulator = static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->constants[instr.constIndex];
+ TEMP_VALUE(instr.destTemp) = accumulator;
+ MOTH_END_INSTR(MoveConst)
+
+ MOTH_BEGIN_INSTR(LoadReg)
+ accumulator = TEMP_VALUE(instr.reg);
+ MOTH_END_INSTR(LoadReg)
+
+ MOTH_BEGIN_INSTR(StoreReg)
+ TEMP_VALUE(instr.reg) = accumulator;
+ MOTH_END_INSTR(StoreReg)
+
+ MOTH_BEGIN_INSTR(MoveReg)
+ accumulator = TEMP_VALUE(instr.srcReg);
+ TEMP_VALUE(instr.destReg) = accumulator;
+ MOTH_END_INSTR(MoveReg)
+
MOTH_BEGIN_INSTR(LoadLocal)
- TEMP_VALUE(instr.result) = VALUE(Param::createLocal(instr.index));
+ accumulator = VALUE(Param::createLocal(instr.index));
MOTH_END_INSTR(LoadLocal)
MOTH_BEGIN_INSTR(StoreLocal)
- VALUE(Param::createLocal(instr.index)) = TEMP_VALUE(instr.source);
+ VALUE(Param::createLocal(instr.index)) = accumulator;
MOTH_END_INSTR(StoreLocal)
MOTH_BEGIN_INSTR(LoadArg)
- TEMP_VALUE(instr.result) = VALUE(Param::createArgument(instr.index, 0));
+ accumulator = VALUE(Param::createArgument(instr.index, 0));
MOTH_END_INSTR(LoadArg)
MOTH_BEGIN_INSTR(StoreArg)
- VALUE(Param::createArgument(instr.index, 0)) = TEMP_VALUE(instr.source);
+ VALUE(Param::createArgument(instr.index, 0)) = accumulator;
MOTH_END_INSTR(StoreArg)
MOTH_BEGIN_INSTR(LoadScopedLocal)
- TEMP_VALUE(instr.result) = VALUE(Param::createScopedLocal(instr.index, instr.scope));
+ accumulator = VALUE(Param::createScopedLocal(instr.index, instr.scope));
MOTH_END_INSTR(LoadScopedLocal)
MOTH_BEGIN_INSTR(StoreScopedLocal)
- VALUE(Param::createScopedLocal(instr.index, instr.scope)) = TEMP_VALUE(instr.source);
+ VALUE(Param::createScopedLocal(instr.index, instr.scope)) = accumulator;
MOTH_END_INSTR(StoreScopedLocal)
MOTH_BEGIN_INSTR(LoadScopedArg)
- TEMP_VALUE(instr.result) = VALUE(Param::createArgument(instr.index, instr.scope));
+ accumulator = VALUE(Param::createArgument(instr.index, instr.scope));
MOTH_END_INSTR(LoadScopedArg);
MOTH_BEGIN_INSTR(StoreScopedArg)
- VALUE(Param::createArgument(instr.index, instr.scope)) = TEMP_VALUE(instr.source);
+ VALUE(Param::createArgument(instr.index, instr.scope)) = accumulator;
MOTH_END_INSTR(StoreScopedArg)
- MOTH_BEGIN_INSTR(Move)
- TEMP_VALUE(instr.result) = TEMP_VALUE(instr.source);
- MOTH_END_INSTR(Move)
-
MOTH_BEGIN_INSTR(LoadRuntimeString)
-// TRACE(value, "%s", instr.value.toString(context)->toQString().toUtf8().constData());
- TEMP_VALUE(instr.result) = engine->current->compilationUnit->runtimeStrings[instr.stringId];
+ accumulator = engine->current->compilationUnit->runtimeStrings[instr.stringId];
MOTH_END_INSTR(LoadRuntimeString)
MOTH_BEGIN_INSTR(LoadRegExp)
-// TRACE(value, "%s", instr.value.toString(context)->toQString().toUtf8().constData());
- TEMP_VALUE(instr.result) = static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->runtimeRegularExpressions[instr.regExpId];
+ accumulator = static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->runtimeRegularExpressions[instr.regExpId];
MOTH_END_INSTR(LoadRegExp)
MOTH_BEGIN_INSTR(LoadClosure)
- STORE_TEMP_VALUE(instr.result, Runtime::method_closure(engine, instr.value));
+ STORE_ACCUMULATOR(Runtime::method_closure(engine, instr.value));
MOTH_END_INSTR(LoadClosure)
MOTH_BEGIN_INSTR(LoadName)
- STORE_TEMP_VALUE(instr.result, Runtime::method_getActivationProperty(engine, instr.name));
+ STORE_ACCUMULATOR(Runtime::method_getActivationProperty(engine, instr.name));
MOTH_END_INSTR(LoadName)
MOTH_BEGIN_INSTR(GetGlobalLookup)
QV4::Lookup *l = engine->current->lookups + instr.index;
- STORE_TEMP_VALUE(instr.result, l->globalGetter(l, engine));
+ STORE_ACCUMULATOR(l->globalGetter(l, engine));
MOTH_END_INSTR(GetGlobalLookup)
MOTH_BEGIN_INSTR(StoreName)
- Runtime::method_setActivationProperty(engine, instr.name, TEMP_VALUE(instr.source));
+ Runtime::method_setActivationProperty(engine, instr.name, accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreName)
MOTH_BEGIN_INSTR(LoadElement)
- STORE_TEMP_VALUE(instr.result, Runtime::method_getElement(engine, TEMP_VALUE(instr.base), TEMP_VALUE(instr.index)));
+ STORE_ACCUMULATOR(Runtime::method_getElement(engine, TEMP_VALUE(instr.base), TEMP_VALUE(instr.index)));
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(LoadElementLookup)
QV4::Lookup *l = engine->current->lookups + instr.lookup;
- STORE_TEMP_VALUE(instr.result, l->indexedGetter(l, engine, TEMP_VALUE(instr.base), TEMP_VALUE(instr.index)));
+ STORE_ACCUMULATOR(l->indexedGetter(l, engine, TEMP_VALUE(instr.base), TEMP_VALUE(instr.index)));
MOTH_END_INSTR(LoadElementLookup)
MOTH_BEGIN_INSTR(StoreElement)
- Runtime::method_setElement(engine, TEMP_VALUE(instr.base), TEMP_VALUE(instr.index), TEMP_VALUE(instr.source));
+ Runtime::method_setElement(engine, TEMP_VALUE(instr.base), TEMP_VALUE(instr.index), accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreElement)
MOTH_BEGIN_INSTR(StoreElementLookup)
QV4::Lookup *l = engine->current->lookups + instr.lookup;
- l->indexedSetter(l, engine, TEMP_VALUE(instr.base), TEMP_VALUE(instr.index), TEMP_VALUE(instr.source));
+ l->indexedSetter(l, engine, TEMP_VALUE(instr.base), TEMP_VALUE(instr.index), accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreElementLookup)
MOTH_BEGIN_INSTR(LoadProperty)
- STORE_TEMP_VALUE(instr.result, Runtime::method_getProperty(engine, TEMP_VALUE(instr.base), instr.name));
+ STORE_ACCUMULATOR(Runtime::method_getProperty(engine, TEMP_VALUE(instr.base), instr.name));
MOTH_END_INSTR(LoadProperty)
MOTH_BEGIN_INSTR(GetLookup)
QV4::Lookup *l = engine->current->lookups + instr.index;
- STORE_TEMP_VALUE(instr.result, l->getter(l, engine, TEMP_VALUE(instr.base)));
+ STORE_ACCUMULATOR(l->getter(l, engine, TEMP_VALUE(instr.base)));
MOTH_END_INSTR(GetLookup)
MOTH_BEGIN_INSTR(StoreProperty)
- Runtime::method_setProperty(engine, TEMP_VALUE(instr.base), instr.name, TEMP_VALUE(instr.source));
+ Runtime::method_setProperty(engine, TEMP_VALUE(instr.base), instr.name, accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreProperty)
MOTH_BEGIN_INSTR(SetLookup)
QV4::Lookup *l = engine->current->lookups + instr.index;
- l->setter(l, engine, TEMP_VALUE(instr.base), TEMP_VALUE(instr.source));
+ l->setter(l, engine, TEMP_VALUE(instr.base), accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(SetLookup)
MOTH_BEGIN_INSTR(StoreScopeObjectProperty)
- Runtime::method_setQmlScopeObjectProperty(engine, TEMP_VALUE(instr.base), instr.propertyIndex, TEMP_VALUE(instr.source));
+ Runtime::method_setQmlScopeObjectProperty(engine, TEMP_VALUE(instr.base), instr.propertyIndex, accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreScopeObjectProperty)
MOTH_BEGIN_INSTR(LoadScopeObjectProperty)
- STORE_TEMP_VALUE(instr.result, Runtime::method_getQmlScopeObjectProperty(engine, TEMP_VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
+ STORE_ACCUMULATOR(Runtime::method_getQmlScopeObjectProperty(engine, TEMP_VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
MOTH_END_INSTR(LoadScopeObjectProperty)
MOTH_BEGIN_INSTR(StoreContextObjectProperty)
- Runtime::method_setQmlContextObjectProperty(engine, TEMP_VALUE(instr.base), instr.propertyIndex, TEMP_VALUE(instr.source));
+ Runtime::method_setQmlContextObjectProperty(engine, TEMP_VALUE(instr.base), instr.propertyIndex, accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreContextObjectProperty)
MOTH_BEGIN_INSTR(LoadContextObjectProperty)
- STORE_TEMP_VALUE(instr.result, Runtime::method_getQmlContextObjectProperty(engine, TEMP_VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
+ STORE_ACCUMULATOR(Runtime::method_getQmlContextObjectProperty(engine, TEMP_VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
MOTH_END_INSTR(LoadContextObjectProperty)
MOTH_BEGIN_INSTR(LoadIdObject)
- STORE_TEMP_VALUE(instr.result, Runtime::method_getQmlIdObject(engine, TEMP_VALUE(instr.base), instr.index));
+ STORE_ACCUMULATOR(Runtime::method_getQmlIdObject(engine, TEMP_VALUE(instr.base), instr.index));
MOTH_END_INSTR(LoadIdObject)
MOTH_BEGIN_INSTR(InitStackFrame)
@@ -654,15 +673,13 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
MOTH_BEGIN_INSTR(CallValue)
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.index);
- STORE_TEMP_VALUE(instr.result, Runtime::method_callValue(engine, TEMP_VALUE(instr.dest), callData));
- //### write barrier?
+ STORE_ACCUMULATOR(Runtime::method_callValue(engine, TEMP_VALUE(instr.dest), callData));
MOTH_END_INSTR(CallValue)
MOTH_BEGIN_INSTR(CallProperty)
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.index);
callData->thisObject = TEMP_VALUE(instr.base);
- STORE_TEMP_VALUE(instr.result, Runtime::method_callProperty(engine, instr.name, callData));
- //### write barrier?
+ STORE_ACCUMULATOR(Runtime::method_callProperty(engine, instr.name, callData));
MOTH_END_INSTR(CallProperty)
MOTH_BEGIN_INSTR(CallPropertyLookup)
@@ -671,26 +688,23 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
callData->tag = quint32(Value::ValueTypeInternal::Integer);
callData->argc = instr.argc;
callData->thisObject = TEMP_VALUE(instr.base);
- STORE_TEMP_VALUE(instr.result, Runtime::method_callPropertyLookup(engine, instr.lookupIndex, callData));
+ STORE_ACCUMULATOR(Runtime::method_callPropertyLookup(engine, instr.lookupIndex, callData));
MOTH_END_INSTR(CallPropertyLookup)
MOTH_BEGIN_INSTR(CallElement)
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.index);
callData->thisObject = TEMP_VALUE(instr.base);
- STORE_TEMP_VALUE(instr.result, Runtime::method_callElement(engine, TEMP_VALUE(instr.index), callData));
- //### write barrier?
+ STORE_ACCUMULATOR(Runtime::method_callElement(engine, TEMP_VALUE(instr.index), callData));
MOTH_END_INSTR(CallElement)
MOTH_BEGIN_INSTR(CallActivationProperty)
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.index);
- STORE_TEMP_VALUE(instr.result, Runtime::method_callActivationProperty(engine, instr.name, callData));
- //### write barrier?
+ STORE_ACCUMULATOR(Runtime::method_callActivationProperty(engine, instr.name, callData));
MOTH_END_INSTR(CallActivationProperty)
MOTH_BEGIN_INSTR(CallGlobalLookup)
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.index);
- STORE_TEMP_VALUE(instr.result, Runtime::method_callGlobalLookup(engine, instr.index, callData));
- //### write barrier?
+ STORE_ACCUMULATOR(Runtime::method_callGlobalLookup(engine, instr.index, callData));
MOTH_END_INSTR(CallGlobalLookup)
MOTH_BEGIN_INSTR(SetExceptionHandler)
@@ -699,22 +713,22 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
MOTH_END_INSTR(SetExceptionHandler)
MOTH_BEGIN_INSTR(CallBuiltinThrow)
- Runtime::method_throwException(engine, TEMP_VALUE(instr.arg));
+ Runtime::method_throwException(engine, accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(CallBuiltinThrow)
MOTH_BEGIN_INSTR(GetException)
- *TEMP_VALUEPTR(instr.result) = engine->hasException ? *engine->exceptionValue : Primitive::emptyValue();
+ accumulator = engine->hasException ? *engine->exceptionValue : Primitive::emptyValue();
engine->hasException = false;
MOTH_END_INSTR(HasException)
MOTH_BEGIN_INSTR(SetException)
- *engine->exceptionValue = TEMP_VALUE(instr.exception);
+ *engine->exceptionValue = accumulator;
engine->hasException = true;
MOTH_END_INSTR(SetException)
MOTH_BEGIN_INSTR(CallBuiltinUnwindException)
- STORE_TEMP_VALUE(instr.result, Runtime::method_unwindException(engine));
+ STORE_ACCUMULATOR(Runtime::method_unwindException(engine));
MOTH_END_INSTR(CallBuiltinUnwindException)
MOTH_BEGIN_INSTR(CallBuiltinPushCatchScope)
@@ -722,7 +736,7 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
MOTH_END_INSTR(CallBuiltinPushCatchScope)
MOTH_BEGIN_INSTR(CallBuiltinPushScope)
- Runtime::method_pushWithScope(TEMP_VALUE(instr.arg), static_cast<QV4::NoThrowEngine*>(engine));
+ Runtime::method_pushWithScope(accumulator, static_cast<QV4::NoThrowEngine*>(engine));
CHECK_EXCEPTION;
MOTH_END_INSTR(CallBuiltinPushScope)
@@ -731,31 +745,31 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
MOTH_END_INSTR(CallBuiltinPopScope)
MOTH_BEGIN_INSTR(CallBuiltinForeachIteratorObject)
- STORE_TEMP_VALUE(instr.result, Runtime::method_foreachIterator(engine, TEMP_VALUE(instr.arg)));
+ STORE_ACCUMULATOR(Runtime::method_foreachIterator(engine, accumulator));
MOTH_END_INSTR(CallBuiltinForeachIteratorObject)
MOTH_BEGIN_INSTR(CallBuiltinForeachNextPropertyName)
- STORE_TEMP_VALUE(instr.result, Runtime::method_foreachNextPropertyName(TEMP_VALUE(instr.arg)));
+ STORE_ACCUMULATOR(Runtime::method_foreachNextPropertyName(accumulator));
MOTH_END_INSTR(CallBuiltinForeachNextPropertyName)
MOTH_BEGIN_INSTR(CallBuiltinDeleteMember)
- STORE_TEMP_VALUE(instr.result, Runtime::method_deleteMember(engine, TEMP_VALUE(instr.base), instr.member));
+ STORE_ACCUMULATOR(Runtime::method_deleteMember(engine, TEMP_VALUE(instr.base), instr.member));
MOTH_END_INSTR(CallBuiltinDeleteMember)
MOTH_BEGIN_INSTR(CallBuiltinDeleteSubscript)
- STORE_TEMP_VALUE(instr.result, Runtime::method_deleteElement(engine, TEMP_VALUE(instr.base), TEMP_VALUE(instr.index)));
+ STORE_ACCUMULATOR(Runtime::method_deleteElement(engine, TEMP_VALUE(instr.base), TEMP_VALUE(instr.index)));
MOTH_END_INSTR(CallBuiltinDeleteSubscript)
MOTH_BEGIN_INSTR(CallBuiltinDeleteName)
- STORE_TEMP_VALUE(instr.result, Runtime::method_deleteName(engine, instr.name));
+ STORE_ACCUMULATOR(Runtime::method_deleteName(engine, instr.name));
MOTH_END_INSTR(CallBuiltinDeleteName)
MOTH_BEGIN_INSTR(CallBuiltinTypeofName)
- STORE_TEMP_VALUE(instr.result, Runtime::method_typeofName(engine, instr.name));
+ STORE_ACCUMULATOR(Runtime::method_typeofName(engine, instr.name));
MOTH_END_INSTR(CallBuiltinTypeofName)
MOTH_BEGIN_INSTR(CallBuiltinTypeofValue)
- STORE_TEMP_VALUE(instr.result, Runtime::method_typeofValue(engine, TEMP_VALUE(instr.value)));
+ STORE_ACCUMULATOR(Runtime::method_typeofValue(engine, accumulator));
MOTH_END_INSTR(CallBuiltinTypeofValue)
MOTH_BEGIN_INSTR(CallBuiltinDeclareVar)
@@ -765,16 +779,16 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
MOTH_BEGIN_INSTR(CallBuiltinDefineArray)
Q_ASSERT(instr.args.index + instr.argc <= stackSize);
QV4::Value *args = stack + instr.args.index;
- STORE_TEMP_VALUE(instr.result, Runtime::method_arrayLiteral(engine, args, instr.argc));
+ STORE_ACCUMULATOR(Runtime::method_arrayLiteral(engine, args, instr.argc));
MOTH_END_INSTR(CallBuiltinDefineArray)
MOTH_BEGIN_INSTR(CallBuiltinDefineObjectLiteral)
QV4::Value *args = stack + instr.args.index;
- STORE_TEMP_VALUE(instr.result, Runtime::method_objectLiteral(engine, args, instr.internalClassId, instr.arrayValueCount, instr.arrayGetterSetterCountAndFlags));
+ STORE_ACCUMULATOR(Runtime::method_objectLiteral(engine, args, instr.internalClassId, instr.arrayValueCount, instr.arrayGetterSetterCountAndFlags));
MOTH_END_INSTR(CallBuiltinDefineObjectLiteral)
MOTH_BEGIN_INSTR(CallBuiltinSetupArgumentsObject)
- STORE_TEMP_VALUE(instr.result, Runtime::method_setupArgumentsObject(engine));
+ STORE_ACCUMULATOR(Runtime::method_setupArgumentsObject(engine));
MOTH_END_INSTR(CallBuiltinSetupArgumentsObject)
MOTH_BEGIN_INSTR(CallBuiltinConvertThisToObject)
@@ -784,7 +798,7 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
MOTH_BEGIN_INSTR(CreateValue)
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.index);
- STORE_TEMP_VALUE(instr.result, Runtime::method_constructValue(engine, TEMP_VALUE(instr.func), callData));
+ STORE_ACCUMULATOR(Runtime::method_constructValue(engine, TEMP_VALUE(instr.func), callData));
//### write barrier?
MOTH_END_INSTR(CreateValue)
@@ -794,7 +808,7 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
callData->tag = quint32(Value::ValueTypeInternal::Integer);
callData->argc = instr.argc;
callData->thisObject = TEMP_VALUE(instr.base);
- STORE_TEMP_VALUE(instr.result, Runtime::method_constructProperty(engine, instr.name, callData));
+ STORE_ACCUMULATOR(Runtime::method_constructProperty(engine, instr.name, callData));
MOTH_END_INSTR(CreateProperty)
MOTH_BEGIN_INSTR(ConstructPropertyLookup)
@@ -803,7 +817,7 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
callData->tag = quint32(Value::ValueTypeInternal::Integer);
callData->argc = instr.argc;
callData->thisObject = TEMP_VALUE(instr.base);
- STORE_TEMP_VALUE(instr.result, Runtime::method_constructPropertyLookup(engine, instr.index, callData));
+ STORE_ACCUMULATOR(Runtime::method_constructPropertyLookup(engine, instr.index, callData));
MOTH_END_INSTR(ConstructPropertyLookup)
MOTH_BEGIN_INSTR(CreateActivationProperty)
@@ -812,7 +826,7 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
callData->tag = quint32(Value::ValueTypeInternal::Integer);
callData->argc = instr.argc;
callData->thisObject = QV4::Primitive::undefinedValue();
- STORE_TEMP_VALUE(instr.result, Runtime::method_constructActivationProperty(engine, instr.name, callData));
+ STORE_ACCUMULATOR(Runtime::method_constructActivationProperty(engine, instr.name, callData));
MOTH_END_INSTR(CreateActivationProperty)
MOTH_BEGIN_INSTR(ConstructGlobalLookup)
@@ -821,7 +835,7 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
callData->tag = quint32(Value::ValueTypeInternal::Integer);
callData->argc = instr.argc;
callData->thisObject = QV4::Primitive::undefinedValue();
- STORE_TEMP_VALUE(instr.result, Runtime::method_constructGlobalLookup(engine, instr.index, callData));
+ STORE_ACCUMULATOR(Runtime::method_constructGlobalLookup(engine, instr.index, callData));
MOTH_END_INSTR(ConstructGlobalLookup)
MOTH_BEGIN_INSTR(Jump)
@@ -829,135 +843,125 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
MOTH_END_INSTR(Jump)
MOTH_BEGIN_INSTR(JumpEq)
- if (TEMP_VALUEPTR(instr.condition)->toBoolean())
+ if (accumulator.toBoolean())
code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
MOTH_END_INSTR(JumpEq)
MOTH_BEGIN_INSTR(JumpNe)
- if (!TEMP_VALUEPTR(instr.condition)->toBoolean())
+ if (!accumulator.toBoolean())
code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
MOTH_END_INSTR(JumpNe)
MOTH_BEGIN_INSTR(JumpStrictEqual)
- if (RuntimeHelpers::strictEqual(TEMP_VALUE(instr.lhs), TEMP_VALUE(instr.rhs)))
+ if (RuntimeHelpers::strictEqual(TEMP_VALUE(instr.lhs), accumulator))
code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
MOTH_END_INSTR(JumpStrictEqual)
MOTH_BEGIN_INSTR(JumpStrictNotEqual)
- if (!RuntimeHelpers::strictEqual(TEMP_VALUE(instr.lhs), TEMP_VALUE(instr.rhs)))
+ if (!RuntimeHelpers::strictEqual(TEMP_VALUE(instr.lhs), accumulator))
code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
MOTH_END_INSTR(JumpStrictNotEqual)
MOTH_BEGIN_INSTR(UNot)
- STORE_TEMP_VALUE(instr.result, Runtime::method_uNot(TEMP_VALUE(instr.source)));
+ STORE_ACCUMULATOR(Runtime::method_uNot(accumulator));
MOTH_END_INSTR(UNot)
MOTH_BEGIN_INSTR(UNotBool)
- bool b = TEMP_VALUE(instr.source).booleanValue();
- TEMP_VALUE(instr.result) = QV4::Encode(!b);
+ bool b = accumulator.toBoolean();
+ STORE_ACCUMULATOR(QV4::Encode(!b));
MOTH_END_INSTR(UNotBool)
MOTH_BEGIN_INSTR(UPlus)
- STORE_TEMP_VALUE(instr.result, Runtime::method_uPlus(TEMP_VALUE(instr.source)));
+ STORE_ACCUMULATOR(Runtime::method_uPlus(accumulator));
MOTH_END_INSTR(UPlus)
MOTH_BEGIN_INSTR(UMinus)
- STORE_TEMP_VALUE(instr.result, Runtime::method_uMinus(TEMP_VALUE(instr.source)));
+ STORE_ACCUMULATOR(Runtime::method_uMinus(accumulator));
MOTH_END_INSTR(UMinus)
MOTH_BEGIN_INSTR(UCompl)
- STORE_TEMP_VALUE(instr.result, Runtime::method_complement(TEMP_VALUE(instr.source)));
+ STORE_ACCUMULATOR(Runtime::method_complement(accumulator));
MOTH_END_INSTR(UCompl)
MOTH_BEGIN_INSTR(UComplInt)
- TEMP_VALUE(instr.result) = Runtime::method_complement(TEMP_VALUE(instr.source));
+ STORE_ACCUMULATOR(Runtime::method_complement(accumulator));
MOTH_END_INSTR(UComplInt)
- MOTH_BEGIN_INSTR(PreIncrement)
- STORE_TEMP_VALUE(instr.result, Runtime::method_preIncrement(TEMP_VALUE(instr.source)));
- MOTH_END_INSTR(PreIncrement)
-
- MOTH_BEGIN_INSTR(PreDecrement)
- STORE_TEMP_VALUE(instr.result, Runtime::method_preDecrement(TEMP_VALUE(instr.source)));
- MOTH_END_INSTR(PreDecrement)
-
- MOTH_BEGIN_INSTR(PostIncrement)
- //### we probably need a write-barrier for instr.source, because it will be written to
- STORE_TEMP_VALUE(instr.result, Runtime::method_postIncrement(TEMP_VALUEPTR(instr.source)));
- MOTH_END_INSTR(PreIncrement)
+ MOTH_BEGIN_INSTR(Increment)
+ STORE_ACCUMULATOR(Runtime::method_increment(accumulator));
+ MOTH_END_INSTR(Increment)
- MOTH_BEGIN_INSTR(PostDecrement)
- //### we probably need a write-barrier for instr.source, because it will be written to
- STORE_TEMP_VALUE(instr.result, Runtime::method_postDecrement(TEMP_VALUEPTR(instr.source)));
- MOTH_END_INSTR(PreDecrement)
+ MOTH_BEGIN_INSTR(Decrement)
+ STORE_ACCUMULATOR(Runtime::method_decrement(accumulator));
+ MOTH_END_INSTR(Decrement)
MOTH_BEGIN_INSTR(Binop)
QV4::Runtime::BinaryOperation op = *reinterpret_cast<QV4::Runtime::BinaryOperation *>(reinterpret_cast<char *>(&engine->runtime.runtimeMethods[instr.alu]));
- STORE_TEMP_VALUE(instr.result, op(TEMP_VALUE(instr.lhs), TEMP_VALUE(instr.rhs)));
+ STORE_ACCUMULATOR(op(TEMP_VALUE(instr.lhs), accumulator));
MOTH_END_INSTR(Binop)
MOTH_BEGIN_INSTR(Add)
- STORE_TEMP_VALUE(instr.result, Runtime::method_add(engine, TEMP_VALUE(instr.lhs), TEMP_VALUE(instr.rhs)));
+ STORE_ACCUMULATOR(Runtime::method_add(engine, TEMP_VALUE(instr.lhs), accumulator));
MOTH_END_INSTR(Add)
MOTH_BEGIN_INSTR(BitAnd)
- STORE_TEMP_VALUE(instr.result, Runtime::method_bitAnd(TEMP_VALUE(instr.lhs), TEMP_VALUE(instr.rhs)));
+ STORE_ACCUMULATOR(Runtime::method_bitAnd(TEMP_VALUE(instr.lhs), accumulator));
MOTH_END_INSTR(BitAnd)
MOTH_BEGIN_INSTR(BitOr)
- STORE_TEMP_VALUE(instr.result, Runtime::method_bitOr(TEMP_VALUE(instr.lhs), TEMP_VALUE(instr.rhs)));
+ STORE_ACCUMULATOR(Runtime::method_bitOr(TEMP_VALUE(instr.lhs), accumulator));
MOTH_END_INSTR(BitOr)
MOTH_BEGIN_INSTR(BitXor)
- STORE_TEMP_VALUE(instr.result, Runtime::method_bitXor(TEMP_VALUE(instr.lhs), TEMP_VALUE(instr.rhs)));
+ STORE_ACCUMULATOR(Runtime::method_bitXor(TEMP_VALUE(instr.lhs), accumulator));
MOTH_END_INSTR(BitXor)
MOTH_BEGIN_INSTR(Shr)
- STORE_TEMP_VALUE(instr.result, QV4::Encode((int)(TEMP_VALUEPTR(instr.lhs)->toInt32() >> (TEMP_VALUEPTR(instr.rhs)->toInt32() & 0x1f))));
+ STORE_ACCUMULATOR(Runtime::method_shr(TEMP_VALUE(instr.lhs), accumulator));
MOTH_END_INSTR(Shr)
MOTH_BEGIN_INSTR(Shl)
- STORE_TEMP_VALUE(instr.result, QV4::Encode((int)(TEMP_VALUEPTR(instr.lhs)->toInt32() << (TEMP_VALUEPTR(instr.rhs)->toInt32() & 0x1f))));
+ STORE_ACCUMULATOR(Runtime::method_shl(TEMP_VALUE(instr.lhs), accumulator));
MOTH_END_INSTR(Shl)
MOTH_BEGIN_INSTR(BitAndConst)
- int lhs = TEMP_VALUEPTR(instr.lhs)->toInt32();
- STORE_TEMP_VALUE(instr.result, QV4::Encode((int)(lhs & instr.rhs)));
+ int lhs = accumulator.toInt32();
+ STORE_ACCUMULATOR(QV4::Primitive::fromInt32(lhs & instr.rhs));
MOTH_END_INSTR(BitAnd)
MOTH_BEGIN_INSTR(BitOrConst)
- int lhs = TEMP_VALUEPTR(instr.lhs)->toInt32();
- STORE_TEMP_VALUE(instr.result, QV4::Encode((int)(lhs | instr.rhs)));
+ int lhs = accumulator.toInt32();
+ STORE_ACCUMULATOR(QV4::Encode((int)(lhs | instr.rhs)));
MOTH_END_INSTR(BitOr)
MOTH_BEGIN_INSTR(BitXorConst)
- int lhs = TEMP_VALUEPTR(instr.lhs)->toInt32();
- STORE_TEMP_VALUE(instr.result, QV4::Encode((int)(lhs ^ instr.rhs)));
+ int lhs = accumulator.toInt32();
+ STORE_ACCUMULATOR(QV4::Encode((int)(lhs ^ instr.rhs)));
MOTH_END_INSTR(BitXor)
MOTH_BEGIN_INSTR(ShrConst)
- STORE_TEMP_VALUE(instr.result, QV4::Encode((int)(TEMP_VALUEPTR(instr.lhs)->toInt32() >> instr.rhs)));
+ STORE_ACCUMULATOR(QV4::Encode((int)(accumulator.toInt32() >> instr.rhs)));
MOTH_END_INSTR(ShrConst)
MOTH_BEGIN_INSTR(ShlConst)
- STORE_TEMP_VALUE(instr.result, QV4::Encode((int)(TEMP_VALUEPTR(instr.lhs)->toInt32() << instr.rhs)));
+ STORE_ACCUMULATOR(QV4::Encode((int)(accumulator.toInt32() << instr.rhs)));
MOTH_END_INSTR(ShlConst)
MOTH_BEGIN_INSTR(Mul)
- STORE_TEMP_VALUE(instr.result, Runtime::method_mul(TEMP_VALUE(instr.lhs), TEMP_VALUE(instr.rhs)));
+ STORE_ACCUMULATOR(Runtime::method_mul(TEMP_VALUE(instr.lhs), accumulator));
MOTH_END_INSTR(Mul)
MOTH_BEGIN_INSTR(Sub)
- STORE_TEMP_VALUE(instr.result, Runtime::method_sub(TEMP_VALUE(instr.lhs), TEMP_VALUE(instr.rhs)));
+ STORE_ACCUMULATOR(Runtime::method_sub(TEMP_VALUE(instr.lhs), accumulator));
MOTH_END_INSTR(Sub)
MOTH_BEGIN_INSTR(BinopContext)
QV4::Runtime::BinaryOperationContext op = *reinterpret_cast<QV4::Runtime::BinaryOperationContext *>(reinterpret_cast<char *>(&engine->runtime.runtimeMethods[instr.alu]));
- STORE_TEMP_VALUE(instr.result, op(engine, TEMP_VALUE(instr.lhs), TEMP_VALUE(instr.rhs)));
+ STORE_ACCUMULATOR(op(engine, TEMP_VALUE(instr.lhs), accumulator));
MOTH_END_INSTR(BinopContext)
MOTH_BEGIN_INSTR(Ret)
- returnValue = TEMP_VALUE(instr.result).asReturnedValue();
+ accumulator = TEMP_VALUE(instr.result).asReturnedValue();
goto functionExit;
MOTH_END_INSTR(Ret)
@@ -974,7 +978,7 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
#endif // QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(LoadThis)
- TEMP_VALUE(instr.result) = engine->currentContext->thisObject();
+ STORE_ACCUMULATOR(engine->currentContext->thisObject());
MOTH_END_INSTR(LoadThis)
MOTH_BEGIN_INSTR(LoadQmlContext)
@@ -986,7 +990,7 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
MOTH_END_INSTR(LoadQmlImportedScripts)
MOTH_BEGIN_INSTR(LoadQmlSingleton)
- TEMP_VALUE(instr.result) = Runtime::method_getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
+ accumulator = Runtime::method_getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
MOTH_END_INSTR(LoadQmlSingleton)
#ifdef MOTH_THREADED_INTERPRETER
@@ -1002,7 +1006,7 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
catchException:
Q_ASSERT(engine->hasException);
if (!exceptionHandler) {
- returnValue = QV4::Encode::undefined();
+ accumulator = Primitive::undefinedValue();
goto functionExit;
}
code = exceptionHandler;
@@ -1010,6 +1014,6 @@ QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
functionExit:
if (QV4::Debugging::Debugger *debugger = engine->debugger())
- debugger->leavingFunction(returnValue);
- return returnValue;
+ debugger->leavingFunction(accumulator.asReturnedValue());
+ return accumulator.asReturnedValue();
}