aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4jscall_p.h
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-05-17 16:38:25 +0200
committerUlf Hermann <ulf.hermann@qt.io>2021-06-10 11:53:19 +0200
commite20650e0702259b4be79be85a3d27e45db42efc1 (patch)
tree7536cee98f4cc502774f807d1a609940cd20d4f5 /src/qml/jsruntime/qv4jscall_p.h
parent7fa28f98824a94396106eadfc028b329985a0cfc (diff)
Eliminate JS call frame from metatypes calls
If we call an AOT-compiled function we never need the JavaScript call frame. We can just skip its setup and save some overhead. Change-Id: I39dc2ca6eea5b5a66f3b87b642a310534cecf6cd Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4jscall_p.h')
-rw-r--r--src/qml/jsruntime/qv4jscall_p.h53
1 files changed, 32 insertions, 21 deletions
diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h
index c6d320ac20..337b86dbc0 100644
--- a/src/qml/jsruntime/qv4jscall_p.h
+++ b/src/qml/jsruntime/qv4jscall_p.h
@@ -56,6 +56,7 @@
#include "qv4context_p.h"
#include "qv4scopedvalue_p.h"
#include "qv4stackframe_p.h"
+#include "qv4qobjectwrapper_p.h"
#include <private/qv4alloca_p.h>
QT_BEGIN_NAMESPACE
@@ -134,27 +135,24 @@ ReturnedValue FunctionObject::call(const JSCallData &data) const
void populateJSCallArguments(ExecutionEngine *v4, JSCallArguments &jsCall, int argc,
void **args, const QMetaType *types);
-struct ScopedStackFrame {
- Scope &scope;
- CppStackFrame frame;
-
- ScopedStackFrame(Scope &scope, Heap::ExecutionContext *context)
- : scope(scope)
+struct ScopedStackFrame
+{
+ ScopedStackFrame(const Scope &scope, ExecutionContext *context)
+ : engine(scope.engine)
{
- frame.setParentFrame(scope.engine->currentStackFrame);
- if (!context)
- return;
- frame.jsFrame = reinterpret_cast<CallData *>(scope.alloc(sizeof(CallData)/sizeof(Value)));
- frame.jsFrame->context = context;
- if (auto *parent = frame.parentFrame())
- frame.v4Function = parent->v4Function;
- else
- frame.v4Function = nullptr;
- scope.engine->currentStackFrame = &frame;
+ frame.init(engine->currentStackFrame ? engine->currentStackFrame->v4Function : nullptr,
+ nullptr, context, nullptr, nullptr, 0);
+ frame.push(engine);
}
- ~ScopedStackFrame() {
- scope.engine->currentStackFrame = frame.parentFrame();
+
+ ~ScopedStackFrame()
+ {
+ frame.pop(engine);
}
+
+private:
+ ExecutionEngine *engine = nullptr;
+ MetaTypesStackFrame frame;
};
template<typename Callable>
@@ -189,7 +187,10 @@ ReturnedValue convertAndCall(
values[0] = nullptr;
}
- call(thisObject, values, types, argc);
+ if (const QV4::QObjectWrapper *cppThisObject = thisObject->as<QV4::QObjectWrapper>())
+ call(cppThisObject->object(), values, types, argc);
+ else
+ call(nullptr, values, types, argc);
ReturnedValue result;
if (values[0]) {
@@ -206,7 +207,7 @@ ReturnedValue convertAndCall(
}
template<typename Callable>
-bool convertAndCall(ExecutionEngine *engine, const Value *thisObject,
+bool convertAndCall(ExecutionEngine *engine, QObject *thisObject,
void **a, const QMetaType *types, int argc, Callable call)
{
Scope scope(engine);
@@ -215,7 +216,17 @@ bool convertAndCall(ExecutionEngine *engine, const Value *thisObject,
for (int ii = 0; ii < argc; ++ii)
jsCallData.args[ii] = engine->metaTypeToJS(types[ii + 1], a[ii + 1]);
- ScopedValue jsResult(scope, call(thisObject, jsCallData.args, argc));
+ ScopedObject jsThisObject(scope);
+ if (thisObject) {
+ // The result of wrap() can only be null, undefined, or an object.
+ jsThisObject = QV4::QObjectWrapper::wrap(engine, thisObject);
+ if (!jsThisObject)
+ jsThisObject = engine->globalObject;
+ } else {
+ jsThisObject = engine->globalObject;
+ }
+
+ ScopedValue jsResult(scope, call(jsThisObject, jsCallData.args, argc));
void *result = a[0];
if (!result)
return !jsResult->isUndefined();