aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
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
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')
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp5
-rw-r--r--src/qml/qml/qqmlmetatype.cpp1
-rw-r--r--src/qml/qml/qqmlopenmetaobject.cpp18
-rw-r--r--src/qml/qml/qqmlopenmetaobject_p.h4
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp24
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h50
-rw-r--r--src/qml/qml/qqmlpropertydata_p.h37
-rw-r--r--src/qml/qml/qqmlproxymetaobject.cpp9
-rw-r--r--src/qml/qml/qqmlproxymetaobject_p.h6
-rw-r--r--src/qml/qml/qqmltype.cpp1
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp5
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h5
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp41
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h4
14 files changed, 116 insertions, 94 deletions
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index 65481e4539..66693fb0d2 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -206,7 +206,10 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
//
// Note: The scope object is only a QADMO for example when somebody registers a QQmlPropertyMap
// sub-class as QML type and then instantiates it in .qml.
- if (scopeObject && QQmlPropertyCache::isDynamicMetaObject(scopeObject->metaObject())) {
+ const QMetaObjectPrivate *metaObjectPrivate = scopeObject
+ ? reinterpret_cast<const QMetaObjectPrivate *>(scopeObject->metaObject()->d.data)
+ : nullptr;
+ if (metaObjectPrivate && metaObjectPrivate->flags & DynamicMetaObject) {
// all bets are off, so don't try to optimize any lookups
lookup = nullptr;
if (performGobalLookUp())
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 6383643ebb..bd49fc3b51 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -1530,7 +1530,6 @@ QList<QQmlProxyMetaObject::ProxyData> QQmlMetaType::proxyData(const QMetaObject
QMetaObjectBuilder builder;
clone(builder, extMetaObject, superdataBaseMetaObject, baseMetaObject);
- builder.setFlags(MetaObjectFlag::DynamicMetaObject);
QMetaObject *mmo = builder.toMetaObject();
mmo->d.superdata = baseMetaObject;
if (!metaObjects.isEmpty())
diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp
index ec2d57013f..24aff03fca 100644
--- a/src/qml/qml/qqmlopenmetaobject.cpp
+++ b/src/qml/qml/qqmlopenmetaobject.cpp
@@ -99,11 +99,6 @@ QByteArray QQmlOpenMetaObjectType::propertyName(int idx) const
return d->mob.property(idx).name();
}
-QMetaObject *QQmlOpenMetaObjectType::metaObject() const
-{
- return d->mem;
-}
-
void QQmlOpenMetaObjectType::createProperties(const QVector<QByteArray> &names)
{
for (int i = 0; i < names.count(); ++i) {
@@ -238,7 +233,7 @@ public:
}
QQmlOpenMetaObject *q;
- QAbstractDynamicMetaObject *parent = nullptr;
+ QDynamicMetaObjectData *parent = nullptr;
QVector<Property> data;
QObject *object;
QQmlRefPointer<QQmlOpenMetaObjectType> type;
@@ -254,7 +249,7 @@ QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj, const QMetaObject *base)
d->type->d->referers.insert(this);
QObjectPrivate *op = QObjectPrivate::get(obj);
- d->parent = static_cast<QAbstractDynamicMetaObject *>(op->metaObject);
+ d->parent = op->metaObject;
*static_cast<QMetaObject *>(this) = *d->type->d->mem;
op->metaObject = this;
}
@@ -266,7 +261,7 @@ QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj, QQmlOpenMetaObjectType *typ
d->type->d->referers.insert(this);
QObjectPrivate *op = QObjectPrivate::get(obj);
- d->parent = static_cast<QAbstractDynamicMetaObject *>(op->metaObject);
+ d->parent = op->metaObject;
*static_cast<QMetaObject *>(this) = *d->type->d->mem;
op->metaObject = this;
}
@@ -292,6 +287,11 @@ void QQmlOpenMetaObject::emitPropertyNotification(const QByteArray &propertyName
activate(d->object, *iter + d->type->d->signalOffset, nullptr);
}
+void QQmlOpenMetaObject::unparent()
+{
+ d->parent = nullptr;
+}
+
int QQmlOpenMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void **a)
{
Q_ASSERT(d->object == o);
@@ -319,7 +319,7 @@ int QQmlOpenMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void *
}
}
-QAbstractDynamicMetaObject *QQmlOpenMetaObject::parent() const
+QDynamicMetaObjectData *QQmlOpenMetaObject::parent() const
{
return d->parent;
}
diff --git a/src/qml/qml/qqmlopenmetaobject_p.h b/src/qml/qml/qqmlopenmetaobject_p.h
index 47bba085b5..e455725bdf 100644
--- a/src/qml/qml/qqmlopenmetaobject_p.h
+++ b/src/qml/qml/qqmlopenmetaobject_p.h
@@ -78,7 +78,6 @@ public:
int propertyCount() const;
QByteArray propertyName(int) const;
- QMetaObject *metaObject() const;
protected:
virtual void propertyCreated(int, QMetaPropertyBuilder &);
@@ -121,6 +120,7 @@ public:
QQmlOpenMetaObjectType *type() const;
void emitPropertyNotification(const QByteArray &propertyName);
+ void unparent();
protected:
int metaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a) override;
@@ -132,7 +132,7 @@ protected:
virtual void propertyWritten(int);
virtual void propertyCreated(int, QMetaPropertyBuilder &);
- QAbstractDynamicMetaObject *parent() const;
+ QDynamicMetaObjectData *parent() const;
bool checkedSetValue(int index, const QVariant &value, bool force);
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 315f9f07fa..5ed63fb57c 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -342,7 +342,7 @@ const QMetaObject *QQmlPropertyCache::createMetaObject()
QMetaObjectBuilder builder;
toMetaObjectBuilder(builder);
builder.setSuperClass(_parent->createMetaObject());
- _metaObject = RefCountedMetaObject(builder.toMetaObject(), RefCountedMetaObject::SharedMetaObject);
+ _metaObject = RefCountedMetaObject::createShared(builder.toMetaObject());
}
return _metaObject;
@@ -403,10 +403,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
QQmlPropertyData::Flags methodFlags,
QQmlPropertyData::Flags signalFlags)
{
- _metaObject = RefCountedMetaObject(metaObject, RefCountedMetaObject::StaticMetaObject);
-
- bool dynamicMetaObject = isDynamicMetaObject(metaObject);
-
+ _metaObject = RefCountedMetaObject::createStatic(metaObject);
allowedRevisionCache.append(QTypeRevision::zero());
int methodCount = metaObject->methodCount();
@@ -557,8 +554,6 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
data->load(p);
data->setTypeVersion(typeVersion);
- data->m_flags.setIsDirect(!dynamicMetaObject);
-
Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
data->setMetaObjectOffset(allowedRevisionCache.count() - 1);
@@ -586,9 +581,8 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
isGadget = false;
}
- if (isGadget) // always dispatch over a 'normal' meta-call so the QQmlValueType can intercept
- data->m_flags.setIsDirect(false);
- else
+ // otherwise always dispatch over a 'normal' meta-call so the QQmlValueType can intercept
+ if (!isGadget)
data->trySetStaticMetaCallFunction(metaObject->d.static_metacall, ii - propOffset);
}
}
@@ -969,10 +963,7 @@ QQmlPropertyCache::property(QJSEngine *engine, QObject *obj, const QLatin1String
return qQmlPropertyCacheProperty<const QLatin1String &>(engine, obj, name, context, local);
}
-// these two functions are copied from qmetaobject.cpp
-static inline const QMetaObjectPrivate *priv(const uint* data)
-{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
-
+// this function is copied from qmetaobject.cpp
static inline const QByteArray stringData(const QMetaObject *mo, int index)
{
uint offset = mo->d.stringdata[2*index];
@@ -981,11 +972,6 @@ static inline const QByteArray stringData(const QMetaObject *mo, int index)
return QByteArray::fromRawData(string, length);
}
-bool QQmlPropertyCache::isDynamicMetaObject(const QMetaObject *mo)
-{
- return priv(mo->d.data)->flags & DynamicMetaObject;
-}
-
const char *QQmlPropertyCache::className() const
{
if (_metaObject)
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 93e776527e..1db3f0f464 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -84,8 +84,14 @@ public:
};
struct Data {
- ~Data() { if (mode == SharedMetaObject) ::free(const_cast<QMetaObject *>(mo)); }
- const QMetaObject *mo = nullptr;
+ ~Data() {
+ if (mode == SharedMetaObject)
+ ::free(sharedMetaObject);
+ }
+ union {
+ QMetaObject *sharedMetaObject = nullptr;
+ const QMetaObject *staticMetaObject;
+ };
int ref = 1;
OwnershipMode mode;
} *d;
@@ -94,11 +100,24 @@ public:
: d(nullptr)
{}
- RefCountedMetaObject(const QMetaObject *mo, OwnershipMode mode)
- : d(new Data) {
- d->mo = mo;
- d->mode = mode;
+ static RefCountedMetaObject createShared(QMetaObject *mo)
+ {
+ RefCountedMetaObject result;
+ result.d = new Data();
+ result.d->sharedMetaObject = mo;
+ result.d->mode = SharedMetaObject;
+ return result;
+ }
+
+ static RefCountedMetaObject createStatic(const QMetaObject *mo)
+ {
+ RefCountedMetaObject result;
+ result.d = new Data();
+ result.d->staticMetaObject = mo;
+ result.d->mode = StaticMetaObject;
+ return result;
}
+
~RefCountedMetaObject() {
if (d && !--d->ref)
delete d;
@@ -120,8 +139,21 @@ public:
++d->ref;
return *this;
}
- operator const QMetaObject *() const { return d ? d->mo : nullptr; }
- const QMetaObject * operator ->() const { return d ? d->mo : nullptr; }
+
+ const QMetaObject *constMetaObject() const
+ {
+ if (!d)
+ return nullptr;
+ return isShared() ? d->sharedMetaObject : d->staticMetaObject;
+ }
+
+ QMetaObject *sharedMetaObject() const
+ {
+ return isShared() ? d->sharedMetaObject : nullptr;
+ }
+
+ operator const QMetaObject *() const { return constMetaObject(); }
+ const QMetaObject * operator ->() const { return constMetaObject(); }
bool isShared() const { return d && d->mode == SharedMetaObject; }
};
@@ -206,8 +238,6 @@ public:
inline int signalOffset() const;
inline int qmlEnumCount() const;
- static bool isDynamicMetaObject(const QMetaObject *);
-
void toMetaObjectBuilder(QMetaObjectBuilder &);
inline bool callJSFactoryMethod(QObject *object, void **args) const;
diff --git a/src/qml/qml/qqmlpropertydata_p.h b/src/qml/qml/qqmlpropertydata_p.h
index edf777ff18..24e2204b71 100644
--- a/src/qml/qml/qqmlpropertydata_p.h
+++ b/src/qml/qml/qqmlpropertydata_p.h
@@ -104,7 +104,7 @@ public:
// Lastly, isDirect and isOverridden apply to both functions and non-functions
private:
unsigned isConst : 1; // Property: has CONST flag/Method: is const
- unsigned isDirectOrVMEFunction : 1; // Exists on a C++ QMetaOBject OR Function was added by QML
+ unsigned isVMEFunction : 1; // Function was added by QML
unsigned isWritableORhasArguments : 1; // Has WRITE function OR Function takes arguments
unsigned isResettableORisSignal : 1; // Has RESET function OR Function is a signal
unsigned isAliasORisVMESignal : 1; // Is a QML alias to another property OR Signal was added by QML
@@ -159,11 +159,6 @@ public:
isConstructorORisBindable = b;
}
- void setIsDirect(bool b) {
- Q_ASSERT(type != FunctionType);
- isDirectOrVMEFunction = b;
- }
-
void setIsRequired(bool b) {
Q_ASSERT(type != FunctionType);
isRequiredORisCloned = b;
@@ -171,7 +166,7 @@ public:
void setIsVMEFunction(bool b) {
Q_ASSERT(type == FunctionType);
- isDirectOrVMEFunction = b;
+ isVMEFunction = b;
}
void setHasArguments(bool b) {
Q_ASSERT(type == FunctionType);
@@ -233,7 +228,6 @@ public:
bool isAlias() const { return !isFunction() && m_flags.isAliasORisVMESignal; }
bool isFinal() const { return !isFunction() && m_flags.isFinalORisV4Function; }
bool isOverridden() const { return m_flags.isOverridden; }
- bool isDirect() const { return !isFunction() && m_flags.isDirectOrVMEFunction; }
bool isRequired() const { return !isFunction() && m_flags.isRequiredORisCloned; }
bool hasStaticMetaCallFunction() const { return staticMetaCallFunction() != nullptr; }
bool isFunction() const { return m_flags.type == Flags::FunctionType; }
@@ -244,7 +238,7 @@ public:
bool isQJSValue() const { return m_flags.type == Flags::QJSValueType; }
bool isVarProperty() const { return m_flags.type == Flags::VarPropertyType; }
bool isQVariant() const { return m_flags.type == Flags::QVariantType; }
- bool isVMEFunction() const { return isFunction() && m_flags.isDirectOrVMEFunction; }
+ bool isVMEFunction() const { return isFunction() && m_flags.isVMEFunction; }
bool hasArguments() const { return isFunction() && m_flags.isWritableORhasArguments; }
bool isSignal() const { return isFunction() && m_flags.isResettableORisSignal; }
bool isVMESignal() const { return isFunction() && m_flags.isAliasORisVMESignal; }
@@ -353,14 +347,23 @@ public:
readPropertyWithArgs(target, args);
}
- inline void readPropertyWithArgs(QObject *target, void *args[]) const
+ // This is the same as QMetaObject::metacall(), but inlined here to avoid a function call.
+ // And we ignore the return value.
+ template<QMetaObject::Call call>
+ void doMetacall(QObject *object, int idx, void **argv) const
+ {
+ if (QDynamicMetaObjectData *dynamicMetaObject = QObjectPrivate::get(object)->metaObject)
+ dynamicMetaObject->metaCall(object, call, idx, argv);
+ else
+ object->qt_metacall(call, idx, argv);
+ }
+
+ void readPropertyWithArgs(QObject *target, void *args[]) const
{
if (hasStaticMetaCallFunction())
staticMetaCallFunction()(target, QMetaObject::ReadProperty, relativePropertyIndex(), args);
- else if (isDirect())
- target->qt_metacall(QMetaObject::ReadProperty, coreIndex(), args);
else
- QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex(), args);
+ doMetacall<QMetaObject::ReadProperty>(target, coreIndex(), args);
}
bool writeProperty(QObject *target, void *value, WriteFlags flags) const
@@ -369,10 +372,8 @@ public:
void *argv[] = { value, nullptr, &status, &flags };
if (flags.testFlag(BypassInterceptor) && hasStaticMetaCallFunction())
staticMetaCallFunction()(target, QMetaObject::WriteProperty, relativePropertyIndex(), argv);
- else if (flags.testFlag(BypassInterceptor) && isDirect())
- target->qt_metacall(QMetaObject::WriteProperty, coreIndex(), argv);
else
- QMetaObject::metacall(target, QMetaObject::WriteProperty, coreIndex(), argv);
+ doMetacall<QMetaObject::WriteProperty>(target, coreIndex(), argv);
return true;
}
@@ -437,7 +438,7 @@ bool QQmlPropertyData::operator==(const QQmlPropertyData &other) const
QQmlPropertyData::Flags::Flags()
: otherBits(0)
, isConst(false)
- , isDirectOrVMEFunction(false)
+ , isVMEFunction(false)
, isWritableORhasArguments(false)
, isResettableORisSignal(false)
, isAliasORisVMESignal(false)
@@ -454,7 +455,7 @@ QQmlPropertyData::Flags::Flags()
bool QQmlPropertyData::Flags::operator==(const QQmlPropertyData::Flags &other) const
{
return isConst == other.isConst &&
- isDirectOrVMEFunction == other.isDirectOrVMEFunction &&
+ isVMEFunction == other.isVMEFunction &&
isWritableORhasArguments == other.isWritableORhasArguments &&
isResettableORisSignal == other.isResettableORisSignal &&
isAliasORisVMESignal == other.isAliasORisVMESignal &&
diff --git a/src/qml/qml/qqmlproxymetaobject.cpp b/src/qml/qml/qqmlproxymetaobject.cpp
index 21d3c7ed05..33b216ee78 100644
--- a/src/qml/qml/qqmlproxymetaobject.cpp
+++ b/src/qml/qml/qqmlproxymetaobject.cpp
@@ -45,11 +45,11 @@ QT_BEGIN_NAMESPACE
QQmlProxyMetaObject::QQmlProxyMetaObject(QObject *obj, QList<ProxyData> *mList)
: metaObjects(mList), proxies(nullptr), parent(nullptr), object(obj)
{
- *static_cast<QMetaObject *>(this) = *metaObjects->constFirst().metaObject;
+ metaObject = metaObjects->constFirst().metaObject;
QObjectPrivate *op = QObjectPrivate::get(obj);
if (op->metaObject)
- parent = static_cast<QAbstractDynamicMetaObject*>(op->metaObject);
+ parent = op->metaObject;
op->metaObject = this;
}
@@ -145,4 +145,9 @@ int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void
return object->qt_metacall(c, id, a);
}
+QMetaObject *QQmlProxyMetaObject::toDynamicMetaObject(QObject *)
+{
+ return metaObject;
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlproxymetaobject_p.h b/src/qml/qml/qqmlproxymetaobject_p.h
index dfa5d44059..3eb25caa7b 100644
--- a/src/qml/qml/qqmlproxymetaobject_p.h
+++ b/src/qml/qml/qqmlproxymetaobject_p.h
@@ -62,7 +62,7 @@
QT_BEGIN_NAMESPACE
-class QQmlProxyMetaObject : public QAbstractDynamicMetaObject
+class QQmlProxyMetaObject : public QDynamicMetaObjectData
{
public:
struct ProxyData {
@@ -78,6 +78,7 @@ public:
protected:
int metaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a) override;
+ QMetaObject *toDynamicMetaObject(QObject *) override;
private:
QObject *getProxy(int index);
@@ -85,7 +86,8 @@ private:
QList<ProxyData> *metaObjects;
QObject **proxies;
- QAbstractDynamicMetaObject *parent;
+ QDynamicMetaObjectData *parent;
+ QMetaObject *metaObject;
QObject *object;
};
diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp
index f9f40e7ec6..4b1e84f236 100644
--- a/src/qml/qml/qqmltype.cpp
+++ b/src/qml/qml/qqmltype.cpp
@@ -228,7 +228,6 @@ void QQmlTypePrivate::init() const
// XXX - very inefficient
QMetaObjectBuilder builder;
QQmlMetaType::clone(builder, extMetaObject, extMetaObject, extMetaObject);
- builder.setFlags(MetaObjectFlag::DynamicMetaObject);
QMetaObject *mmo = builder.toMetaObject();
mmo->d.superdata = mo;
QQmlProxyMetaObject::ProxyData data = { mmo, extFunc, 0, 0 };
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index 7446322019..69baa03f74 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -52,7 +52,6 @@ QQmlValueType::QQmlValueType(QMetaType type, const QMetaObject *gadgetMetaObject
{
QMetaObjectBuilder builder(gadgetMetaObject);
dynamicMetaObject = builder.toMetaObject();
- *static_cast<QMetaObject*>(this) = *dynamicMetaObject;
}
QQmlValueType::~QQmlValueType()
@@ -113,7 +112,7 @@ void QQmlGadgetPtrWrapper::setValue(const QVariant &value)
int QQmlGadgetPtrWrapper::metaCall(QMetaObject::Call type, int id, void **argv)
{
Q_ASSERT(m_gadgetPtr);
- const QMetaObject *metaObject = valueType();
+ const QMetaObject *metaObject = valueType()->metaObject();
QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(type, &metaObject, &id);
metaObject->d.static_metacall(static_cast<QObject *>(m_gadgetPtr), type, id, argv);
return id;
@@ -127,7 +126,7 @@ const QQmlValueType *QQmlGadgetPtrWrapper::valueType() const
QMetaObject *QQmlValueType::toDynamicMetaObject(QObject *)
{
- return this;
+ return dynamicMetaObject;
}
void QQmlValueType::objectDestroyed(QObject *)
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index b1e985ba7a..c8e2945413 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -67,7 +67,7 @@
QT_BEGIN_NAMESPACE
-class Q_QML_PRIVATE_EXPORT QQmlValueType : public QAbstractDynamicMetaObject
+class Q_QML_PRIVATE_EXPORT QQmlValueType : public QDynamicMetaObjectData
{
public:
QQmlValueType() : metaType(QMetaType::UnknownType) {}
@@ -81,6 +81,7 @@ public:
void destruct(void *gadgetPtr) const { metaType.destruct(gadgetPtr); }
int metaTypeId() const { return metaType.id(); }
+ const QMetaObject *metaObject() const { return dynamicMetaObject; }
// ---- dynamic meta object data interface
QMetaObject *toDynamicMetaObject(QObject *) override;
@@ -109,7 +110,7 @@ public:
int metaTypeId() const { return valueType()->metaTypeId(); }
int metaCall(QMetaObject::Call type, int id, void **argv);
- QMetaProperty property(int index) { return valueType()->property(index); }
+ QMetaProperty property(int index) { return valueType()->metaObject()->property(index); }
private:
const QQmlValueType *valueType() const;
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.
}
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index 41b9a42b51..885efa01c5 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -89,7 +89,7 @@ public:
};
-class Q_QML_PRIVATE_EXPORT QQmlInterceptorMetaObject : public QAbstractDynamicMetaObject
+class Q_QML_PRIVATE_EXPORT QQmlInterceptorMetaObject : public QDynamicMetaObjectData
{
public:
QQmlInterceptorMetaObject(QObject *obj, const QQmlRefPointer<QQmlPropertyCache> &cache);
@@ -125,7 +125,7 @@ public:
QBiPointer<QDynamicMetaObjectData, const QMetaObject> parent;
QQmlPropertyValueInterceptor *interceptors;
- bool hasAssignedMetaObjectData;
+ const QMetaObject *metaObject;
};
inline QQmlInterceptorMetaObject *QQmlInterceptorMetaObject::get(QObject *obj)