diff options
author | Fabian Kosmale <[email protected]> | 2024-11-22 15:03:48 +0100 |
---|---|---|
committer | Fabian Kosmale <[email protected]> | 2024-12-04 21:26:24 +0100 |
commit | 84835c51f335acf15982d987cd4486479c1719eb (patch) | |
tree | 1d9923423c94d9f705ff29338d7510c4a4e7fd96 | |
parent | cb0ae6730f66639eb8447f74d76824ed77ad4421 (diff) |
Move inlineComponentName from CU to ObjectCreator
A (base) compilation unit should ideally be immutable, as we otherwise
open a can of worms when it comes to cross-thread usage of CUs. However,
so far, we've been using a mutable inlineComponentName member of the
compilation unit to select whether the root component of a CU should be
constructed, or one of its inline components.
This patch change prepares for making the CU immutable, by moving the
inline component name tracking into the ObjectCreator itself, requiring
that the name gets passed into its constructor – or that an empty string
gets passed in case of the main component.
The resulting refactoring makes it apparent that deferred properties
did not handle inline components at all. Support for them gets added by
also storing the inline component name inside of DeferredData, and
passing it along when needed. A test case which verifies that deferred
properties are now fixed is added as a follow-up commit.
Besides the core engine, we also need to adjust qmltc which also
generates code to handle deferred properties. Consequently, we also need
to pass the inline component name along in the qmltc generated code.
Task-number: QTBUG-131442
Pick-to: 6.5 6.8
Change-Id: Ide9bc98223c01225b954662b3f4989bbbfda7672
Reviewed-by: Ulf Hermann <[email protected]>
-rw-r--r-- | src/qml/common/qv4compileddata.cpp | 61 | ||||
-rw-r--r-- | src/qml/common/qv4compileddata_p.h | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit_p.h | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent.cpp | 15 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent_p.h | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmldata_p.h | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 43 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 14 | ||||
-rw-r--r-- | src/qmlmeta/types/qqmlbind.cpp | 2 | ||||
-rw-r--r-- | src/quicktemplates/qquickdeferredexecute.cpp | 5 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 2 | ||||
-rw-r--r-- | tools/qmltc/qmltccompilerpieces.h | 10 |
13 files changed, 91 insertions, 91 deletions
diff --git a/src/qml/common/qv4compileddata.cpp b/src/qml/common/qv4compileddata.cpp index 9dee91f713..80b806ec2d 100644 --- a/src/qml/common/qv4compileddata.cpp +++ b/src/qml/common/qv4compileddata.cpp @@ -14,6 +14,7 @@ #include <QtCore/qdir.h> #include <QtCore/qscopeguard.h> #include <QtCore/qstandardpaths.h> +#include <QtCore/qxpfunctional.h> static_assert(QV4::CompiledData::QmlCompileHashSpace > QML_COMPILE_HASH_LENGTH); @@ -245,44 +246,30 @@ ResolvedTypeReference *CompilationUnit::resolvedType(QMetaType type) const } -int CompilationUnit::totalBindingsCount() const +int CompilationUnit::totalBindingsCount(const QString &inlineComponentRootName) const { - if (!icRootName) + if (inlineComponentRootName.isEmpty()) return m_totalBindingsCount; - return inlineComponentData[*icRootName].totalBindingCount; + return inlineComponentData[inlineComponentRootName].totalBindingCount; } -int CompilationUnit::totalObjectCount() const +int CompilationUnit::totalObjectCount(const QString &inlineComponentRootName) const { - if (!icRootName) + if (inlineComponentRootName.isEmpty()) return m_totalObjectCount; - return inlineComponentData[*icRootName].totalObjectCount; + return inlineComponentData[inlineComponentRootName].totalObjectCount; } -template<typename F> -void processInlinComponentType( + +static void processInlinComponentType( const QQmlType &type, - const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, - F &&populateIcData) + qxp::function_ref<void(const QString&)> &&populateIcData) { + QString icRootName; if (type.isInlineComponentType()) { - QString icRootName; - if (compilationUnit->icRootName) { - icRootName = type.elementName(); - std::swap(*compilationUnit->icRootName, icRootName); - } else { - compilationUnit->icRootName = std::make_unique<QString>(type.elementName()); - } - - populateIcData(); - - if (icRootName.isEmpty()) - compilationUnit->icRootName.reset(); - else - std::swap(*compilationUnit->icRootName, icRootName); - } else { - populateIcData(); + icRootName = type.elementName(); } + populateIcData(icRootName); } void CompiledData::CompilationUnit::finalizeCompositeType(const QQmlType &type) @@ -357,11 +344,11 @@ void CompiledData::CompilationUnit::finalizeCompositeType(const QQmlType &type) // if the type is an inline component type, we have to extract the information // from it. // This requires that inline components are visited in the correct order. - processInlinComponentType(type, compilationUnit, [&]() { + processInlinComponentType(type, [&](const QString ¤tlyVisitedICName) { auto &icData = inlineComponentData[lastICRootName]; - icData.totalBindingCount += compilationUnit->totalBindingsCount(); - icData.totalParserStatusCount += compilationUnit->totalParserStatusCount(); - icData.totalObjectCount += compilationUnit->totalObjectCount(); + icData.totalBindingCount += compilationUnit->totalBindingsCount(currentlyVisitedICName); + icData.totalParserStatusCount += compilationUnit->totalParserStatusCount(currentlyVisitedICName); + icData.totalObjectCount += compilationUnit->totalObjectCount(currentlyVisitedICName); }); } } @@ -382,10 +369,10 @@ void CompiledData::CompilationUnit::finalizeCompositeType(const QQmlType &type) ++parserStatusCount; ++objectCount; if (const auto compilationUnit = typeRef->compilationUnit()) { - processInlinComponentType(type, compilationUnit, [&](){ - bindingCount += compilationUnit->totalBindingsCount(); - parserStatusCount += compilationUnit->totalParserStatusCount(); - objectCount += compilationUnit->totalObjectCount(); + processInlinComponentType(type, [&](const QString ¤tlyVisitedICName){ + bindingCount += compilationUnit->totalBindingsCount(currentlyVisitedICName); + parserStatusCount += compilationUnit->totalParserStatusCount(currentlyVisitedICName); + objectCount += compilationUnit->totalObjectCount(currentlyVisitedICName); }); } } @@ -396,11 +383,11 @@ void CompiledData::CompilationUnit::finalizeCompositeType(const QQmlType &type) m_totalObjectCount = objectCount; } -int CompilationUnit::totalParserStatusCount() const +int CompilationUnit::totalParserStatusCount(const QString &inlineComponentRootName) const { - if (!icRootName) + if (inlineComponentRootName.isEmpty()) return m_totalParserStatusCount; - return inlineComponentData[*icRootName].totalParserStatusCount; + return inlineComponentData[inlineComponentRootName].totalParserStatusCount; } bool CompilationUnit::verifyChecksum(const DependentTypesHasher &dependencyHasher) const diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index 1ee7a5cbd4..18d2a4c114 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -1483,7 +1483,6 @@ struct CompilationUnit final : public QQmlRefCounted<CompilationUnit> int m_totalParserStatusCount = 0; // Number of instantiated types that are QQmlParserStatus subclasses int m_totalObjectCount = 0; // Number of objects explicitly instantiated - std::unique_ptr<QString> icRootName; QHash<QString, InlineComponentData> inlineComponentData; // index is object index. This allows fast access to the @@ -1655,9 +1654,9 @@ public: int objectCount() const { return qmlData->nObjects; } const CompiledObject *objectAt(int index) const { return qmlData->objectAt(index); } - int totalBindingsCount() const; - int totalParserStatusCount() const; - int totalObjectCount() const; + int totalBindingsCount(const QString &inlineComponentRootName) const; + int totalParserStatusCount(const QString &inlineComponentRootName) const; + int totalObjectCount(const QString &inlineComponentRootName) const; int inlineComponentId(const QString &inlineComponentName) const { diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h index b7a52523fb..b09686278e 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit_p.h +++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h @@ -99,9 +99,9 @@ public: QHash<int, IdentifierHash> namedObjectsPerComponentCache; inline IdentifierHash namedObjectsPerComponent(int componentObjectIndex); - int totalBindingsCount() const { return m_compilationUnit->totalBindingsCount(); } - int totalParserStatusCount() const { return m_compilationUnit->totalParserStatusCount(); } - int totalObjectCount() const { return m_compilationUnit->totalObjectCount(); } + int totalBindingsCount(const QString &inlineComponentRoot) const { return m_compilationUnit->totalBindingsCount(inlineComponentRoot); } + int totalParserStatusCount(const QString &inlineComponentRoot) const { return m_compilationUnit->totalParserStatusCount(inlineComponentRoot); } + int totalObjectCount(const QString &inlineComponentRoot) const { return m_compilationUnit->totalObjectCount(inlineComponentRoot); } ResolvedTypeReference *resolvedType(int id) const { diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 93810b44fe..0ae85b8fa5 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1099,10 +1099,11 @@ QObject *QQmlComponentPrivate::beginCreate(QQmlRefPointer<QQmlContextData> conte const QQmlType type = loadedType(); if (!type.isValid()) { enginePriv->referenceScarceResources(); - state.initCreator(context, compilationUnit, creationContext); + const QString *icName = inlineComponentName.get(); + state.initCreator(context, compilationUnit, creationContext, icName ? *icName : QString()); QQmlObjectCreator::CreationFlags flags; - if (const QString *icName = inlineComponentName.get()) { + if (icName) { flags = QQmlObjectCreator::InlineComponent; if (start == -1) start = compilationUnit->inlineComponentId(*icName); @@ -1172,7 +1173,9 @@ void QQmlComponentPrivate::beginDeferred(QQmlEnginePrivate *enginePriv, auto creator = state.initCreator( deferredData->context->parent(), deferredData->compilationUnit, - QQmlRefPointer<QQmlContextData>()); + QQmlRefPointer<QQmlContextData>(), + deferredData->inlineComponentName + ); if (!creator->populateDeferredProperties(object, deferredData)) state.appendCreatorErrors(); @@ -1546,7 +1549,9 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context, QQmlC p->compilationUnit = d->compilationUnit; p->enginePriv = enginePriv; - p->creator.reset(new QQmlObjectCreator(contextData, d->compilationUnit, d->creationContext, p.data())); + p->creator.reset(new QQmlObjectCreator(contextData, d->compilationUnit, d->creationContext, + d->inlineComponentName ? *d->inlineComponentName : QString(), + p.data())); p->subComponentToCreate = d->start; enginePriv->incubate(incubator, forContextData); @@ -1618,7 +1623,7 @@ void QQmlComponentPrivate::incubateObject( incubatorPriv->compilationUnit = componentPriv->compilationUnit; incubatorPriv->enginePriv = enginePriv; - incubatorPriv->creator.reset(new QQmlObjectCreator(context, componentPriv->compilationUnit, componentPriv->creationContext)); + incubatorPriv->creator.reset(new QQmlObjectCreator(context, componentPriv->compilationUnit, componentPriv->creationContext, inlineComponentName ? *inlineComponentName : QString())); if (start == -1) { if (const QString *icName = componentPriv->inlineComponentName.get()) { diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index 09d59f6597..0e9d16e302 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -132,7 +132,8 @@ public: inline QQmlObjectCreator *initCreator( const QQmlRefPointer<QQmlContextData> &parentContext, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, - const QQmlRefPointer<QQmlContextData> &creationContext); + const QQmlRefPointer<QQmlContextData> &creationContext, + const QString &inlineComponentName); QList<AnnotatedQmlError> errors; inline bool isCompletePending() const; @@ -288,14 +289,15 @@ inline void QQmlComponentPrivate::ConstructionState::clear() inline QQmlObjectCreator *QQmlComponentPrivate::ConstructionState::initCreator( const QQmlRefPointer<QQmlContextData> &parentContext, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, - const QQmlRefPointer<QQmlContextData> &creationContext) + const QQmlRefPointer<QQmlContextData> &creationContext, + const QString &inlineComponentName) { if (m_creatorOrRequiredProperties.isT1()) delete m_creatorOrRequiredProperties.asT1(); else delete m_creatorOrRequiredProperties.asT2(); m_creatorOrRequiredProperties = new QQmlObjectCreator( - parentContext, compilationUnit, creationContext); + parentContext, compilationUnit, creationContext, inlineComponentName); return m_creatorOrRequiredProperties.asT1(); } diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index 7055ca94e6..f4bec851ce 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -181,13 +181,17 @@ public: // Could be either context or outerContext QQmlRefPointer<QQmlContextData> context; + /* set if the deferred binding originates in an inline component, + necessary to adjust the compilationUnit; null if there was no + inline component */ + QString inlineComponentName; Q_DISABLE_COPY(DeferredData); }; QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit; QVector<DeferredData *> deferredData; void deferData(int objectIndex, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &, - const QQmlRefPointer<QQmlContextData> &); + const QQmlRefPointer<QQmlContextData> &, const QString &inlineComponentName); void releaseDeferredData(); QV4::WeakValue jsWrapper; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 119c0a3f0e..8f4758fe35 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1232,12 +1232,13 @@ void QQmlData::NotifyList::layout() void QQmlData::deferData( int objectIndex, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, - const QQmlRefPointer<QQmlContextData> &context) + const QQmlRefPointer<QQmlContextData> &context, const QString &inlineComponentName) { QQmlData::DeferredData *deferData = new QQmlData::DeferredData; deferData->deferredIdx = objectIndex; deferData->compilationUnit = compilationUnit; deferData->context = context; + deferData->inlineComponentName = inlineComponentName; const QV4::CompiledData::Object *compiledObject = compilationUnit->objectAt(objectIndex); const QV4::CompiledData::BindingPropertyData *propertyData diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 045678b76c..ecf4425836 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -55,8 +55,10 @@ QQmlObjectCreator::QQmlObjectCreator( const QQmlRefPointer<QQmlContextData> &parentContext, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QQmlRefPointer<QQmlContextData> &creationContext, + const QString &inlineComponentName, QQmlIncubatorPrivate *incubator) : phase(Startup) + , m_inlineComponentName(inlineComponentName) , compilationUnit(compilationUnit) , propertyCaches(compilationUnit->propertyCachesPtr()) , sharedState(new QQmlObjectCreatorSharedState, QQmlRefPointer<QQmlObjectCreatorSharedState>::Adopt) @@ -67,9 +69,9 @@ QQmlObjectCreator::QQmlObjectCreator( init(parentContext); sharedState->componentAttached = nullptr; - sharedState->allCreatedBindings.allocate(compilationUnit->totalBindingsCount()); - sharedState->allParserStatusCallbacks.allocate(compilationUnit->totalParserStatusCount()); - sharedState->allCreatedObjects.allocate(compilationUnit->totalObjectCount()); + sharedState->allCreatedBindings.allocate(compilationUnit->totalBindingsCount(inlineComponentName)); + sharedState->allParserStatusCallbacks.allocate(compilationUnit->totalParserStatusCount(inlineComponentName)); + sharedState->allCreatedObjects.allocate(compilationUnit->totalObjectCount(inlineComponentName)); sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList(); sharedState->creationContext = creationContext; sharedState->rootContext.reset(); @@ -77,17 +79,17 @@ QQmlObjectCreator::QQmlObjectCreator( if (auto profiler = QQmlEnginePrivate::get(engine)->profiler) { Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler, - sharedState->profiler.init(profiler, compilationUnit->totalParserStatusCount())); + sharedState->profiler.init(profiler, compilationUnit->totalParserStatusCount(inlineComponentName))); } else { Q_UNUSED(profiler); } } -QQmlObjectCreator::QQmlObjectCreator( - const QQmlRefPointer<QQmlContextData> &parentContext, - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, - QQmlObjectCreatorSharedState *inheritedSharedState, bool isContextObject) +QQmlObjectCreator::QQmlObjectCreator(const QQmlRefPointer<QQmlContextData> &parentContext, + const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QString inlineComponentName, + QQmlObjectCreatorSharedState *inheritedSharedState, bool isContextObject) : phase(Startup) + , m_inlineComponentName(inlineComponentName) , compilationUnit(compilationUnit) , propertyCaches(compilationUnit->propertyCachesPtr()) , sharedState(inheritedSharedState) @@ -192,7 +194,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI Q_ASSERT(sharedState->allJavaScriptObjects.canTrack() || topLevelCreator); if (topLevelCreator) - sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList(scope, compilationUnit->totalObjectCount()); + sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList(scope, compilationUnit->totalObjectCount(m_inlineComponentName)); if (!isComponentRoot && sharedState->creationContext) { // otherwise QQmlEnginePrivate::createInternalContext() handles it @@ -240,7 +242,7 @@ void QQmlObjectCreator::beginPopulateDeferred(const QQmlRefPointer<QQmlContextDa // FIXME (QTBUG-122956): allocating from the short lived scope does not make any sense QV4::Scope valueScope(v4); - sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList(valueScope, compilationUnit->totalObjectCount()); + sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList(valueScope, compilationUnit->totalObjectCount(m_inlineComponentName)); } void QQmlObjectCreator::populateDeferred(QObject *instance, int deferredIndex, @@ -1345,6 +1347,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo QQmlObjectCreator subCreator( context, engine->handle()->executableCompilationUnit( std::move(compilationUnit)), + QString(), // not an inline component sharedState.data(), isContextObject); instance = subCreator.create(); if (!instance) { @@ -1352,28 +1355,16 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo return nullptr; } } else { - QString subObjectName; - if (QString *icRootName = compilationUnit->icRootName.get()) { - subObjectName = type.elementName(); - std::swap(*icRootName, subObjectName); - } else { - compilationUnit->icRootName = std::make_unique<QString>(type.elementName()); - } - - const auto guard = qScopeGuard([&] { - if (subObjectName.isEmpty()) - compilationUnit->icRootName.reset(); - else - std::swap(*compilationUnit->icRootName, subObjectName); - }); + const QString inlineComponentName = type.elementName(); const int inlineComponentId - = compilationUnit->inlineComponentId(*compilationUnit->icRootName); + = compilationUnit->inlineComponentId(inlineComponentName); QQmlObjectCreator subCreator( context, engine->handle()->executableCompilationUnit( QQmlRefPointer<QV4::CompiledData::CompilationUnit>( compilationUnit)), + inlineComponentName, sharedState.data(), isContextObject); instance = subCreator.create( @@ -1677,7 +1668,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * _ddata->compilationUnit = compilationUnit; if (_compiledObject->hasFlag(QV4::CompiledData::Object::HasDeferredBindings)) - _ddata->deferData(_compiledObjectIndex, compilationUnit, context); + _ddata->deferData(_compiledObjectIndex, compilationUnit, context, m_inlineComponentName); const qsizetype oldRequiredPropertiesCount = sharedState->requiredProperties.size(); QSet<QString> postHocRequired; diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index d13a234c6e..eb0c7aa09a 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -130,11 +130,11 @@ class Q_QML_EXPORT QQmlObjectCreator { Q_DECLARE_TR_FUNCTIONS(QQmlObjectCreator) public: - QQmlObjectCreator( - const QQmlRefPointer<QQmlContextData> &parentContext, - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, - const QQmlRefPointer<QQmlContextData> &creationContext, - QQmlIncubatorPrivate *incubator = nullptr); + QQmlObjectCreator(const QQmlRefPointer<QQmlContextData> &parentContext, + const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, + const QQmlRefPointer<QQmlContextData> &creationContext, + const QString &inlineComponentName, + QQmlIncubatorPrivate *incubator = nullptr); ~QQmlObjectCreator(); enum CreationFlags { NormalObject = 1, InlineComponent = 2 }; @@ -186,6 +186,7 @@ private: QQmlObjectCreator( const QQmlRefPointer<QQmlContextData> &contextData, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, + const QString inlineComponentName, QQmlObjectCreatorSharedState *inheritedSharedState, bool isContextObject); void init(const QQmlRefPointer<QQmlContextData> &parentContext); @@ -237,6 +238,7 @@ private: QQmlEngine *engine; QV4::ExecutionEngine *v4; + QString m_inlineComponentName; QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit; const QV4::CompiledData::Unit *qmlUnit; QQmlGuardedContextData parentContext; @@ -284,7 +286,7 @@ private: QV4::Scope valueScope(v4); QScopedValueRollback<ObjectInCreationGCAnchorList> jsObjectGuard( sharedState->allJavaScriptObjects, - ObjectInCreationGCAnchorList(valueScope, compilationUnit->totalObjectCount())); + ObjectInCreationGCAnchorList(valueScope, compilationUnit->totalObjectCount(m_inlineComponentName))); Q_ASSERT(topLevelCreator); QV4::QmlContext *qmlContext = static_cast<QV4::QmlContext *>(valueScope.alloc()); diff --git a/src/qmlmeta/types/qqmlbind.cpp b/src/qmlmeta/types/qqmlbind.cpp index 168cdcde89..7eca2b2cf0 100644 --- a/src/qmlmeta/types/qqmlbind.cpp +++ b/src/qmlmeta/types/qqmlbind.cpp @@ -764,7 +764,7 @@ static void initCreator( immediateState->setCompletePending(true); immediateState->initCreator( deferredData->context->parent(), deferredData->compilationUnit, - contextData); + contextData, deferredData->inlineComponentName); immediateState->creator()->beginPopulateDeferred(deferredData->context); } } diff --git a/src/quicktemplates/qquickdeferredexecute.cpp b/src/quicktemplates/qquickdeferredexecute.cpp index 90eeae991d..35a051502d 100644 --- a/src/quicktemplates/qquickdeferredexecute.cpp +++ b/src/quicktemplates/qquickdeferredexecute.cpp @@ -9,6 +9,8 @@ #include <QtQml/private/qqmlcomponent_p.h> #include <QtQml/private/qqmlobjectcreator_p.h> +#include <private/qv4resolvedtypereference_p.h> + #include <deque> QT_BEGIN_NAMESPACE @@ -82,7 +84,8 @@ static bool beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &pro state.setCompletePending(true); QQmlContextData *creationContext = nullptr; - state.initCreator(deferData->context->parent(), deferData->compilationUnit, creationContext); + + state.initCreator(deferData->context->parent(), deferData->compilationUnit, creationContext, deferData->inlineComponentName); enginePriv->inProgressCreations++; diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index a97e6f9696..232d0c9c8f 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -5231,7 +5231,7 @@ static void beginDeferredOnce(QQmlEnginePrivate *enginePriv, state.setCompletePending(true); state.initCreator(deferData->context->parent(), deferData->compilationUnit, - QQmlRefPointer<QQmlContextData>()); + QQmlRefPointer<QQmlContextData>(), deferData->inlineComponentName); enginePriv->inProgressCreations++; diff --git a/tools/qmltc/qmltccompilerpieces.h b/tools/qmltc/qmltccompilerpieces.h index 3252f19e86..cd85b1e2f0 100644 --- a/tools/qmltc/qmltccompilerpieces.h +++ b/tools/qmltc/qmltccompilerpieces.h @@ -440,15 +440,21 @@ inline void QmltcCodeGenerator::generate_endInitCode(QmltcType ¤t, generate_qmltcInstructionCallCode(¤t.endInit, type, u"engine"_s, u"creator, engine"_s); if (visitor->hasDeferredBindings(type)) { + QString icName; + if (auto potentialICName = type->enclosingInlineComponentName(); + std::holds_alternative<QQmlJSScope::InlineComponentNameType>(potentialICName)) + icName =get<QQmlJSScope::InlineComponentNameType>(potentialICName); + else + icName = u"{}"_s; current.endInit.body << u"{ // defer bindings"_s; current.endInit.body << u"auto ddata = QQmlData::get(this);"_s; current.endInit.body << u"auto thisContext = ddata->outerContext;"_s; current.endInit.body << u"Q_ASSERT(thisContext);"_s; current.endInit.body << QStringLiteral("ddata->deferData(%1, " "QQmlEnginePrivate::get(engine)->" - "compilationUnitFromUrl(%2()), thisContext);") + "compilationUnitFromUrl(%2()), thisContext, %3);") .arg(QString::number(visitor->qmlIrObjectIndex(type)), - QmltcCodeGenerator::urlMethodName()); + QmltcCodeGenerator::urlMethodName(), icName); current.endInit.body << u"}"_s; } } |