aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-08-07 08:10:15 +0200
committerLars Knoll <lars.knoll@qt.io>2017-08-10 08:18:05 +0000
commitfd221cf6e056b7239fc2fa2faeccd9ddeb542199 (patch)
treea453f21ac01aa01a16a7a4f378ec2ed60e07512f
parent01c338023a3a604bb24c2efb18d48f9bac33e6bc (diff)
Introduce a JS stack frame that corresponds to the C++ stack frame
The frame currently contains the function itself and the current context. Change-Id: I7d3402627fbc90e860a7bdc277585f365f5b4cb5 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qml/compiler/qv4codegen.cpp3
-rw-r--r--src/qml/jsruntime/qv4context.cpp4
-rw-r--r--src/qml/jsruntime/qv4enginebase_p.h8
-rw-r--r--src/qml/jsruntime/qv4function.cpp3
-rw-r--r--src/qml/jsruntime/qv4function_p.h6
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4profiling_p.h12
-rw-r--r--src/qml/jsruntime/qv4script.cpp2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp8
-rw-r--r--src/qml/jsruntime/qv4vme_moth_p.h2
10 files changed, 32 insertions, 18 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index f75839ad4b..6505469a8b 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1771,6 +1771,9 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
savedBytecodeGenerator = bytecodeGenerator;
bytecodeGenerator = &bytecode;
+ // allocate the js stack frame (Context & js Function)
+ bytecodeGenerator->newRegisterArray(2);
+
int returnAddress = bytecodeGenerator->newRegister();
if (!_context->parent || _context->usesArgumentsObject == Context::ArgumentsObjectUnknown)
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 1019770275..8678529916 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -244,7 +244,7 @@ ReturnedValue ExecutionContext::call(ExecutionEngine *engine, CallData *callData
ctx->d()->function.set(engine, f->d());
engine->pushContext(ctx);
- ReturnedValue res = Q_V4_PROFILE(engine, function);
+ ReturnedValue res = Q_V4_PROFILE(engine, function, f);
if (function->hasQmlDependencies)
QQmlPropertyCapture::registerQmlDependencies(engine, function->compiledFunction);
@@ -271,7 +271,7 @@ ReturnedValue QV4::ExecutionContext::simpleCall(ExecutionEngine *engine, CallDat
engine->pushContext(ctx);
Q_ASSERT(engine->current == ctx);
- ReturnedValue res = Q_V4_PROFILE(engine, function);
+ ReturnedValue res = Q_V4_PROFILE(engine, function, 0);
if (function->hasQmlDependencies)
QQmlPropertyCapture::registerQmlDependencies(engine, function->compiledFunction);
diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h
index cc049fb296..a713e8eab4 100644
--- a/src/qml/jsruntime/qv4enginebase_p.h
+++ b/src/qml/jsruntime/qv4enginebase_p.h
@@ -63,9 +63,17 @@ namespace QV4 {
#pragma pack(push, 1)
#endif
struct EngineBase {
+ struct JSStackFrame {
+ // callData is directly before this
+ QV4::Value jsFunction;
+ QV4::Value context;
+ // registers follow
+ };
+
struct StackFrame {
StackFrame *parent;
Function *v4Function;
+ JSStackFrame *jsFrame;
int line = -1;
int column = -1;
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index d21afa3b87..bcc776dc98 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -49,8 +49,7 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function,
- ReturnedValue (*codePtr)(Function *))
+Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function, Code codePtr)
: compiledFunction(function)
, compilationUnit(unit)
, code(codePtr)
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index 9fc51e90af..17311ca3c1 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -63,7 +63,8 @@ struct Q_QML_EXPORT Function {
const CompiledData::Function *compiledFunction;
CompiledData::CompilationUnit *compilationUnit;
- ReturnedValue (*code)(Function *);
+ typedef ReturnedValue (*Code)(Function *, const FunctionObject *);
+ Code code;
const uchar *codeData;
// first nArguments names in internalClass are the actual arguments
@@ -72,8 +73,7 @@ struct Q_QML_EXPORT Function {
bool hasQmlDependencies;
bool canUseSimpleCall;
- Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function,
- ReturnedValue (*codePtr)(Function *));
+ Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function, Code codePtr);
~Function();
// used when dynamically assigning signal handlers (QQmlConnection)
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 69d9683eaa..71140e5386 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -386,7 +386,7 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall) const
ctx->d()->strictMode = false;
ctx->d()->v4Function = function;
- return Q_V4_PROFILE(ctx->engine(), function);
+ return Q_V4_PROFILE(ctx->engine(), function, 0);
}
diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h
index e7b6909690..adf9853f62 100644
--- a/src/qml/jsruntime/qv4profiling_p.h
+++ b/src/qml/jsruntime/qv4profiling_p.h
@@ -61,7 +61,7 @@
#define Q_V4_PROFILE_ALLOC(engine, size, type) (!engine)
#define Q_V4_PROFILE_DEALLOC(engine, size, type) (!engine)
-#define Q_V4_PROFILE(engine, function) (function->code(function))
+#define Q_V4_PROFILE(engine, function, jsFunction) (function->code(function, jsFunction))
QT_BEGIN_NAMESPACE
@@ -85,11 +85,11 @@ QT_END_NAMESPACE
(engine->profiler()->featuresEnabled & (1 << Profiling::FeatureMemoryAllocation)) ?\
engine->profiler()->trackDealloc(size, type) : false)
-#define Q_V4_PROFILE(engine, function)\
+#define Q_V4_PROFILE(engine, function, jsFunction)\
(Q_UNLIKELY(engine->profiler()) &&\
(engine->profiler()->featuresEnabled & (1 << Profiling::FeatureFunctionCall)) ?\
- Profiling::FunctionCallProfiler::profileCall(engine->profiler(), function) :\
- function->code(function))
+ Profiling::FunctionCallProfiler::profileCall(engine->profiler(), function, jsFunction) :\
+ function->code(function, jsFunction))
QT_BEGIN_NAMESPACE
@@ -279,10 +279,10 @@ public:
profiler->m_data.append(FunctionCall(function, startTime, profiler->m_timer.nsecsElapsed()));
}
- static ReturnedValue profileCall(Profiler *profiler, Function *function)
+ static ReturnedValue profileCall(Profiler *profiler, Function *function, const FunctionObject *jsFunction)
{
FunctionCallProfiler callProfiler(profiler, function);
- return function->code(function);
+ return function->code(function, jsFunction);
}
Profiler *profiler;
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 2b97a0f1d4..188b66d8d3 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -153,7 +153,7 @@ ReturnedValue Script::run()
scope->d()->strictMode = vmFunction->isStrict();
scope->d()->v4Function = vmFunction;
- return Q_V4_PROFILE(engine, vmFunction);
+ return Q_V4_PROFILE(engine, vmFunction, 0);
} else {
Scoped<QmlContext> qml(valueScope, qmlContext.value());
ScopedCallData callData(valueScope);
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 21a2095196..747101fef2 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -432,7 +432,7 @@ static inline const QV4::Value &constant(Function *function, int index)
return function->compilationUnit->constants[index];
}
-QV4::ReturnedValue VME::exec(Function *function)
+QV4::ReturnedValue VME::exec(Function *function, const FunctionObject *jsFunction)
{
qt_v4ResolvePendingBreakpointsHook();
@@ -456,11 +456,15 @@ QV4::ReturnedValue VME::exec(Function *function)
QV4::Scope scope(engine);
int nFormals = function->nFormals;
- stack = scope.alloc(function->compiledFunction->nRegisters + nFormals + 2);
+ stack = scope.alloc(function->compiledFunction->nRegisters + nFormals + 2 + sizeof(EngineBase::JSStackFrame)/sizeof(QV4::Value));
QV4::Value &accumulator = *stack;
++stack;
memcpy(stack, &engine->current->callData->thisObject, (nFormals + 1)*sizeof(Value));
stack += nFormals + 1;
+ frame.jsFrame = reinterpret_cast<EngineBase::JSStackFrame *>(stack);
+ frame.jsFrame->context = engine->current;
+ if (jsFunction)
+ frame.jsFrame->jsFunction = *jsFunction;
if (QV4::Debugging::Debugger *debugger = engine->debugger())
debugger->enteringFunction();
diff --git a/src/qml/jsruntime/qv4vme_moth_p.h b/src/qml/jsruntime/qv4vme_moth_p.h
index 51ea5fbdac..5055af65fd 100644
--- a/src/qml/jsruntime/qv4vme_moth_p.h
+++ b/src/qml/jsruntime/qv4vme_moth_p.h
@@ -65,7 +65,7 @@ namespace Moth {
class VME
{
public:
- static QV4::ReturnedValue exec(QV4::Function *);
+ static QV4::ReturnedValue exec(QV4::Function *, const FunctionObject *jsFunction = 0);
};
} // namespace Moth