diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-08-30 15:16:15 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-09-01 12:30:43 +0000 |
commit | cc7a858698063649f9770a89949354e2b58ae288 (patch) | |
tree | 5a79c1335192ed757edd69b5b9ded873423aa0bd /src/qml | |
parent | 20596907289d50be3a5e1597ba62cefb733e6f19 (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.cpp | 18 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen_p.h | 4 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth.cpp | 131 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 30 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 22 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 18 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4scopedvalue_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 37 |
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(); |