aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2019-04-07 16:51:13 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2020-11-26 17:57:53 +0100
commit9b337179e1b2c8ece6401262d0f6f2a47e471382 (patch)
tree5d767f28128cc535fe85084440cc8e842c3b5b45
parent2bbd21c097e3456919b238df3476d0a38846b9a7 (diff)
Make QQmlMetaObject independent of the property cache
Don't store a pointer to the property cache in QQmlMetaObject anymore, instead always use the QMetaObject. Task-number: QTBUG-82931 Change-Id: I792b84c93c84a625ece2022bdbc9176250c8a409 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--src/qml/qml/qqmlmetaobject.cpp135
-rw-r--r--src/qml/qml/qqmlmetaobject_p.h48
-rw-r--r--src/qml/qml/qqmlobjectorgadget.cpp5
-rw-r--r--src/qml/qml/qqmlstaticmetaobject.cpp2
4 files changed, 31 insertions, 159 deletions
diff --git a/src/qml/qml/qqmlmetaobject.cpp b/src/qml/qml/qqmlmetaobject.cpp
index 057eb94f54..da587de10e 100644
--- a/src/qml/qml/qqmlmetaobject.cpp
+++ b/src/qml/qml/qqmlmetaobject.cpp
@@ -88,45 +88,18 @@ bool QQmlMetaObject::canConvert(const QQmlMetaObject &from, const QQmlMetaObject
{
Q_ASSERT(!from.isNull() && !to.isNull());
- struct I { static bool equal(const QMetaObject *lhs, const QMetaObject *rhs) {
- return lhs == rhs || (lhs && rhs && lhs->d.stringdata == rhs->d.stringdata);
- } };
+ auto equal = [] (const QMetaObject *lhs, const QMetaObject *rhs) -> bool {
+ return lhs == rhs || (lhs && rhs && lhs->d.stringdata == rhs->d.stringdata);
+ };
- const QMetaObject *tom = to._m.isT1()?to._m.asT1()->metaObject():to._m.asT2();
+ const QMetaObject *tom = to.metaObject();
if (tom == &QObject::staticMetaObject) return true;
- if (from._m.isT1() && to._m.isT1()) { // QQmlPropertyCache -> QQmlPropertyCache
- QQmlPropertyCache *fromp = from._m.asT1();
- QQmlPropertyCache *top = to._m.asT1();
-
- while (fromp) {
- if (fromp == top) return true;
- fromp = fromp->parent();
- }
- } else if (from._m.isT1() && to._m.isT2()) { // QQmlPropertyCache -> QMetaObject
- QQmlPropertyCache *fromp = from._m.asT1();
-
- while (fromp) {
- const QMetaObject *fromm = fromp->metaObject();
- if (fromm && I::equal(fromm, tom)) return true;
- fromp = fromp->parent();
- }
- } else if (from._m.isT2() && to._m.isT1()) { // QMetaObject -> QQmlPropertyCache
- const QMetaObject *fromm = from._m.asT2();
-
- if (!tom) return false;
-
- while (fromm) {
- if (I::equal(fromm, tom)) return true;
- fromm = fromm->superClass();
- }
- } else { // QMetaObject -> QMetaObject
- const QMetaObject *fromm = from._m.asT2();
-
- while (fromm) {
- if (I::equal(fromm, tom)) return true;
- fromm = fromm->superClass();
- }
+ const QMetaObject *fromm = from.metaObject();
+ while (fromm) {
+ if (equal(fromm, tom))
+ return true;
+ fromm = fromm->superClass();
}
return false;
@@ -162,16 +135,9 @@ void QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(QMetaObject::Call type,
*index -= offset;
}
-QQmlPropertyCache *QQmlMetaObject::propertyCache(QQmlEnginePrivate *e) const
-{
- if (_m.isNull()) return nullptr;
- if (_m.isT1()) return _m.asT1();
- else return e->cache(_m.asT2());
-}
-
int QQmlMetaObject::methodReturnType(const QQmlPropertyData &data, QByteArray *unknownTypeError) const
{
- Q_ASSERT(!_m.isNull() && data.coreIndex() >= 0);
+ Q_ASSERT(_m && data.coreIndex() >= 0);
int type = data.propType();
@@ -179,21 +145,7 @@ int QQmlMetaObject::methodReturnType(const QQmlPropertyData &data, QByteArray *u
if (type == QMetaType::UnknownType) {
// Find the return type name from the method info
- QMetaMethod m;
-
- if (_m.isT1()) {
- QQmlPropertyCache *c = _m.asT1();
- Q_ASSERT(data.coreIndex() < c->methodIndexCacheStart + c->methodIndexCache.count());
-
- while (data.coreIndex() < c->methodIndexCacheStart)
- c = c->_parent;
-
- const QMetaObject *metaObject = c->createMetaObject();
- Q_ASSERT(metaObject);
- m = metaObject->method(data.coreIndex());
- } else {
- m = _m.asT2()->method(data.coreIndex());
- }
+ QMetaMethod m = _m->method(data.coreIndex());
type = m.returnType();
propTypeName = m.typeName();
@@ -203,7 +155,7 @@ int QQmlMetaObject::methodReturnType(const QQmlPropertyData &data, QByteArray *u
if (QMetaType(type).flags() & QMetaType::IsEnumeration)
return QMetaType::Int;
- if (isNamedEnumerator(metaObject(), propTypeName))
+ if (isNamedEnumerator(_m, propTypeName))
return QMetaType::Int;
if (type == QMetaType::UnknownType) {
@@ -218,65 +170,10 @@ int QQmlMetaObject::methodReturnType(const QQmlPropertyData &data, QByteArray *u
int *QQmlMetaObject::methodParameterTypes(int index, ArgTypeStorage *argStorage,
QByteArray *unknownTypeError) const
{
- Q_ASSERT(!_m.isNull() && index >= 0);
+ Q_ASSERT(_m && index >= 0);
- if (_m.isT1()) {
- typedef QQmlPropertyCacheMethodArguments A;
-
- QQmlPropertyCache *c = _m.asT1();
- Q_ASSERT(index < c->methodIndexCacheStart + c->methodIndexCache.count());
-
- while (index < c->methodIndexCacheStart)
- c = c->_parent;
-
- QQmlPropertyData *rv = const_cast<QQmlPropertyData *>(&c->methodIndexCache.at(index - c->methodIndexCacheStart));
-
- if (rv->arguments() && static_cast<A *>(rv->arguments())->argumentsValid)
- return static_cast<A *>(rv->arguments())->arguments;
-
- const QMetaObject *metaObject = c->createMetaObject();
- Q_ASSERT(metaObject);
- QMetaMethod m = metaObject->method(index);
-
- int argc = m.parameterCount();
- if (!rv->arguments()) {
- A *args = c->createArgumentsObject(argc, m.parameterNames());
- rv->setArguments(args);
- }
- A *args = static_cast<A *>(rv->arguments());
-
- QList<QByteArray> argTypeNames; // Only loaded if needed
-
- for (int ii = 0; ii < argc; ++ii) {
- int type = m.parameterType(ii);
-
- if (QMetaType(type).sizeOf() > qsizetype(sizeof(int))) {
- // Cannot be passed as int
- // We know that it's a known type, as sizeOf(UnknownType) == 0
- } else if (QMetaType(type).flags() & QMetaType::IsEnumeration) {
- type = QMetaType::Int;
- } else {
- if (argTypeNames.isEmpty())
- argTypeNames = m.parameterTypes();
- if (isNamedEnumerator(metaObject, argTypeNames.at(ii))) {
- type = QMetaType::Int;
- } else if (type == QMetaType::UnknownType){
- if (unknownTypeError)
- *unknownTypeError = argTypeNames.at(ii);
- return nullptr;
- }
-
- }
- args->arguments[ii + 1] = type;
- }
- args->argumentsValid = true;
- return static_cast<A *>(rv->arguments())->arguments;
-
- } else {
- QMetaMethod m = _m.asT2()->method(index);
- return methodParameterTypes(m, argStorage, unknownTypeError);
-
- }
+ QMetaMethod m = _m->method(index);
+ return methodParameterTypes(m, argStorage, unknownTypeError);
}
int *QQmlMetaObject::methodParameterTypes(const QMetaMethod &m, ArgTypeStorage *argStorage,
@@ -299,7 +196,7 @@ int *QQmlMetaObject::methodParameterTypes(const QMetaMethod &m, ArgTypeStorage *
} else {
if (argTypeNames.isEmpty())
argTypeNames = m.parameterTypes();
- if (isNamedEnumerator(_m.asT2(), argTypeNames.at(ii))) {
+ if (isNamedEnumerator(_m, argTypeNames.at(ii))) {
type = QMetaType::Int;
} else if (type == QMetaType::UnknownType) {
if (unknownTypeError)
diff --git a/src/qml/qml/qqmlmetaobject_p.h b/src/qml/qml/qqmlmetaobject_p.h
index 65d6361b90..d2b034dca2 100644
--- a/src/qml/qml/qqmlmetaobject_p.h
+++ b/src/qml/qml/qqmlmetaobject_p.h
@@ -74,7 +74,7 @@ class Q_QML_EXPORT QQmlMetaObject
public:
typedef QVarLengthArray<int, 9> ArgTypeStorage;
- inline QQmlMetaObject();
+ inline QQmlMetaObject() = default;
inline QQmlMetaObject(QObject *);
inline QQmlMetaObject(const QMetaObject *);
inline QQmlMetaObject(QQmlPropertyCache *);
@@ -87,11 +87,8 @@ public:
inline const char *className() const;
inline int propertyCount() const;
- inline bool hasMetaObject() const;
inline const QMetaObject *metaObject() const;
- QQmlPropertyCache *propertyCache(QQmlEnginePrivate *) const;
-
int methodReturnType(const QQmlPropertyData &data, QByteArray *unknownTypeError) const;
int *methodParameterTypes(int index, ArgTypeStorage *argStorage,
QByteArray *unknownTypeError) const;
@@ -103,23 +100,16 @@ public:
static void resolveGadgetMethodOrPropertyIndex(QMetaObject::Call type, const QMetaObject **metaObject, int *index);
protected:
- QBiPointer<QQmlPropertyCache, const QMetaObject> _m;
+ const QMetaObject *_m = nullptr;
int *methodParameterTypes(const QMetaMethod &method, ArgTypeStorage *argStorage,
QByteArray *unknownTypeError) const;
};
-QQmlMetaObject::QQmlMetaObject()
-{
-}
-
QQmlMetaObject::QQmlMetaObject(QObject *o)
{
- if (o) {
- QQmlData *ddata = QQmlData::get(o, false);
- if (ddata && ddata->propertyCache) _m = ddata->propertyCache;
- else _m = o->metaObject();
- }
+ if (o)
+ _m = o->metaObject();
}
QQmlMetaObject::QQmlMetaObject(const QMetaObject *m)
@@ -128,8 +118,9 @@ QQmlMetaObject::QQmlMetaObject(const QMetaObject *m)
}
QQmlMetaObject::QQmlMetaObject(QQmlPropertyCache *m)
- : _m(m)
{
+ if (m)
+ _m = m->createMetaObject();
}
QQmlMetaObject::QQmlMetaObject(const QQmlMetaObject &o)
@@ -145,41 +136,26 @@ QQmlMetaObject &QQmlMetaObject::operator=(const QQmlMetaObject &o)
bool QQmlMetaObject::isNull() const
{
- return _m.isNull();
+ return !_m;
}
const char *QQmlMetaObject::className() const
{
- if (_m.isNull()) {
+ if (!_m)
return nullptr;
- } else if (_m.isT1()) {
- return _m.asT1()->className();
- } else {
- return _m.asT2()->className();
- }
+ return metaObject()->className();
}
int QQmlMetaObject::propertyCount() const
{
- if (_m.isNull()) {
+ if (!_m)
return 0;
- } else if (_m.isT1()) {
- return _m.asT1()->propertyCount();
- } else {
- return _m.asT2()->propertyCount();
- }
-}
-
-bool QQmlMetaObject::hasMetaObject() const
-{
- return _m.isT2() || (!_m.isNull() && _m.asT1()->metaObject());
+ return metaObject()->propertyCount();
}
const QMetaObject *QQmlMetaObject::metaObject() const
{
- if (_m.isNull()) return nullptr;
- if (_m.isT1()) return _m.asT1()->createMetaObject();
- else return _m.asT2();
+ return _m;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlobjectorgadget.cpp b/src/qml/qml/qqmlobjectorgadget.cpp
index 1d4916d7d1..454c029fc3 100644
--- a/src/qml/qml/qqmlobjectorgadget.cpp
+++ b/src/qml/qml/qqmlobjectorgadget.cpp
@@ -44,14 +44,13 @@ QT_BEGIN_NAMESPACE
void QQmlObjectOrGadget::metacall(QMetaObject::Call type, int index, void **argv) const
{
if (ptr.isNull()) {
- const QMetaObject *metaObject = _m.asT2();
- metaObject->d.static_metacall(nullptr, type, index, argv);
+ _m->d.static_metacall(nullptr, type, index, argv);
}
else if (ptr.isT1()) {
QMetaObject::metacall(ptr.asT1(), type, index, argv);
}
else {
- const QMetaObject *metaObject = _m.asT1()->metaObject();
+ const QMetaObject *metaObject = _m;
QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(type, &metaObject, &index);
metaObject->d.static_metacall(reinterpret_cast<QObject*>(ptr.asT2()), type, index, argv);
}
diff --git a/src/qml/qml/qqmlstaticmetaobject.cpp b/src/qml/qml/qqmlstaticmetaobject.cpp
index 218d0134fd..57438452d2 100644
--- a/src/qml/qml/qqmlstaticmetaobject.cpp
+++ b/src/qml/qml/qqmlstaticmetaobject.cpp
@@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE
int *QQmlStaticMetaObject::constructorParameterTypes(int index, ArgTypeStorage *dummy,
QByteArray *unknownTypeError) const
{
- QMetaMethod m = _m.asT2()->constructor(index);
+ QMetaMethod m = _m->constructor(index);
return methodParameterTypes(m, dummy, unknownTypeError);
}