diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2022-02-14 21:28:51 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2022-02-21 18:20:56 +0100 |
commit | 214b92b00a2f9c1527401a1a20bfcc2b30e8efab (patch) | |
tree | 2380e8f9157c6adbf9fa1073c1429deb2984acec /src/qml/qml/qqmlvmemetaobject.cpp | |
parent | ac4f3aa7cf4af7b0b48d2d9c44063ea19aea90b1 (diff) |
Cleanup QQmlGuard and related classes
An investigation of uses of QQmlGuard (+ related classes) yielded the
following results:
- objectDestroyed is the only virtual method of QQmlGuard (besides the
dtor)
- we never have an owning pointer of type QQmlGuard * to one of its
subclasess
=> Therefore, we can replace the use of virtual methods with a function
pointer, which avoids the issue of duplicated vtables.
None of the objectDestroyed actually cares about the object we pass to
them, so we can leave it out in the function pointer. As everything is
private API, we could easily bring it back if the need arises in the
future.
By moving the function pointer into QQmlGuardImpl we also avoid UB in
qqmlengine.cpp, which cast any QQmlGuardImpl pointer to
QQmlGuard<QObject>. This, however, is wrong as QQmlGuard<T> does not
inherit from QQmlGuard<QObject>, even if T inherits from QObject. As we
now can sipmly access the pointer from QQmlGuardImpl, we can side-step
any casting woes alltogether.
Moreover, we use this opportunity to let QQmlStrongJSObjectReference
drectly inherit from QQmlGuardImpl. This requires duplicating some of
the QQmlGuard API, but on the other hand avoids busy-work to hide no
longer desired API.
Unfortunately, we can no longer inherit privately from QQmlGuardImpl, as
otherwise the various subclasses can no longer cast the QQmlGuardImpl we
pass to them to their own type in the objectDestroyed(Impl) methods.
QQmlGuard(Impl) still could benefit from a move ctor/assignment
operator; those will be added in a later commit.
Task-number: QTBUG-45582
Change-Id: I995148a428e541ced5c79b3a61d91c4bb7e03308
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlvmemetaobject.cpp')
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject.cpp | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 93abe3c83a..ef41d81868 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -165,31 +165,28 @@ static void list_removeLast(QQmlListProperty<QObject> *prop) } QQmlVMEVariantQObjectPtr::QQmlVMEVariantQObjectPtr() - : QQmlGuard<QObject>(nullptr), m_target(nullptr), m_index(-1) + : QQmlGuard<QObject>(QQmlVMEVariantQObjectPtr::objectDestroyedImpl, nullptr), m_target(nullptr), m_index(-1) { } -QQmlVMEVariantQObjectPtr::~QQmlVMEVariantQObjectPtr() +void QQmlVMEVariantQObjectPtr::objectDestroyedImpl(QQmlGuardImpl *guard) { -} - -void QQmlVMEVariantQObjectPtr::objectDestroyed(QObject *) -{ - if (!m_target || QQmlData::wasDeleted(m_target->object)) + auto This = static_cast<QQmlVMEVariantQObjectPtr *>(guard); + if (!This->m_target || QQmlData::wasDeleted(This->m_target->object)) return; - if (m_index >= 0) { - QV4::ExecutionEngine *v4 = m_target->propertyAndMethodStorage.engine(); + if (This->m_index >= 0) { + QV4::ExecutionEngine *v4 = This->m_target->propertyAndMethodStorage.engine(); if (v4) { QV4::Scope scope(v4); - QV4::Scoped<QV4::MemberData> sp(scope, m_target->propertyAndMethodStorage.value()); + QV4::Scoped<QV4::MemberData> sp(scope, This->m_target->propertyAndMethodStorage.value()); if (sp) { - QV4::PropertyIndex index{ sp->d(), sp->d()->values.values + m_index }; + QV4::PropertyIndex index{ sp->d(), sp->d()->values.values + This->m_index }; index.set(v4, QV4::Value::nullValue()); } } - m_target->activate(m_target->object, m_target->methodOffset() + m_index, nullptr); + This->m_target->activate(This->m_target->object, This->m_target->methodOffset() + This->m_index, nullptr); } } |