From 2d7fe23b41aa3fd719b7bc8aa585ab799e4a0c39 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 7 Mar 2023 14:39:52 +0100 Subject: 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 Reviewed-by: Fabian Kosmale --- src/qml/qml/qqmlpropertycachecreator_p.h | 146 +++---------------------------- 1 file changed, 14 insertions(+), 132 deletions(-) (limited to 'src/qml/qml/qqmlpropertycachecreator_p.h') 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 @@ -232,20 +224,6 @@ QQmlPropertyCacheCreator::buildMetaObjectsIncrementally() return {diag, false, 0}; } -template -inline QQmlError -QQmlPropertyCacheCreator::buildMetaObjects() -{ - QQmlError error = verifyNoICCycle(); - if (error.isValid()) - return error; - QQmlPropertyCacheCreatorBase::IncrementalResult result; - do { - result = buildMetaObjectsIncrementally(); - } while (result.canResume); - return result.error; -} - template inline QQmlError QQmlPropertyCacheCreator::buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context, VMEMetaObjectIsRequired isVMERequired) { @@ -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 *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 -inline QQmlPropertyCacheAliasCreator::QQmlPropertyCacheAliasCreator(QQmlPropertyCacheVector *propertyCaches, const ObjectContainer *objectContainer) +inline QQmlPropertyCacheAliasCreator::QQmlPropertyCacheAliasCreator( + QQmlPropertyCacheVector *propertyCaches, const ObjectContainer *objectContainer) : propertyCaches(propertyCaches) , objectContainer(objectContainer) { - -} - -template -inline void QQmlPropertyCacheAliasCreator::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 -inline void QQmlPropertyCacheAliasCreator::appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex, QQmlEnginePrivate *enginePriv) -{ - QVector 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 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 -inline void QQmlPropertyCacheAliasCreator::collectObjectsWithAliasesRecursively(int objectIndex, QVector *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 @@ -912,7 +792,8 @@ inline QQmlError QQmlPropertyCacheAliasCreator::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::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); -- cgit v1.2.3