diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-03-07 14:39:52 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-03-15 01:08:43 +0100 |
commit | 2d7fe23b41aa3fd719b7bc8aa585ab799e4a0c39 (patch) | |
tree | 4d5720b2713ffbce0fc00769c02ed676f078f879 /src/qml/qml/qqmlpropertycachecreator_p.h | |
parent | 4c6d0b2bf09329dd8b036761f8f2924f54af3a07 (diff) |
QML: Insert aliases in inline components when loading from disk cache
So far we did not completely restore aliases in inline components. This
was masked by the fact that until recently we failed to load inline
components from the disk cache and always loaded them from source
instead.
To fix this, refactor QQmlComponentAndAliasResolver to work for both,
QmlIR and QV4::CompiledData. With QmlIR, it populates the relevant data
structures. With QV4::CompiledData, it sanity-checks them. The
sanity-checks do incur some overhead, but given recent events, we
should err on the side of caution here.
Since QQmlComponentAndAliasResolver has received all the fixes we've
applied to make inline components work, this should lead to inline
components loaded from cache files to work the same way as those
compiled from source.
In turn, we can drop some methods of QQmlPropertyCacheAliasCreator.
Amends commit 131db085a752469e8f19974c2edb3a138d900249
Pick-to: 6.5
Fixes: QTBUG-111766
Fixes: QTBUG-111857
Change-Id: I9cc75e700a5fe5810a866e9aa930b9811368b1b4
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/qqmlpropertycachecreator_p.h')
-rw-r--r-- | src/qml/qml/qqmlpropertycachecreator_p.h | 146 |
1 files changed, 14 insertions, 132 deletions
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index 824260330b..99a64802c1 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -115,14 +115,6 @@ public: */ QQmlError verifyNoICCycle(); - /*! - \internal - Fills the property caches for the CompiledObjects by - calling buildMetaObjectsIncrementally until it can no - longer resume. - */ - QQmlError buildMetaObjects(); - enum class VMEMetaObjectIsRequired { Maybe, Always @@ -233,20 +225,6 @@ QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectsIncrementally() } template <typename ObjectContainer> -inline QQmlError -QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjects() -{ - QQmlError error = verifyNoICCycle(); - if (error.isValid()) - return error; - QQmlPropertyCacheCreatorBase::IncrementalResult result; - do { - result = buildMetaObjectsIncrementally(); - } while (result.canResume); - return result.error; -} - -template <typename ObjectContainer> inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context, VMEMetaObjectIsRequired isVMERequired) { auto isAddressable = [](const QUrl &url) { @@ -753,18 +731,16 @@ class QQmlPropertyCacheAliasCreator public: typedef typename ObjectContainer::CompiledObject CompiledObject; - QQmlPropertyCacheAliasCreator(QQmlPropertyCacheVector *propertyCaches, const ObjectContainer *objectContainer); - - void appendAliasPropertiesToMetaObjects(QQmlEnginePrivate *enginePriv); - - QQmlError appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex, QQmlEnginePrivate *enginePriv); + QQmlPropertyCacheAliasCreator( + QQmlPropertyCacheVector *propertyCaches, const ObjectContainer *objectContainer); + QQmlError appendAliasesToPropertyCache( + const CompiledObject &component, int objectIndex, QQmlEnginePrivate *enginePriv); private: - void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex, QQmlEnginePrivate *enginePriv); - QQmlError propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, QMetaType *type, QTypeRevision *version, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv); - - void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const; - + QQmlError propertyDataForAlias( + const CompiledObject &component, const QV4::CompiledData::Alias &alias, QMetaType *type, + QTypeRevision *version, QQmlPropertyData::Flags *propertyFlags, + QQmlEnginePrivate *enginePriv); int objectForId(const CompiledObject &component, int id) const; QQmlPropertyCacheVector *propertyCaches; @@ -772,107 +748,11 @@ private: }; template <typename ObjectContainer> -inline QQmlPropertyCacheAliasCreator<ObjectContainer>::QQmlPropertyCacheAliasCreator(QQmlPropertyCacheVector *propertyCaches, const ObjectContainer *objectContainer) +inline QQmlPropertyCacheAliasCreator<ObjectContainer>::QQmlPropertyCacheAliasCreator( + QQmlPropertyCacheVector *propertyCaches, const ObjectContainer *objectContainer) : propertyCaches(propertyCaches) , objectContainer(objectContainer) { - -} - -template <typename ObjectContainer> -inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertiesToMetaObjects(QQmlEnginePrivate *enginePriv) -{ - // skip the root object (index 0) as that one does not have a first object index originating - // from a binding. - for (int i = 1; i < objectContainer->objectCount(); ++i) { - const CompiledObject &component = *objectContainer->objectAt(i); - if (!component.hasFlag(QV4::CompiledData::Object::IsComponent)) - continue; - - const auto rootBinding = component.bindingsBegin(); - appendAliasPropertiesInMetaObjectsWithinComponent(component, rootBinding->value.objectIndex, enginePriv); - } - - const int rootObjectIndex = 0; - appendAliasPropertiesInMetaObjectsWithinComponent(*objectContainer->objectAt(rootObjectIndex), rootObjectIndex, enginePriv); -} - -template <typename ObjectContainer> -inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex, QQmlEnginePrivate *enginePriv) -{ - QVector<int> objectsWithAliases; - collectObjectsWithAliasesRecursively(firstObjectIndex, &objectsWithAliases); - if (objectsWithAliases.isEmpty()) - return; - - const auto allAliasTargetsExist = [this, &component](const CompiledObject &object) { - auto alias = object.aliasesBegin(); - auto end = object.aliasesEnd(); - for ( ; alias != end; ++alias) { - Q_ASSERT(alias->hasFlag(QV4::CompiledData::Alias::Resolved)); - - const int targetObjectIndex = objectForId(component, alias->targetObjectId()); - Q_ASSERT(targetObjectIndex >= 0); - - if (alias->isAliasToLocalAlias()) - continue; - - if (alias->encodedMetaPropertyIndex == -1) - continue; - - const QQmlPropertyCache::ConstPtr targetCache - = propertyCaches->at(targetObjectIndex); - Q_ASSERT(targetCache); - - int coreIndex = QQmlPropertyIndex::fromEncoded(alias->encodedMetaPropertyIndex).coreIndex(); - const QQmlPropertyData *targetProperty = targetCache->property(coreIndex); - if (!targetProperty) - return false; - } - return true; - }; - - do { - QVector<int> pendingObjects; - - for (int objectIndex: std::as_const(objectsWithAliases)) { - const CompiledObject &object = *objectContainer->objectAt(objectIndex); - - if (allAliasTargetsExist(object)) { - appendAliasesToPropertyCache(component, objectIndex, enginePriv); - } else { - pendingObjects.append(objectIndex); - } - - } - objectsWithAliases = std::move(pendingObjects); - } while (!objectsWithAliases.isEmpty()); -} - -template <typename ObjectContainer> -inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const -{ - const CompiledObject &object = *objectContainer->objectAt(objectIndex); - if (object.aliasCount() > 0) - objectsWithAliases->append(objectIndex); - - // Stop at Component boundary - if (object.hasFlag(QV4::CompiledData::Object::IsComponent) && objectIndex != /*root object*/0) - return; - - auto binding = object.bindingsBegin(); - auto end = object.bindingsEnd(); - for (; binding != end; ++binding) { - switch (binding->type()) { - case QV4::CompiledData::Binding::Type_Object: - case QV4::CompiledData::Binding::Type_AttachedProperty: - case QV4::CompiledData::Binding::Type_GroupProperty: - collectObjectsWithAliasesRecursively(binding->value.objectIndex, objectsWithAliases); - break; - default: - break; - } - } } template <typename ObjectContainer> @@ -912,7 +792,8 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor lastAlias = targetAlias; } while (lastAlias->isAliasToLocalAlias()); - return propertyDataForAlias(component, *lastAlias, type, version, propertyFlags, enginePriv); + return propertyDataForAlias( + component, *lastAlias, type, version, propertyFlags, enginePriv); } const int targetObjectIndex = objectForId(component, alias.targetObjectId()); @@ -947,7 +828,8 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor propertyFlags->type = QQmlPropertyData::Flags::QObjectDerivedType; } else { int coreIndex = QQmlPropertyIndex::fromEncoded(alias.encodedMetaPropertyIndex).coreIndex(); - int valueTypeIndex = QQmlPropertyIndex::fromEncoded(alias.encodedMetaPropertyIndex).valueTypeIndex(); + int valueTypeIndex = QQmlPropertyIndex::fromEncoded( + alias.encodedMetaPropertyIndex).valueTypeIndex(); QQmlPropertyCache::ConstPtr targetCache = propertyCaches->at(targetObjectIndex); Q_ASSERT(targetCache); |