aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-08-30 15:16:15 +0200
committerLars Knoll <lars.knoll@qt.io>2017-09-01 12:30:43 +0000
commitcc7a858698063649f9770a89949354e2b58ae288 (patch)
tree5a79c1335192ed757edd69b5b9ded873423aa0bd /src/qml
parent20596907289d50be3a5e1597ba62cefb733e6f19 (diff)
Unify JSStackFrame and CallData
Change-Id: I4494dae8166026074c9efc74bac62de9d3fa2342 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qv4codegen.cpp18
-rw-r--r--src/qml/compiler/qv4codegen_p.h4
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp131
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h30
-rw-r--r--src/qml/jsruntime/qv4context_p.h22
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine_p.h18
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp37
10 files changed, 126 insertions, 140 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 34cffc3faa..52f88905c5 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1232,13 +1232,14 @@ Moth::StackSlot Codegen::pushArgs(ArgumentList *args)
++argc;
int calldata = bytecodeGenerator->newRegisterArray(sizeof(CallData)/sizeof(Value) - 1 + argc);
- (void) Reference::fromConst(this, QV4::Encode(argc)).storeOnStack(calldata);
#ifndef QT_NO_DEBUG
- (void) Reference::fromConst(this, QV4::Encode::undefined()).storeOnStack(calldata + 1);
- (void) Reference::fromConst(this, QV4::Encode::undefined()).storeOnStack(calldata + 2);
+ (void) Reference::fromConst(this, QV4::Encode::undefined()).storeOnStack(calldata + CallData::Function);
+ (void) Reference::fromConst(this, QV4::Encode::undefined()).storeOnStack(calldata + CallData::Context);
+ (void) Reference::fromConst(this, QV4::Encode::undefined()).storeOnStack(calldata + CallData::Accumulator);
#endif
- (void) Reference::fromConst(this, QV4::Encode::undefined()).storeOnStack(calldata + 3);
- Q_STATIC_ASSERT(sizeof(CallData) == 5 * sizeof(Value));
+ (void) Reference::fromConst(this, QV4::Encode::undefined()).storeOnStack(calldata + CallData::This);
+ (void) Reference::fromConst(this, QV4::Encode(argc)).storeOnStack(calldata + CallData::Argc);
+ Q_STATIC_ASSERT(sizeof(CallData) == 6 * sizeof(Value));
argc = 0;
for (ArgumentList *it = args; it; it = it->next) {
@@ -1958,8 +1959,8 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
bytecodeGenerator = &bytecode;
bytecodeGenerator->setLocation(ast->firstSourceLocation());
- // allocate the js stack frame (Context & js Function & accumulator)
- bytecodeGenerator->newRegisterArray(sizeof(JSStackFrame)/sizeof(Value));
+ // reserve the js stack frame (Context & js Function & accumulator)
+ bytecodeGenerator->newRegisterArray(sizeof(CallData)/sizeof(Value) - 1 + _context->arguments.size());
int returnAddress = -1;
bool _requiresReturnValue = (_context->compilationMode == QmlBinding || _context->compilationMode == EvalCode);
@@ -3231,9 +3232,8 @@ QT_WARNING_POP
codegen->_context->contextObjectPropertyDependencies.insert(qmlCoreIndex, qmlNotifyIndex);
} return;
case This: {
- Context *c = codegen->currentContext();
Instruction::LoadReg load;
- load.reg = Moth::StackSlot::createArgument(c->arguments.size(), -1);
+ load.reg = Moth::StackSlot::createRegister(CallData::This);
codegen->bytecodeGenerator->addInstruction(load);
} return;
case Invalid:
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index 5f6385fd62..2ccf97d7a2 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -201,7 +201,7 @@ public:
bool isAccumulator() const { return type == Accumulator; }
bool isStackSlot() const { return type == StackSlot; }
bool isRegister() const {
- return isStackSlot() && theStackSlot.isRegister();
+ return isStackSlot();
}
static Reference fromAccumulator(Codegen *cg) {
@@ -217,7 +217,7 @@ public:
}
static Reference fromArgument(Codegen *cg, int index) {
Reference r(cg, StackSlot);
- r.theStackSlot = Moth::StackSlot::createArgument(cg->currentContext()->arguments.size(), index);
+ r.theStackSlot = Moth::StackSlot::createRegister(index + sizeof(CallData)/sizeof(Value) - 1);
r.stackSlotIsLocalOrArgument = true;
return r;
}
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 940c49c83a..601cdc551c 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -134,6 +134,31 @@ void dumpConstantTable(const Value *constants, uint count)
<< toString(constants[i].asReturnedValue()).toUtf8().constData() << "\n";
}
+QString dumpRegister(int reg, int nFormals)
+{
+ Q_STATIC_ASSERT(offsetof(CallData, function) == 0);
+ Q_STATIC_ASSERT(offsetof(CallData, context) == sizeof(Value));
+ Q_STATIC_ASSERT(offsetof(CallData, accumulator) == 2*sizeof(Value));
+ Q_STATIC_ASSERT(offsetof(CallData, thisObject) == 3*sizeof(Value));
+ if (reg == CallData::Function)
+ return QStringLiteral("(function)");
+ else if (reg == CallData::Context)
+ return QStringLiteral("(context)");
+ else if (reg == CallData::Accumulator)
+ return QStringLiteral("(accumulator)");
+ else if (reg == CallData::This)
+ return QStringLiteral("(this)");
+ else if (reg == CallData::Argc)
+ return QStringLiteral("(argc)");
+ reg -= 4;
+ if (reg <= nFormals)
+ return QStringLiteral("a%1").arg(reg);
+ reg -= nFormals;
+ return QStringLiteral("r%1").arg(reg);
+
+}
+
+
void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*startLine*/, const QVector<CompiledData::CodeOffsetToLine> &lineNumberMapping)
{
MOTH_JUMP_TABLE;
@@ -158,15 +183,15 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_DISPATCH()
MOTH_BEGIN_INSTR(LoadReg)
- d << StackSlot::dump(reg, nFormals);
+ d << dumpRegister(reg, nFormals);
MOTH_END_INSTR(LoadReg)
MOTH_BEGIN_INSTR(StoreReg)
- d << StackSlot::dump(reg, nFormals);
+ d << dumpRegister(reg, nFormals);
MOTH_END_INSTR(StoreReg)
MOTH_BEGIN_INSTR(MoveReg)
- d << StackSlot::dump(destReg, nFormals) << ", " << StackSlot::dump(srcReg, nFormals);
+ d << dumpRegister(destReg, nFormals) << ", " << dumpRegister(srcReg, nFormals);
MOTH_END_INSTR(MoveReg)
MOTH_BEGIN_INSTR(LoadConst)
@@ -193,7 +218,7 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(LoadInt)
MOTH_BEGIN_INSTR(MoveConst)
- d << StackSlot::dump(destTemp, nFormals) << ", C" << constIndex;
+ d << dumpRegister(destTemp, nFormals) << ", C" << constIndex;
MOTH_END_INSTR(MoveConst)
MOTH_BEGIN_INSTR(LoadLocal)
@@ -253,19 +278,19 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(StoreNameStrict)
MOTH_BEGIN_INSTR(LoadElement)
- d << StackSlot::dump(base, nFormals) << "[" << StackSlot::dump(index, nFormals) << "]";
+ d << dumpRegister(base, nFormals) << "[" << dumpRegister(index, nFormals) << "]";
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(LoadElementA)
- d << StackSlot::dump(base, nFormals) << "[acc]";
+ d << dumpRegister(base, nFormals) << "[acc]";
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(StoreElement)
- d << StackSlot::dump(base, nFormals) << "[" << StackSlot::dump(index, nFormals) << "]";
+ d << dumpRegister(base, nFormals) << "[" << dumpRegister(index, nFormals) << "]";
MOTH_END_INSTR(StoreElement)
MOTH_BEGIN_INSTR(LoadProperty)
- d << StackSlot::dump(base, nFormals) << "[" << name << "]";
+ d << dumpRegister(base, nFormals) << "[" << name << "]";
MOTH_END_INSTR(LoadProperty)
MOTH_BEGIN_INSTR(LoadPropertyA)
@@ -273,7 +298,7 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(LoadElementA)
MOTH_BEGIN_INSTR(GetLookup)
- d << StackSlot::dump(base, nFormals) << "(" << index << ")";
+ d << dumpRegister(base, nFormals) << "(" << index << ")";
MOTH_END_INSTR(GetLookup)
MOTH_BEGIN_INSTR(GetLookupA)
@@ -281,59 +306,59 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(GetLookupA)
MOTH_BEGIN_INSTR(StoreProperty)
- d << StackSlot::dump(base, nFormals) << "[" << name<< "]";
+ d << dumpRegister(base, nFormals) << "[" << name<< "]";
MOTH_END_INSTR(StoreProperty)
MOTH_BEGIN_INSTR(SetLookup)
- d << StackSlot::dump(base, nFormals) << "(" << index << ")";
+ d << dumpRegister(base, nFormals) << "(" << index << ")";
MOTH_END_INSTR(SetLookup)
MOTH_BEGIN_INSTR(StoreScopeObjectProperty)
- d << StackSlot::dump(base, nFormals) << "[" << propertyIndex << "]";
+ d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]";
MOTH_END_INSTR(StoreScopeObjectProperty)
MOTH_BEGIN_INSTR(LoadScopeObjectProperty)
- d << StackSlot::dump(base, nFormals) << "[" << propertyIndex << "]" << (captureRequired ? " (capture)" : " (no capture)");
+ d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]" << (captureRequired ? " (capture)" : " (no capture)");
MOTH_END_INSTR(LoadScopeObjectProperty)
MOTH_BEGIN_INSTR(StoreContextObjectProperty)
- d << StackSlot::dump(base, nFormals) << "[" << propertyIndex << "]";
+ d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]";
MOTH_END_INSTR(StoreContextObjectProperty)
MOTH_BEGIN_INSTR(LoadContextObjectProperty)
- d << StackSlot::dump(base, nFormals) << "[" << propertyIndex << "]" << (captureRequired ? " (capture)" : " (no capture)");
+ d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]" << (captureRequired ? " (capture)" : " (no capture)");
MOTH_END_INSTR(LoadContextObjectProperty)
MOTH_BEGIN_INSTR(LoadIdObject)
- d << StackSlot::dump(base, nFormals) << "[" << index << "]";
+ d << dumpRegister(base, nFormals) << "[" << index << "]";
MOTH_END_INSTR(LoadIdObject)
MOTH_BEGIN_INSTR(CallValue)
- d << "(" << StackSlot::dump(callData, nFormals) << ")";
+ d << "(" << dumpRegister(callData, nFormals) << ")";
MOTH_END_INSTR(CallValue)
MOTH_BEGIN_INSTR(CallProperty)
- d << StackSlot::dump(base, nFormals) << "." << name << "(" << StackSlot::dump(callData, nFormals) << ")";
+ d << dumpRegister(base, nFormals) << "." << name << "(" << dumpRegister(callData, nFormals) << ")";
MOTH_END_INSTR(CallProperty)
MOTH_BEGIN_INSTR(CallPropertyLookup)
- d << StackSlot::dump(base, nFormals) << "." << lookupIndex << "(" << StackSlot::dump(callData, nFormals) << ")";
+ d << dumpRegister(base, nFormals) << "." << lookupIndex << "(" << dumpRegister(callData, nFormals) << ")";
MOTH_END_INSTR(CallPropertyLookup)
MOTH_BEGIN_INSTR(CallElement)
- d << StackSlot::dump(base, nFormals) << "[" << StackSlot::dump(index, nFormals) << "]" << "(" << StackSlot::dump(callData, nFormals) << ")";
+ d << dumpRegister(base, nFormals) << "[" << dumpRegister(index, nFormals) << "]" << "(" << dumpRegister(callData, nFormals) << ")";
MOTH_END_INSTR(CallElement)
MOTH_BEGIN_INSTR(CallName)
- d << name << "(" << StackSlot::dump(callData, nFormals) << ")";
+ d << name << "(" << dumpRegister(callData, nFormals) << ")";
MOTH_END_INSTR(CallName)
MOTH_BEGIN_INSTR(CallPossiblyDirectEval)
- d << "(" << StackSlot::dump(callData, nFormals) << ")";
+ d << "(" << dumpRegister(callData, nFormals) << ")";
MOTH_END_INSTR(CallPossiblyDirectEval)
MOTH_BEGIN_INSTR(CallGlobalLookup)
- d << index << "(" << StackSlot::dump(callData, nFormals) << ")";
+ d << index << "(" << dumpRegister(callData, nFormals) << ")";
MOTH_END_INSTR(CallGlobalLookup)
MOTH_BEGIN_INSTR(SetExceptionHandler)
@@ -353,15 +378,15 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(SetExceptionFlag)
MOTH_BEGIN_INSTR(PushCatchContext)
- d << StackSlot::dump(reg, nFormals) << ", " << name;
+ d << dumpRegister(reg, nFormals) << ", " << name;
MOTH_END_INSTR(PushCatchContext)
MOTH_BEGIN_INSTR(PushWithContext)
- d << StackSlot::dump(reg, nFormals);
+ d << dumpRegister(reg, nFormals);
MOTH_END_INSTR(PushWithContext)
MOTH_BEGIN_INSTR(PopContext)
- d << StackSlot::dump(reg, nFormals);
+ d << dumpRegister(reg, nFormals);
MOTH_END_INSTR(PopContext)
MOTH_BEGIN_INSTR(ForeachIteratorObject)
@@ -371,11 +396,11 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(ForeachNextPropertyName)
MOTH_BEGIN_INSTR(DeleteMember)
- d << StackSlot::dump(base, nFormals) << "[" << member << "]";
+ d << dumpRegister(base, nFormals) << "[" << member << "]";
MOTH_END_INSTR(DeleteMember)
MOTH_BEGIN_INSTR(DeleteSubscript)
- d << StackSlot::dump(base, nFormals) << "[" << StackSlot::dump(index, nFormals) << "]";
+ d << dumpRegister(base, nFormals) << "[" << dumpRegister(index, nFormals) << "]";
MOTH_END_INSTR(DeleteSubscript)
MOTH_BEGIN_INSTR(DeleteName)
@@ -394,11 +419,11 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(DeclareVar)
MOTH_BEGIN_INSTR(DefineArray)
- d << StackSlot::dump(args, nFormals) << ", " << argc;
+ d << dumpRegister(args, nFormals) << ", " << argc;
MOTH_END_INSTR(DefineArray)
MOTH_BEGIN_INSTR(DefineObjectLiteral)
- d << StackSlot::dump(args, nFormals)
+ d << dumpRegister(args, nFormals)
<< ", " << internalClassId
<< ", " << arrayValueCount
<< ", " << arrayGetterSetterCountAndFlags;
@@ -414,7 +439,7 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(ConvertThisToObject)
MOTH_BEGIN_INSTR(Construct)
- d << "new" << StackSlot::dump(func, nFormals) << "(" << StackSlot::dump(callData, nFormals) << ")";
+ d << "new" << dumpRegister(func, nFormals) << "(" << dumpRegister(callData, nFormals) << ")";
MOTH_END_INSTR(Construct)
MOTH_BEGIN_INSTR(Jump)
@@ -447,43 +472,43 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_BEGIN_INSTR(CmpJmpEq)
- d << StackSlot::dump(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
+ d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
MOTH_END_INSTR(CmpJmpEq)
MOTH_BEGIN_INSTR(CmpJmpNe)
- d << StackSlot::dump(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
+ d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
MOTH_END_INSTR(CmpJmpNe)
MOTH_BEGIN_INSTR(CmpJmpGt)
- d << StackSlot::dump(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
+ d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
MOTH_END_INSTR(CmpJmpGt)
MOTH_BEGIN_INSTR(CmpJmpGe)
- d << StackSlot::dump(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
+ d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
MOTH_END_INSTR(CmpJmpGe)
MOTH_BEGIN_INSTR(CmpJmpLt)
- d << StackSlot::dump(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
+ d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
MOTH_END_INSTR(CmpJmpLt)
MOTH_BEGIN_INSTR(CmpJmpLe)
- d << StackSlot::dump(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
+ d << dumpRegister(lhs, nFormals) << ", " << ABSOLUTE_OFFSET();
MOTH_END_INSTR(CmpJmpLe)
MOTH_BEGIN_INSTR(JumpStrictEqual)
- d << StackSlot::dump(lhs, nFormals) << " " << ABSOLUTE_OFFSET();
+ d << dumpRegister(lhs, nFormals) << " " << ABSOLUTE_OFFSET();
MOTH_END_INSTR(JumpStrictEqual)
MOTH_BEGIN_INSTR(JumpStrictNotEqual)
- d << StackSlot::dump(lhs, nFormals) << " " << ABSOLUTE_OFFSET();
+ d << dumpRegister(lhs, nFormals) << " " << ABSOLUTE_OFFSET();
MOTH_END_INSTR(JumpStrictNotEqual)
MOTH_BEGIN_INSTR(JumpStrictEqualStackSlotInt)
- d << StackSlot::dump(lhs, nFormals) << ", " << rhs << " " << ABSOLUTE_OFFSET();
+ d << dumpRegister(lhs, nFormals) << ", " << rhs << " " << ABSOLUTE_OFFSET();
MOTH_END_INSTR(JumpStrictEqualStackSlotInt)
MOTH_BEGIN_INSTR(JumpStrictNotEqualStackSlotInt)
- d << StackSlot::dump(lhs, nFormals) << ", " << rhs << " " << ABSOLUTE_OFFSET();
+ d << dumpRegister(lhs, nFormals) << ", " << rhs << " " << ABSOLUTE_OFFSET();
MOTH_END_INSTR(JumpStrictNotEqualStackSlotInt)
MOTH_BEGIN_INSTR(UNot)
@@ -505,31 +530,31 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(PreDecrement)
MOTH_BEGIN_INSTR(Binop)
- d << alu << ", " << StackSlot::dump(lhs, nFormals) << ", acc";
+ d << alu << ", " << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(Binop)
MOTH_BEGIN_INSTR(Add)
- d << StackSlot::dump(lhs, nFormals) << ", acc";
+ d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(Add)
MOTH_BEGIN_INSTR(BitAnd)
- d << StackSlot::dump(lhs, nFormals) << ", acc";
+ d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(BitAnd)
MOTH_BEGIN_INSTR(BitOr)
- d << StackSlot::dump(lhs, nFormals) << ", acc";
+ d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(BitOr)
MOTH_BEGIN_INSTR(BitXor)
- d << StackSlot::dump(lhs, nFormals) << ", acc";
+ d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(BitXor)
MOTH_BEGIN_INSTR(Shr)
- d << StackSlot::dump(lhs, nFormals) << ", acc";
+ d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(Shr)
MOTH_BEGIN_INSTR(Shl)
- d << StackSlot::dump(lhs, nFormals) << ", acc";
+ d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(Shl)
MOTH_BEGIN_INSTR(BitAndConst)
@@ -553,15 +578,15 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_END_INSTR(ShlConst)
MOTH_BEGIN_INSTR(Mul)
- d << StackSlot::dump(lhs, nFormals) << ", acc";
+ d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(Mul)
MOTH_BEGIN_INSTR(Sub)
- d << StackSlot::dump(lhs, nFormals) << ", acc";
+ d << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(Sub)
MOTH_BEGIN_INSTR(BinopContext)
- d << alu << " " << StackSlot::dump(lhs, nFormals) << ", acc";
+ d << alu << " " << dumpRegister(lhs, nFormals) << ", acc";
MOTH_END_INSTR(BinopContext)
MOTH_BEGIN_INSTR(Ret)
@@ -573,11 +598,11 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
#endif // QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(LoadQmlContext)
- d << StackSlot::dump(result, nFormals);
+ d << dumpRegister(result, nFormals);
MOTH_END_INSTR(LoadQmlContext)
MOTH_BEGIN_INSTR(LoadQmlImportedScripts)
- d << StackSlot::dump(result, nFormals);
+ d << dumpRegister(result, nFormals);
MOTH_END_INSTR(LoadQmlImportedScripts)
MOTH_BEGIN_INSTR(LoadQmlSingleton)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index c70440fedd..8922493163 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -447,38 +447,8 @@ public:
return t;
}
- static StackSlot createArgument(int nFormals, int index) {
- Q_ASSERT(index >= -1);
- StackSlot t;
- t.index = index - nFormals;
- return t;
- }
-
- bool isRegister() const { return index >= 0; }
- bool isArgument() const { return index < 0; }
-
- int argIndex() const {
- Q_ASSERT(isArgument());
- return -index - 1;
- }
-
int stackSlot() const { return index; }
operator int() const { return index; }
-
- static QString dump(int reg, int nFormals) {
- StackSlot t;
- t.index = reg;
- return t.dump(nFormals);
- }
- QString dump(int nFormals) const {
- if (isRegister())
- return QStringLiteral("r%1").arg(index);
-
- if (nFormals + index == -1)
- return QStringLiteral("(this)");
-
- return QStringLiteral("a%1").arg(nFormals + index);
- }
};
inline bool operator==(const StackSlot &l, const StackSlot &r) { return l.stackSlot() == r.stackSlot(); }
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 8bcf89c1a4..ec027c9fd3 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -72,10 +72,21 @@ struct CatchContext;
struct QmlContext;
struct QQmlContextWrapper;
-// Attention: Make sure that this structure is the same size on 32-bit and 64-bit
-// architecture or you'll have to change the JIT code.
struct CallData
{
+ enum Offsets {
+ Function = 0,
+ Context = 1,
+ Accumulator = 2,
+ This = 3,
+ Argc = 4
+ };
+
+ Value function;
+ Value context;
+ Value accumulator;
+ Value thisObject;
+
// below is to be compatible with Value. Initialize tag to 0
#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
uint tag;
@@ -88,17 +99,14 @@ struct CallData
return i < argc ? args[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
}
- Value function;
- Value context;
- Value thisObject;
Value args[1];
static Q_DECL_CONSTEXPR int HeaderSize() { return offsetof(CallData, args) / sizeof(QV4::Value); }
};
Q_STATIC_ASSERT(std::is_standard_layout<CallData>::value);
-Q_STATIC_ASSERT(offsetof(CallData, thisObject) == 3*sizeof(Value));
-Q_STATIC_ASSERT(offsetof(CallData, args) == 4*sizeof(Value));
+Q_STATIC_ASSERT(offsetof(CallData, thisObject) == CallData::This*sizeof(Value));
+Q_STATIC_ASSERT(offsetof(CallData, args) == 5*sizeof(Value));
namespace Heap {
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 618565a806..531bfa3737 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -809,7 +809,7 @@ int CppStackFrame::lineNumber() const
}
ReturnedValue CppStackFrame::thisObject() const {
- return jsFrame->stack[-(int)v4Function->nFormals - 1].asReturnedValue();
+ return jsFrame->thisObject.asReturnedValue();
}
StackTrace ExecutionEngine::stackTrace(int frameLimit) const
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 4cee69ed33..fcadf57508 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -87,26 +87,10 @@ struct CompilationUnit;
struct InternalClass;
struct InternalClassPool;
-struct JSStackFrame {
- enum Offsets {
- JSFunction = 0,
- Context = 1,
- Accumulator = 2
- };
- // callData is directly before this
- union {
- Value jsFunction;
- Value stack[1];
- };
- Value context;
- Value accumulator; // ###
- // registers follow
-};
-
struct Q_QML_EXPORT CppStackFrame {
CppStackFrame *parent;
Function *v4Function;
- JSStackFrame *jsFrame;
+ CallData *jsFrame;
const uchar *instructionPointer;
QString source() const;
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 724d41be82..08963f18b4 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -369,7 +369,7 @@ ReturnedValue ScriptFunction::construct(const Managed *that, CallData *callData)
Q_ASSERT(v4Function);
callData->context = f->scope();
-ReturnedValue result = v4Function->call(callData);
+ ReturnedValue result = v4Function->call(callData);
if (Q_UNLIKELY(v4->hasException))
return Encode::undefined();
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index b21f23c34e..9522e919bd 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -381,7 +381,7 @@ struct ScopedStackFrame {
frame.parent = scope.engine->currentStackFrame;
if (!context)
return;
- frame.jsFrame = reinterpret_cast<JSStackFrame *>(scope.alloc(sizeof(JSStackFrame)/sizeof(Value)));
+ frame.jsFrame = reinterpret_cast<CallData *>(scope.alloc(sizeof(CallData)/sizeof(Value)));
frame.jsFrame->context = context;
frame.v4Function = frame.parent ? frame.parent->v4Function : 0;
scope.engine->currentStackFrame = &frame;
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index ad3fd0bce1..da0b06dac7 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -336,7 +336,7 @@ static struct InstrCount {
static inline Heap::CallContext *getScope(Value *stack, int level)
{
- Heap::ExecutionContext *scope = static_cast<ExecutionContext &>(stack[JSStackFrame::Context]).d();
+ Heap::ExecutionContext *scope = static_cast<ExecutionContext &>(stack[CallData::Context]).d();
while (level > 0) {
--level;
scope = scope->outer;
@@ -499,22 +499,21 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
Profiling::FunctionCallProfiler(engine, function);
Value *jsStackTop = engine->jsStackTop;
- engine->jsStackTop = reinterpret_cast<QV4::Value *>(callData) + sizeof(CallData)/sizeof(Value) - 1 + (int)function->nFormals;
- for (int i = callData->argc; i < (int)function->nFormals; ++i)
- callData->args[i] = Encode::undefined();
CppStackFrame frame;
frame.parent = engine->currentStackFrame;
frame.v4Function = function;
frame.instructionPointer = function->codeData;
+ frame.jsFrame = callData;
engine->currentStackFrame = &frame;
- QV4::Value *stack = nullptr;
- const uchar *exceptionHandler = 0;
+ engine->jsStackTop = reinterpret_cast<QV4::Value *>(callData) + function->compiledFunction->nRegisters + 1;
+ // clear out remaining arguments and local registers
+ for (Value *v = callData->args + callData->argc; v < jsStackTop; ++v)
+ *v = Encode::undefined();
- stack = engine->jsAlloca(function->compiledFunction->nRegisters + sizeof(JSStackFrame)/sizeof(QV4::Value));
- frame.jsFrame = reinterpret_cast<JSStackFrame *>(stack);
- frame.jsFrame->context = callData->context;
+ QV4::Value *stack = reinterpret_cast<QV4::Value *>(callData);
+ const uchar *exceptionHandler = 0;
QV4::Value &accumulator = frame.jsFrame->accumulator;
QV4::ReturnedValue acc = Encode::undefined();
@@ -572,13 +571,13 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
MOTH_END_INSTR(MoveReg)
MOTH_BEGIN_INSTR(LoadLocal)
- auto cc = static_cast<Heap::CallContext *>(stack[JSStackFrame::Context].m());
+ auto cc = static_cast<Heap::CallContext *>(stack[CallData::Context].m());
acc = cc->locals[index].asReturnedValue();
MOTH_END_INSTR(LoadLocal)
MOTH_BEGIN_INSTR(StoreLocal)
CHECK_EXCEPTION;
- auto cc = static_cast<Heap::CallContext *>(stack[JSStackFrame::Context].m());
+ auto cc = static_cast<Heap::CallContext *>(stack[CallData::Context].m());
QV4::WriteBarrier::write(engine, cc, cc->locals.values + index, ACC);
MOTH_END_INSTR(StoreLocal)
@@ -803,9 +802,9 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
MOTH_END_INSTR(SetException)
MOTH_BEGIN_INSTR(PushCatchContext)
- STACK_VALUE(reg) = STACK_VALUE(JSStackFrame::Context);
- ExecutionContext *c = static_cast<ExecutionContext *>(stack + JSStackFrame::Context);
- STACK_VALUE(JSStackFrame::Context) = Runtime::method_createCatchContext(c, name);
+ STACK_VALUE(reg) = STACK_VALUE(CallData::Context);
+ ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context);
+ STACK_VALUE(CallData::Context) = Runtime::method_createCatchContext(c, name);
MOTH_END_INSTR(PushCatchContext)
MOTH_BEGIN_INSTR(PushWithContext)
@@ -813,13 +812,13 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
STORE_ACC();
accumulator = accumulator.toObject(engine);
CHECK_EXCEPTION;
- STACK_VALUE(reg) = STACK_VALUE(JSStackFrame::Context);
- ExecutionContext *c = static_cast<ExecutionContext *>(stack + JSStackFrame::Context);
- STACK_VALUE(JSStackFrame::Context) = Runtime::method_createWithContext(c, accumulator);
+ STACK_VALUE(reg) = STACK_VALUE(CallData::Context);
+ ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context);
+ STACK_VALUE(CallData::Context) = Runtime::method_createWithContext(c, accumulator);
MOTH_END_INSTR(PushWithContext)
MOTH_BEGIN_INSTR(PopContext)
- STACK_VALUE(JSStackFrame::Context) = STACK_VALUE(reg);
+ STACK_VALUE(CallData::Context) = STACK_VALUE(reg);
MOTH_END_INSTR(PopContext)
MOTH_BEGIN_INSTR(ForeachIteratorObject)
@@ -906,7 +905,7 @@ QV4::ReturnedValue VME::exec(CallData *callData, QV4::Function *function)
MOTH_END_INSTR(CreateUnmappedArgumentsObject)
MOTH_BEGIN_INSTR(ConvertThisToObject)
- Value *t = &stack[-(int)function->nFormals - 1];
+ Value *t = &stack[CallData::This];
if (!t->isObject()) {
if (t->isNullOrUndefined()) {
*t = engine->globalObject->asReturnedValue();