aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlvmemetaobject.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-10-06 13:30:19 +0200
committerUlf Hermann <ulf.hermann@qt.io>2021-10-12 19:14:47 +0200
commit63865ebd75ede8122011a19e58dc56c19978c91a (patch)
tree90f250b1c692475ea4d17407d39c82b3c80a97e5 /src/qml/qml/qqmlvmemetaobject.cpp
parent852c8d1d8a953c626735f044838454a4d249c225 (diff)
Avoid QAbstractDynamicMetaObject where possible
We don't want to copy metaobjects, but QAbstractDynamicMetaObject forces us. Rather, use plain QDynamicMetaObjectData, and store a pointer to the actual metaobject. This requires us to drop the "isDirect()" optimization for property access, as we realize that there can be dynamic meta objects which are not QAbstractDynamicMetaObject. However, this optimization was questionable anyway. What it did was cache the fact that an object might have a dynamic metaobject in a flag. Checking this on the object itself should not be much more expensive, though. On the other hand, an object might receive a dynamic metaobject individually without us adjusting flags for its type. In that case we would call the wrong method. Furthermore, most property access can be done using the static metacall function anyway. Change-Id: I5897351253496309721bd38adf3e35a1f069b080 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlvmemetaobject.cpp')
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp41
1 files changed, 19 insertions, 22 deletions
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 99663d9daa..ea4c9f6c6f 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -79,12 +79,13 @@ public:
m_id = encodedIndex & ((quintptr(1) << (usableBits / 2)) - 1);
// walk up to the correct meta object if necessary
- auto mo = prop->object->metaObject();
+ auto mo = static_cast<QQmlVMEMetaObject *>(QObjectPrivate::get(prop->object)->metaObject);
while (inheritanceDepth--)
- mo = mo->superClass();
- m_metaObject = static_cast<QQmlVMEMetaObject *>(const_cast<QMetaObject *>(mo));
+ mo = mo->parentVMEMetaObject();
+ m_metaObject = mo;
Q_ASSERT(m_metaObject);
- Q_ASSERT( ::strstr(m_metaObject->property(m_metaObject->propOffset() + m_id).typeName(), "QQmlListProperty") );
+ Q_ASSERT(::strstr(m_metaObject->toDynamicMetaObject(prop->object)->property(
+ m_metaObject->propOffset() + m_id).typeName(), "QQmlListProperty") );
Q_ASSERT(m_metaObject->object == prop->object);
// readPropertyAsList() with checks transformed into Q_ASSERT
@@ -272,7 +273,7 @@ QQmlInterceptorMetaObject::QQmlInterceptorMetaObject(QObject *obj, const QQmlRef
: object(obj),
cache(cache),
interceptors(nullptr),
- hasAssignedMetaObjectData(false)
+ metaObject(nullptr)
{
QObjectPrivate *op = QObjectPrivate::get(obj);
@@ -400,18 +401,13 @@ bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a)
QMetaObject *QQmlInterceptorMetaObject::toDynamicMetaObject(QObject *o)
{
- if (!hasAssignedMetaObjectData) {
- *static_cast<QMetaObject *>(this) = *cache->createMetaObject();
-
- if (parent.isT1())
- this->d.superdata = parent.asT1()->toDynamicMetaObject(o);
- else
- this->d.superdata = parent.asT2();
-
- hasAssignedMetaObjectData = true;
- }
+ Q_UNUSED(o);
+ if (!metaObject)
+ metaObject = cache->createMetaObject();
- return this;
+ // ### Qt7: The const_cast is only due to toDynamicMetaObject having the wrong return type.
+ // It should be const QMetaObject *. Fix this.
+ return const_cast<QMetaObject *>(metaObject);
}
QQmlVMEMetaObject::QQmlVMEMetaObject(QV4::ExecutionEngine *engine,
@@ -777,10 +773,11 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
// To do this, we encode the hierarchy depth together with the id of the
// property in a single quintptr, with the first half storing the depth
// and the second half storing the property id
- auto mo = object->metaObject();
+ auto mo = static_cast<QQmlVMEMetaObject *>(
+ QObjectPrivate::get(object)->metaObject);
quintptr inheritanceDepth = 0u;
while (mo && mo != this) {
- mo = mo->superClass();
+ mo = mo->parentVMEMetaObject();
++inheritanceDepth;
}
constexpr quintptr usableBits = sizeof(quintptr) * CHAR_BIT;
@@ -996,10 +993,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
// are not rewritten correctly but this bug is deemed out-of-scope to fix for
// performance reasons; see QTBUG-24064) and thus compilation will have failed.
QQmlError e;
- e.setDescription(QLatin1String("Exception occurred during compilation of "
- "function: ")
- + QString::fromUtf8(QMetaObject::method(_id)
- .methodSignature()));
+ e.setDescription(
+ QStringLiteral(
+ "Exception occurred during compilation of function: ")
+ + QString::fromUtf8(metaObject->method(_id).methodSignature()));
ep->warning(e);
return -1; // The dynamic method with that id is not available.
}