aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
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/jsruntime
parent20596907289d50be3a5e1597ba62cefb733e6f19 (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.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
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();