From 9b337179e1b2c8ece6401262d0f6f2a47e471382 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sun, 7 Apr 2019 16:51:13 +0200 Subject: 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 --- src/qml/qml/qqmlmetaobject.cpp | 135 +++++------------------------------ src/qml/qml/qqmlmetaobject_p.h | 48 ++++--------- src/qml/qml/qqmlobjectorgadget.cpp | 5 +- src/qml/qml/qqmlstaticmetaobject.cpp | 2 +- 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(&c->methodIndexCache.at(index - c->methodIndexCacheStart)); - - if (rv->arguments() && static_cast(rv->arguments())->argumentsValid) - return static_cast(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(rv->arguments()); - - QList 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(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 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 _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(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); } -- cgit v1.2.3