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/jsruntime | |
parent | 20596907289d50be3a5e1597ba62cefb733e6f19 (diff) |
Unify JSStackFrame and CallData
Change-Id: I4494dae8166026074c9efc74bac62de9d3fa2342
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-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 |
6 files changed, 37 insertions, 46 deletions
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(); |