diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2024-04-30 11:55:01 +0200 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2024-05-14 14:16:57 +0200 |
| commit | 8b6a9403bf2e04d34b9b07d2780186029fab99d0 (patch) | |
| tree | 3849365bf54aea733e6ee3af0165bcb95215c9d2 /src/qml/jsruntime/qv4qobjectwrapper.cpp | |
| parent | 2f7a97806e950967ba67b6f07614ca0def8bda48 (diff) | |
V4: Slim down FunctionObject
Most FunctionObjects do not actually need their custom jsCall members.
They will only call the functions from the vtable anyway. FunctionObject
can therefore be split into a static and a dynamic variant. Only the
dyanmic variant needs to carry (and invoke) the extra pointer. The
jsCallWithMetaTypes pointer is completely pointless because none of the
dynamic functions actually implement it.
Furthermore, the QV4::Function and QV4::ExecutionContext pointers in
FunctionObject are only needed by actual JavaScript functions. The
builtins that like to be dynamic functions never need them. Therefore,
split out another class for this.
In the generic FunctionObject, we need the capability to decide at run
time whether the function shall be a constructor or not. Add a flag to
replace the check for jsCallAsConstructor.
Also, where we can, avoid the pessimization of checking whether a
function is a constructor before trying to call it as constructor.
Rather have the default implementation throw the exception.
As a side effect, for most functions we don't need an ExecutionContext
anymore. The engine is enough.
Task-number: QTBUG-124662
Change-Id: Iac657fa71288dd6ec230a33de2986ba3bcf4628c
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4qobjectwrapper.cpp')
| -rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 38 |
1 files changed, 16 insertions, 22 deletions
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 5f85aae89e..2edeb54b11 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -360,20 +360,15 @@ ReturnedValue QObjectWrapper::getProperty( Q_ASSERT(vmemo); return vmemo->vmeMethod(property->coreIndex()); } else if (property->isV4Function()) { - Scope scope(engine); - ScopedContext global(scope, engine->qmlContext()); - if (!global) - global = engine->rootContext(); return QObjectMethod::create( - global, (flags & AttachMethods) ? wrapper : nullptr, property->coreIndex()); + engine, (flags & AttachMethods) ? wrapper : nullptr, property->coreIndex()); } else if (property->isSignalHandler()) { QmlSignalHandler::initProto(engine); return engine->memoryManager->allocate<QmlSignalHandler>( object, property->coreIndex())->asReturnedValue(); } else { - ExecutionContext *global = engine->rootContext(); return QObjectMethod::create( - global, (flags & AttachMethods) ? wrapper : nullptr, property->coreIndex()); + engine, (flags & AttachMethods) ? wrapper : nullptr, property->coreIndex()); } } @@ -405,8 +400,7 @@ static OptionalReturnedValue getDestroyOrToStringMethod( if (hasProperty) *hasProperty = true; - ExecutionContext *global = v4->rootContext(); - return OptionalReturnedValue(QObjectMethod::create(global, qobj, index)); + return OptionalReturnedValue(QObjectMethod::create(v4, qobj, index)); } static OptionalReturnedValue getPropertyFromImports( @@ -641,7 +635,7 @@ void QObjectWrapper::setProperty( QQmlRefPointer<QQmlContextData> callingQmlContext = scope.engine->callingQmlContext(); Scoped<QQmlBindingFunction> bindingFunction(scope, (const Value &)f); - ScopedFunctionObject f(scope, bindingFunction->bindingFunction()); + Scoped<JavaScriptFunctionObject> f(scope, bindingFunction->bindingFunction()); ScopedContext ctx(scope, f->scope()); // binding assignment. @@ -2559,21 +2553,22 @@ ReturnedValue CallArgument::toValue(ExecutionEngine *engine) return Encode::undefined(); } -ReturnedValue QObjectMethod::create(ExecutionContext *scope, Heap::Object *wrapper, int index) +ReturnedValue QObjectMethod::create(ExecutionEngine *engine, Heap::Object *wrapper, int index) { - Scope valueScope(scope); + Scope valueScope(engine); Scoped<QObjectMethod> method( valueScope, - valueScope.engine->memoryManager->allocate<QObjectMethod>(scope, wrapper, index)); + engine->memoryManager->allocate<QObjectMethod>(engine, wrapper, index)); return method.asReturnedValue(); } -ReturnedValue QObjectMethod::create(ExecutionContext *scope, Heap::QQmlValueTypeWrapper *valueType, int index) +ReturnedValue QObjectMethod::create( + ExecutionEngine *engine, Heap::QQmlValueTypeWrapper *valueType, int index) { - Scope valueScope(scope); + Scope valueScope(engine); Scoped<QObjectMethod> method( valueScope, - valueScope.engine->memoryManager->allocate<QObjectMethod>(scope, valueType, index)); + engine->memoryManager->allocate<QObjectMethod>(engine, valueType, index)); return method.asReturnedValue(); } @@ -2596,11 +2591,10 @@ ReturnedValue QObjectMethod::create( } } - Scoped<ExecutionContext> context(valueScope, cloneFrom->scope.get()); Scoped<QObjectMethod> method( valueScope, engine->memoryManager->allocate<QV4::QObjectMethod>( - context, valueTypeWrapper ? valueTypeWrapper->d() : object, cloneFrom->index)); + engine, valueTypeWrapper ? valueTypeWrapper->d() : object, cloneFrom->index)); method->d()->methodCount = cloneFrom->methodCount; @@ -2626,10 +2620,10 @@ ReturnedValue QObjectMethod::create( return method.asReturnedValue(); } -void Heap::QObjectMethod::init(QV4::ExecutionContext *scope, Object *object, int methodIndex) +void Heap::QObjectMethod::init(QV4::ExecutionEngine *engine, Object *object, int methodIndex) { - Heap::FunctionObject::init(scope); - wrapper.set(internalClass->engine, object); + Heap::FunctionObject::init(engine); + wrapper.set(engine, object); index = methodIndex; } @@ -3106,7 +3100,7 @@ ReturnedValue QmlSignalHandler::call(const Value *thisObject, const Value *argv, Scope scope(engine()); Scoped<QObjectMethod> method( scope, QObjectMethod::create( - scope.engine->rootContext(), + scope.engine, static_cast<Heap::QObjectWrapper *>(nullptr), signalIndex())); |
