diff options
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit.cpp | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function.cpp | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function_p.h | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlprivate.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertybinding.cpp | 15 |
6 files changed, 42 insertions, 11 deletions
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index 94fa3e0fbf..4b0fe0f5f6 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -38,7 +38,9 @@ ****************************************************************************/ #include "qml/qqmlprivate.h" +#include "qv4engine_p.h" #include "qv4executablecompilationunit_p.h" +#include "qv4stackframe_p.h" #include <private/qv4engine_p.h> #include <private/qv4regexp_p.h> @@ -212,13 +214,11 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine) const QQmlPrivate::AOTCompiledFunction *aotFunction = aotCompiledFunctions; for (int i = 0 ;i < runtimeFunctions.size(); ++i) { const QV4::CompiledData::Function *compiledFunction = data->functionAt(i); - runtimeFunctions[i] = QV4::Function::create(engine, this, compiledFunction); + runtimeFunctions[i] = QV4::Function::create(engine, this, compiledFunction, aotFunction); if (aotFunction) { if (aotFunction->functionPtr) { - if (aotFunction->index == i) { - runtimeFunctions[i]->jittedCode = aotFunction->functionPtr; + if (aotFunction->index == i) ++aotFunction; - } } else { aotFunction = nullptr; } diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index aeb4835c40..76eda5dcde 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -37,6 +37,7 @@ ** ****************************************************************************/ +#include "qml/qqmlprivate.h" #include "qv4function_p.h" #include "qv4functionobject_p.h" #include "qv4managed_p.h" @@ -74,9 +75,10 @@ ReturnedValue Function::call(const Value *thisObject, const Value *argv, int arg } Function *Function::create(ExecutionEngine *engine, ExecutableCompilationUnit *unit, - const CompiledData::Function *function) + const CompiledData::Function *function, + const QQmlPrivate::AOTCompiledFunction *aotFunction) { - return new Function(engine, unit, function); + return new Function(engine, unit, function, aotFunction); } void Function::destroy() @@ -85,12 +87,14 @@ void Function::destroy() } Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit, - const CompiledData::Function *function) + const CompiledData::Function *function, + const QQmlPrivate::AOTCompiledFunction *aotFunction) : FunctionData(unit) , compiledFunction(function) , codeData(function->code()) , jittedCode(nullptr) , codeRef(nullptr) + , aotFunction(aotFunction) { Scope scope(engine); Scoped<InternalClass> ic(scope, engine->internalClasses(EngineBase::Class_CallContext)); diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index 51960863c4..ce9151c225 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -50,6 +50,7 @@ // We mean it. // +#include <qqmlprivate.h> #include "qv4global_p.h" #include <private/qv4executablecompilationunit_p.h> #include <private/qv4context_p.h> @@ -82,7 +83,7 @@ Q_STATIC_ASSERT(std::is_standard_layout< FunctionData >::value); struct Q_QML_EXPORT Function : public FunctionData { private: Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit, - const CompiledData::Function *function); + const CompiledData::Function *function, const QQmlPrivate::AOTCompiledFunction *aotFunction); ~Function(); public: @@ -106,6 +107,7 @@ public: typedef ReturnedValue (*JittedCode)(CppStackFrame *, ExecutionEngine *); JittedCode jittedCode; JSC::MacroAssemblerCodeRef *codeRef; + const QQmlPrivate::AOTCompiledFunction *aotFunction = nullptr; // first nArguments names in internalClass are the actual arguments Heap::InternalClass *internalClass; @@ -114,7 +116,8 @@ public: bool isEval = false; static Function *create(ExecutionEngine *engine, ExecutableCompilationUnit *unit, - const CompiledData::Function *function); + const CompiledData::Function *function, + const QQmlPrivate::AOTCompiledFunction *aotFunction); void destroy(); // used when dynamically assigning signal handlers (QQmlConnection) diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index fb103d492d..7772b34c82 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -58,6 +58,7 @@ #include <private/qv4generatorobject_p.h> #include <private/qv4alloca_p.h> #include <private/qqmljavascriptexpression_p.h> +#include <private/qv4qmlcontext_p.h> #include <iostream> #if QT_CONFIG(qml_jit) @@ -458,6 +459,13 @@ ReturnedValue VME::exec(CppStackFrame *frame, ExecutionEngine *engine) ReturnedValue result; if (function->jittedCode != nullptr && debugger == nullptr) { result = function->jittedCode(frame, engine); + } else if (function->aotFunction) { + Scope scope(engine); + Scoped<QmlContext> qmlContext(scope, engine->qmlContext()); + + QVariant resultVariant(function->aotFunction->returnType.id(), nullptr); + function->aotFunction->functionPtr(qmlContext->qmlContext()->asQQmlContext(), qmlContext->qmlScope(), resultVariant.data()); + result = engine->fromVariant(resultVariant); } else { // interpreter result = interpret(frame, engine, function->codeData); diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index cc1a14d24b..79969caa56 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -71,6 +71,7 @@ QT_BEGIN_NAMESPACE class QQmlPropertyValueInterceptor; +class QQmlContext; namespace QQmlPrivate { struct CachedQmlUnit; @@ -84,7 +85,6 @@ namespace CompiledData { struct Unit; struct CompilationUnit; } -struct CppStackFrame; } namespace QmlIR { struct Document; @@ -453,7 +453,8 @@ namespace QQmlPrivate struct AOTCompiledFunction { int index; - quint64 (*functionPtr)(QV4::CppStackFrame *, QV4::ExecutionEngine *); + QMetaType returnType; + void (*functionPtr)(QQmlContext *context, QObject *scopeObject, void *resultPtr); }; struct CachedQmlUnit { diff --git a/src/qml/qml/qqmlpropertybinding.cpp b/src/qml/qml/qqmlpropertybinding.cpp index 9fffafa649..e005635fad 100644 --- a/src/qml/qml/qqmlpropertybinding.cpp +++ b/src/qml/qml/qqmlpropertybinding.cpp @@ -47,6 +47,21 @@ QUntypedPropertyBinding QQmlPropertyBinding::create(const QQmlPropertyData *pd, QObject *obj, const QQmlRefPointer<QQmlContextData> &ctxt, QV4::ExecutionContext *scope) { + if (auto aotFunction = function->aotFunction; aotFunction && aotFunction->returnType.id() == pd->propType()) { + return QUntypedPropertyBinding(aotFunction->returnType, + [ + aotFunction, + unit = QQmlRefPointer<QV4::ExecutableCompilationUnit>(function->executableCompilationUnit()), + scopeObject = QPointer<QObject>(obj), + context = ctxt + ](const QMetaType &, void *dataPtr) -> QUntypedPropertyBinding::BindingEvaluationResult { + Q_UNUSED(unit); // to keep refcount + aotFunction->functionPtr(context->asQQmlContext(), scopeObject.data(), dataPtr); + return QPropertyBindingError::NoError; + }, + QPropertyBindingSourceLocation()); + } + auto binding = new QQmlPropertyBinding(QMetaType(pd->propType())); binding->setNotifyOnValueChanged(true); binding->setContext(ctxt); |