aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--src/quick/designer/qqmldesignermetaobject.cpp38
-rw-r--r--src/quick/designer/qqmldesignermetaobject_p.h5
16 files changed, 137 insertions, 116 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)
diff --git a/src/quick/designer/qqmldesignermetaobject.cpp b/src/quick/designer/qqmldesignermetaobject.cpp
index b005976387..33c161147b 100644
--- a/src/quick/designer/qqmldesignermetaobject.cpp
+++ b/src/quick/designer/qqmldesignermetaobject.cpp
@@ -110,8 +110,7 @@ QQmlDesignerMetaObject* QQmlDesignerMetaObject::getNodeInstanceMetaObject(QObjec
void QQmlDesignerMetaObject::init(QObject *object, QQmlEngine *engine)
{
//Creating QQmlOpenMetaObjectType
- m_type = new QQmlOpenMetaObjectType(metaObjectParent());
- m_type->addref();
+ m_openMetaObject = std::make_unique<QQmlOpenMetaObject>(object, metaObjectParent());
//Assigning type to this
copyTypeMetaObject();
@@ -119,10 +118,9 @@ void QQmlDesignerMetaObject::init(QObject *object, QQmlEngine *engine)
QObjectPrivate *op = QObjectPrivate::get(object);
op->metaObject = this;
- cache = QQmlEnginePrivate::get(engine)->cache(this);
+ cache = QQmlEnginePrivate::get(engine)->cache(metaObject);
nodeInstanceMetaObjectList.insert(this, true);
- hasAssignedMetaObjectData = true;
}
QQmlDesignerMetaObject::QQmlDesignerMetaObject(QObject *object, QQmlEngine *engine)
@@ -136,7 +134,7 @@ QQmlDesignerMetaObject::QQmlDesignerMetaObject(QObject *object, QQmlEngine *engi
//Assign cache to object
if (ddata && ddata->propertyCache) {
cache->setParent(ddata->propertyCache);
- cache->invalidate(this);
+ cache->invalidate(metaObject);
ddata->propertyCache->release();
ddata->propertyCache = cache.data();
ddata->propertyCache->addref();
@@ -146,23 +144,21 @@ QQmlDesignerMetaObject::QQmlDesignerMetaObject(QObject *object, QQmlEngine *engi
QQmlDesignerMetaObject::~QQmlDesignerMetaObject()
{
- m_type->release();
-
+ // m_openMetaObject has this metaobject as its parent.
+ // We need to remove it in order to avoid a dtor recursion
+ m_openMetaObject->unparent();
nodeInstanceMetaObjectList.remove(this);
}
void QQmlDesignerMetaObject::createNewDynamicProperty(const QString &name)
{
- int id = m_type->createProperty(name.toUtf8());
+ int id = type()->createProperty(name.toUtf8());
copyTypeMetaObject();
setValue(id, QVariant());
Q_ASSERT(id >= 0);
- Q_UNUSED(id);
//Updating cache
- QQmlPropertyCache *oldParent = cache->parent();
- QQmlEnginePrivate::get(m_context->engine())->cache(this)->invalidate(this);
- cache->setParent(oldParent);
+ cache->invalidate(metaObject);
QQmlProperty property(myObject(), name, m_context);
Q_ASSERT(property.isValid());
@@ -173,7 +169,7 @@ void QQmlDesignerMetaObject::setValue(int id, const QVariant &value)
QPair<QVariant, bool> &prop = m_data->getDataRef(id);
prop.first = propertyWriteValue(id, value);
prop.second = true;
- QMetaObject::activate(myObject(), id + m_type->signalOffset(), nullptr);
+ QMetaObject::activate(myObject(), id + type()->signalOffset(), nullptr);
}
QVariant QQmlDesignerMetaObject::propertyWriteValue(int, const QVariant &value)
@@ -205,8 +201,8 @@ int QQmlDesignerMetaObject::propertyOffset() const
int QQmlDesignerMetaObject::openMetaCall(QObject *o, QMetaObject::Call call, int id, void **a)
{
if ((call == QMetaObject::ReadProperty || call == QMetaObject::WriteProperty)
- && id >= m_type->propertyOffset()) {
- int propId = id - m_type->propertyOffset();
+ && id >= type()->propertyOffset()) {
+ int propId = id - type()->propertyOffset();
if (call == QMetaObject::ReadProperty) {
//propertyRead(propId);
*reinterpret_cast<QVariant *>(a[0]) = m_data->getData(propId);
@@ -217,7 +213,7 @@ int QQmlDesignerMetaObject::openMetaCall(QObject *o, QMetaObject::Call call, int
prop.first = propertyWriteValue(propId, *reinterpret_cast<QVariant *>(a[0]));
prop.second = true;
//propertyWritten(propId);
- activate(myObject(), m_type->signalOffset() + propId, nullptr);
+ activate(myObject(), type()->signalOffset() + propId, nullptr);
}
}
return -1;
@@ -236,7 +232,7 @@ int QQmlDesignerMetaObject::metaCall(QObject *o, QMetaObject::Call call, int id,
int metaCallReturnValue = -1;
- const QMetaProperty propertyById = QQmlVMEMetaObject::property(id);
+ const QMetaProperty propertyById = metaObject->property(id);
if (call == QMetaObject::WriteProperty
&& propertyById.userType() == QMetaType::QVariant
@@ -284,7 +280,7 @@ int QQmlDesignerMetaObject::metaCall(QObject *o, QMetaObject::Call call, int id,
void QQmlDesignerMetaObject::notifyPropertyChange(int id)
{
- const QMetaProperty propertyById = property(id);
+ const QMetaProperty propertyById = metaObject->property(id);
if (id < propertyOffset()) {
if (notifyPropertyChangeCallBack)
@@ -297,17 +293,17 @@ void QQmlDesignerMetaObject::notifyPropertyChange(int id)
int QQmlDesignerMetaObject::count() const
{
- return m_type->propertyCount();
+ return type()->propertyCount();
}
QByteArray QQmlDesignerMetaObject::name(int idx) const
{
- return m_type->propertyName(idx);
+ return type()->propertyName(idx);
}
void QQmlDesignerMetaObject::copyTypeMetaObject()
{
- *static_cast<QMetaObject *>(this) = *m_type->metaObject();
+ metaObject = m_openMetaObject.get();
}
void QQmlDesignerMetaObject::registerNotifyPropertyChangeCallBack(void (*callback)(QObject *, const QQuickDesignerSupport::PropertyName &))
diff --git a/src/quick/designer/qqmldesignermetaobject_p.h b/src/quick/designer/qqmldesignermetaobject_p.h
index cf91523ca3..08979b1492 100644
--- a/src/quick/designer/qqmldesignermetaobject_p.h
+++ b/src/quick/designer/qqmldesignermetaobject_p.h
@@ -58,6 +58,8 @@
#include <private/qqmlopenmetaobject_p.h>
#include <private/qqmlvmemetaobject_p.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
struct MetaPropertyData;
@@ -95,9 +97,10 @@ protected:
private:
QQmlDesignerMetaObject(QObject *object, QQmlEngine *engine);
void init(QObject *, QQmlEngine *engine);
+ QQmlOpenMetaObjectType *type() const { return m_openMetaObject->type(); }
QPointer<QQmlContext> m_context;
- QQmlOpenMetaObjectType *m_type;
+ std::unique_ptr<QQmlOpenMetaObject> m_openMetaObject;
QScopedPointer<MetaPropertyData> m_data;
//QAbstractDynamicMetaObject *m_parent;