diff options
35 files changed, 358 insertions, 307 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp index 4bfe758c34..847954d3de 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp @@ -232,7 +232,8 @@ GatherSourcesJob::GatherSourcesJob(QV4::ExecutionEngine *engine) void GatherSourcesJob::run() { - for (QV4::ExecutableCompilationUnit *unit : engine->compilationUnits()) { + const auto compilationUnits = engine->compilationUnits(); + for (const auto &unit : compilationUnits) { QString fileName = unit->fileName(); if (!fileName.isEmpty()) sources.append(fileName); diff --git a/src/qml/common/qv4compileddata.cpp b/src/qml/common/qv4compileddata.cpp index 411e8cb0b7..621a3c0326 100644 --- a/src/qml/common/qv4compileddata.cpp +++ b/src/qml/common/qv4compileddata.cpp @@ -3,6 +3,7 @@ #include "qv4compileddata_p.h" +#include <private/inlinecomponentutils_p.h> #include <private/qqmlscriptdata_p.h> #include <private/qqmltypenamecache_p.h> #include <private/qv4resolvedtypereference_p.h> @@ -192,6 +193,143 @@ int CompilationUnit::totalObjectCount() const return inlineComponentData[*icRootName].totalObjectCount; } +template<typename F> +void processInlinComponentType( + const QQmlType &type, + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, + F &&populateIcData) +{ + 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(); + } +} + +void CompiledData::CompilationUnit::finalizeCompositeType(const QQmlType &type) +{ + // Add to type registry of composites + if (propertyCaches.needsVMEMetaObject(/*root object*/0)) { + // qmlType is only valid for types that have references to themselves. + if (type.isValid()) { + qmlType = type; + } else { + qmlType = QQmlMetaType::findCompositeType( + finalUrl(), this, (unitData()->flags & CompiledData::Unit::IsSingleton) + ? QQmlMetaType::Singleton + : QQmlMetaType::NonSingleton); + } + + QQmlMetaType::registerInternalCompositeType(this); + } else { + const QV4::CompiledData::Object *obj = objectAt(/*root object*/0); + auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex); + Q_ASSERT(typeRef); + if (const auto compilationUnit = typeRef->compilationUnit()) + qmlType = compilationUnit->qmlType; + else + qmlType = typeRef->type(); + } + + // Collect some data for instantiation later. + using namespace icutils; + std::vector<QV4::CompiledData::InlineComponent> allICs {}; + for (int i=0; i != objectCount(); ++i) { + const CompiledObject *obj = objectAt(i); + for (auto it = obj->inlineComponentsBegin(); it != obj->inlineComponentsEnd(); ++it) { + allICs.push_back(*it); + } + } + NodeList nodes; + nodes.resize(allICs.size()); + std::iota(nodes.begin(), nodes.end(), 0); + AdjacencyList adjacencyList; + adjacencyList.resize(nodes.size()); + fillAdjacencyListForInlineComponents(this, adjacencyList, nodes, allICs); + bool hasCycle = false; + auto nodesSorted = topoSort(nodes, adjacencyList, hasCycle); + Q_ASSERT(!hasCycle); // would have already been discovered by qqmlpropertycachcecreator + + // We need to first iterate over all inline components, + // as the containing component might create instances of them + // and in that case we need to add its object count + for (auto nodeIt = nodesSorted.rbegin(); nodeIt != nodesSorted.rend(); ++nodeIt) { + const auto &ic = allICs.at(nodeIt->index()); + const int lastICRoot = ic.objectIndex; + for (int i = ic.objectIndex; i<objectCount(); ++i) { + const QV4::CompiledData::Object *obj = objectAt(i); + bool leftCurrentInlineComponent + = (i != lastICRoot + && obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot)) + || !obj->hasFlag(QV4::CompiledData::Object::IsPartOfInlineComponent); + if (leftCurrentInlineComponent) + break; + const QString lastICRootName = stringAt(ic.nameIndex); + inlineComponentData[lastICRootName].totalBindingCount + += obj->nBindings; + + if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) { + const auto type = typeRef->type(); + if (type.isValid() && type.parserStatusCast() != -1) + ++inlineComponentData[lastICRootName].totalParserStatusCount; + + ++inlineComponentData[lastICRootName].totalObjectCount; + if (const auto compilationUnit = typeRef->compilationUnit()) { + // 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, [&]() { + auto &icData = inlineComponentData[lastICRootName]; + icData.totalBindingCount += compilationUnit->totalBindingsCount(); + icData.totalParserStatusCount += compilationUnit->totalParserStatusCount(); + icData.totalObjectCount += compilationUnit->totalObjectCount(); + }); + } + } + } + } + int bindingCount = 0; + int parserStatusCount = 0; + int objectCount = 0; + for (quint32 i = 0, count = this->objectCount(); i < count; ++i) { + const QV4::CompiledData::Object *obj = objectAt(i); + if (obj->hasFlag(QV4::CompiledData::Object::IsPartOfInlineComponent)) + continue; + + bindingCount += obj->nBindings; + if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) { + const auto type = typeRef->type(); + if (type.isValid() && type.parserStatusCast() != -1) + ++parserStatusCount; + ++objectCount; + if (const auto compilationUnit = typeRef->compilationUnit()) { + processInlinComponentType(type, compilationUnit, [&](){ + bindingCount += compilationUnit->totalBindingsCount(); + parserStatusCount += compilationUnit->totalParserStatusCount(); + objectCount += compilationUnit->totalObjectCount(); + }); + } + } + } + + m_totalBindingsCount = bindingCount; + m_totalParserStatusCount = parserStatusCount; + m_totalObjectCount = objectCount; +} + int CompilationUnit::totalParserStatusCount() const { if (!icRootName) diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index 93f9231007..8fe6c8c87b 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -1668,6 +1668,8 @@ public: return -1; } + void finalizeCompositeType(const QQmlType &type); + bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const; enum class ListPropertyAssignBehavior { Append, Replace, ReplaceIfNotDefault }; diff --git a/src/qml/inlinecomponentutils_p.h b/src/qml/inlinecomponentutils_p.h index ba08bb5c80..c7a93c870b 100644 --- a/src/qml/inlinecomponentutils_p.h +++ b/src/qml/inlinecomponentutils_p.h @@ -14,6 +14,7 @@ // We mean it. // +#include <private/qqmlmetatype_p.h> #include <private/qv4compileddata_p.h> #include <private/qv4resolvedtypereference_p.h> diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 0314b6d997..63b388c19f 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -848,7 +848,6 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) ExecutionEngine::~ExecutionEngine() { - modules.clear(); for (auto val : nativeModules) { PersistentValueStorage::free(val); } @@ -859,14 +858,12 @@ ExecutionEngine::~ExecutionEngine() delete identifierTable; delete memoryManager; - // Take a temporary reference to the CU so that it doesn't disappear during unlinking. - while (!m_compilationUnits.isEmpty()) { - QQmlRefPointer<ExecutableCompilationUnit> cu(*m_compilationUnits.begin()); + for (const auto &cu : std::as_const(m_compilationUnits)) { Q_ASSERT(cu->engine == this); cu->clear(); cu->engine = nullptr; - cu->nextCompilationUnit.remove(); } + m_compilationUnits.clear(); delete bumperPointerAllocator; delete regExpCache; @@ -1330,7 +1327,7 @@ void ExecutionEngine::markObjects(MarkStack *markStack) identifierTable->markObjects(markStack); - for (const auto &compilationUnit : m_compilationUnits) + for (const auto &compilationUnit : std::as_const(m_compilationUnits)) compilationUnit->markObjects(markStack); } @@ -2119,17 +2116,29 @@ QQmlRefPointer<ExecutableCompilationUnit> ExecutionEngine::compileModule( return executableCompilationUnit(std::move(unit)); } +QQmlRefPointer<ExecutableCompilationUnit> ExecutionEngine::compilationUnitForUrl(const QUrl &url) const +{ + return m_compilationUnits.value(url); +} + QQmlRefPointer<ExecutableCompilationUnit> ExecutionEngine::executableCompilationUnit( QQmlRefPointer<CompiledData::CompilationUnit> &&unit) { - return ExecutableCompilationUnit::create(std::move(unit), this); + QQmlRefPointer<QV4::ExecutableCompilationUnit> &result = m_compilationUnits[unit->finalUrl()]; + if (!result || result->baseCompilationUnit() != unit) + result = ExecutableCompilationUnit::create(std::move(unit), this); + + return result; } -void ExecutionEngine::injectCompiledModule(const QQmlRefPointer<ExecutableCompilationUnit> &moduleUnit) +void ExecutionEngine::trimCompilationUnits() { - // Injection can happen from the QML type loader thread for example, but instantiation and - // evaluation must be limited to the ExecutionEngine's thread. - modules.insert(moduleUnit->finalUrl(), moduleUnit); + for (auto it = m_compilationUnits.begin(); it != m_compilationUnits.end();) { + if ((*it)->count() == 1) + it = m_compilationUnits.erase(it); + else + ++it; + } } ExecutionEngine::Module ExecutionEngine::moduleForUrl( @@ -2142,8 +2151,8 @@ ExecutionEngine::Module ExecutionEngine::moduleForUrl( const QUrl resolved = referrer ? referrer->finalUrl().resolved(QQmlTypeLoader::normalize(url)) : QQmlTypeLoader::normalize(url); - auto existingModule = modules.find(resolved); - if (existingModule == modules.end()) + auto existingModule = m_compilationUnits.find(resolved); + if (existingModule == m_compilationUnits.end()) return Module { nullptr, nullptr }; return Module { *existingModule, nullptr }; } @@ -2157,13 +2166,13 @@ ExecutionEngine::Module ExecutionEngine::loadModule(const QUrl &url, const Execu const QUrl resolved = referrer ? referrer->finalUrl().resolved(QQmlTypeLoader::normalize(url)) : QQmlTypeLoader::normalize(url); - auto existingModule = modules.find(resolved); - if (existingModule != modules.end()) + auto existingModule = m_compilationUnits.find(resolved); + if (existingModule != m_compilationUnits.end()) return Module { *existingModule, nullptr }; auto newModule = compileModule(resolved); if (newModule) - modules.insert(resolved, newModule); + m_compilationUnits.insert(resolved, newModule); return Module { newModule, nullptr }; } diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index fc4940d006..28242d35c8 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -496,11 +496,6 @@ public: Symbol *symbol_unscopables() const { return reinterpret_cast<Symbol *>(jsSymbols + Symbol_unscopables); } Symbol *symbol_revokableProxy() const { return reinterpret_cast<Symbol *>(jsSymbols + Symbol_revokableProxy); } - using CompilationUnitList = QIntrusiveList< - ExecutableCompilationUnit, &ExecutableCompilationUnit::nextCompilationUnit>; - CompilationUnitList &compilationUnits() { return m_compilationUnits; } - const CompilationUnitList &compilationUnits() const { return m_compilationUnits; } - quint32 m_engineId; RegExpCache *regExpCache; @@ -758,10 +753,16 @@ public: QQmlRefPointer<ExecutableCompilationUnit> compileModule( const QUrl &url, const QString &sourceCode, const QDateTime &sourceTimeStamp); + QQmlRefPointer<ExecutableCompilationUnit> compilationUnitForUrl(const QUrl &url) const; QQmlRefPointer<ExecutableCompilationUnit> executableCompilationUnit( QQmlRefPointer<QV4::CompiledData::CompilationUnit> &&unit); + QHash<QUrl, QQmlRefPointer<ExecutableCompilationUnit>> compilationUnits() const + { + return m_compilationUnits; + } + void clearCompilationUnits() { m_compilationUnits.clear(); } + void trimCompilationUnits(); - void injectCompiledModule(const QQmlRefPointer<ExecutableCompilationUnit> &moduleUnit); QV4::Value *registerNativeModule(const QUrl &url, const QV4::Value &module); struct Module { @@ -877,15 +878,13 @@ private: QVector<Deletable *> m_extensionData; - QHash<QUrl, QQmlRefPointer<ExecutableCompilationUnit>> modules; + QHash<QUrl, QQmlRefPointer<ExecutableCompilationUnit>> m_compilationUnits; // QV4::PersistentValue would be preferred, but using QHash will create copies, // and QV4::PersistentValue doesn't like creating copies. // Instead, we allocate a raw pointer using the same manual memory management // technique in QV4::PersistentValue. QHash<QUrl, Value *> nativeModules; - - CompilationUnitList m_compilationUnits; }; #define CHECK_STACK_LIMITS(v4) \ diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index d35090d293..812a3a5607 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -19,7 +19,6 @@ #include <private/qv4compilationunitmapper_p.h> #include <private/qml_compile_hash_p.h> #include <private/qqmltypewrapper_p.h> -#include <private/inlinecomponentutils_p.h> #include <private/qv4resolvedtypereference_p.h> #include <private/qv4objectiterator_p.h> @@ -58,8 +57,8 @@ ExecutableCompilationUnit::ExecutableCompilationUnit( ExecutableCompilationUnit::~ExecutableCompilationUnit() { - clear(); - nextCompilationUnit.remove(); + if (engine) + clear(); } static QString toString(QV4::ReturnedValue v) @@ -326,32 +325,6 @@ IdentifierHash ExecutableCompilationUnit::createNamedObjectsPerComponent(int com return *namedObjectsPerComponentCache.insert(componentObjectIndex, namedObjectCache); } -template<typename F> -void processInlinComponentType( - const QQmlType &type, - const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, - F &&populateIcData) -{ - 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(); - } -} - QQmlRefPointer<ExecutableCompilationUnit> ExecutableCompilationUnit::create( QQmlRefPointer<CompiledData::CompilationUnit> &&compilationUnit, ExecutionEngine *engine) { @@ -359,119 +332,9 @@ QQmlRefPointer<ExecutableCompilationUnit> ExecutableCompilationUnit::create( new ExecutableCompilationUnit(std::move(compilationUnit)), QQmlRefPointer<ExecutableCompilationUnit>::Adopt); result->engine = engine; - engine->compilationUnits().insert(result.data()); return result; } -void ExecutableCompilationUnit::finalizeCompositeType(const QQmlType &type) -{ - // Add to type registry of composites - if (m_compilationUnit->propertyCaches.needsVMEMetaObject(/*root object*/0)) { - // qmlType is only valid for types that have references to themselves. - if (type.isValid()) { - m_compilationUnit->qmlType = type; - } else { - m_compilationUnit->qmlType = QQmlMetaType::findCompositeType( - finalUrl(), this, (unitData()->flags & CompiledData::Unit::IsSingleton) - ? QQmlMetaType::Singleton - : QQmlMetaType::NonSingleton); - } - - QQmlMetaType::registerInternalCompositeType(this); - } else { - const QV4::CompiledData::Object *obj = objectAt(/*root object*/0); - auto *typeRef = m_compilationUnit->resolvedTypes.value(obj->inheritedTypeNameIndex); - Q_ASSERT(typeRef); - if (const auto compilationUnit = typeRef->compilationUnit()) - m_compilationUnit->qmlType = compilationUnit->m_compilationUnit->qmlType; - else - m_compilationUnit->qmlType = typeRef->type(); - } - - // Collect some data for instantiation later. - using namespace icutils; - std::vector<QV4::CompiledData::InlineComponent> allICs {}; - for (int i=0; i != objectCount(); ++i) { - const CompiledObject *obj = objectAt(i); - for (auto it = obj->inlineComponentsBegin(); it != obj->inlineComponentsEnd(); ++it) { - allICs.push_back(*it); - } - } - NodeList nodes; - nodes.resize(allICs.size()); - std::iota(nodes.begin(), nodes.end(), 0); - AdjacencyList adjacencyList; - adjacencyList.resize(nodes.size()); - fillAdjacencyListForInlineComponents(this, adjacencyList, nodes, allICs); - bool hasCycle = false; - auto nodesSorted = topoSort(nodes, adjacencyList, hasCycle); - Q_ASSERT(!hasCycle); // would have already been discovered by qqmlpropertycachcecreator - - // We need to first iterate over all inline components, as the containing component might create instances of them - // and in that case we need to add its object count - for (auto nodeIt = nodesSorted.rbegin(); nodeIt != nodesSorted.rend(); ++nodeIt) { - const auto &ic = allICs.at(nodeIt->index()); - const int lastICRoot = ic.objectIndex; - for (int i = ic.objectIndex; i<objectCount(); ++i) { - const QV4::CompiledData::Object *obj = objectAt(i); - bool leftCurrentInlineComponent - = (i != lastICRoot - && obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot)) - || !obj->hasFlag(QV4::CompiledData::Object::IsPartOfInlineComponent); - if (leftCurrentInlineComponent) - break; - const QString lastICRootName = stringAt(ic.nameIndex); - m_compilationUnit->inlineComponentData[lastICRootName].totalBindingCount - += obj->nBindings; - - if (auto *typeRef = m_compilationUnit->resolvedTypes.value(obj->inheritedTypeNameIndex)) { - const auto type = typeRef->type(); - if (type.isValid() && type.parserStatusCast() != -1) - ++m_compilationUnit->inlineComponentData[lastICRootName].totalParserStatusCount; - - ++m_compilationUnit->inlineComponentData[lastICRootName].totalObjectCount; - if (const auto compilationUnit = typeRef->compilationUnit()) { - // 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->m_compilationUnit, [&]() { - auto &icData = m_compilationUnit->inlineComponentData[lastICRootName]; - icData.totalBindingCount += compilationUnit->totalBindingsCount(); - icData.totalParserStatusCount += compilationUnit->totalParserStatusCount(); - icData.totalObjectCount += compilationUnit->totalObjectCount(); - }); - } - } - } - } - int bindingCount = 0; - int parserStatusCount = 0; - int objectCount = 0; - for (quint32 i = 0, count = this->objectCount(); i < count; ++i) { - const QV4::CompiledData::Object *obj = objectAt(i); - if (obj->hasFlag(QV4::CompiledData::Object::IsPartOfInlineComponent)) - continue; - - bindingCount += obj->nBindings; - if (auto *typeRef = m_compilationUnit->resolvedTypes.value(obj->inheritedTypeNameIndex)) { - const auto type = typeRef->type(); - if (type.isValid() && type.parserStatusCast() != -1) - ++parserStatusCount; - ++objectCount; - if (const auto compilationUnit = typeRef->compilationUnit()) { - processInlinComponentType(type, compilationUnit->m_compilationUnit, [&](){ - bindingCount += compilationUnit->totalBindingsCount(); - parserStatusCount += compilationUnit->totalParserStatusCount(); - objectCount += compilationUnit->totalObjectCount(); - }); - } - } - } - - m_compilationUnit->m_totalBindingsCount = bindingCount; - m_compilationUnit->m_totalParserStatusCount = parserStatusCount; - m_compilationUnit->m_totalObjectCount = objectCount; -} - Heap::Module *ExecutableCompilationUnit::instantiate() { const CompiledData::Unit *data = m_compilationUnit->data; diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h index 0f0f8af399..014bb5e5e5 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit_p.h +++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h @@ -69,8 +69,8 @@ class Q_QML_EXPORT ExecutableCompilationUnit final public: friend class QQmlRefCounted<ExecutableCompilationUnit>; friend class QQmlRefPointer<ExecutableCompilationUnit>; + friend struct ExecutionEngine; - QIntrusiveListNode nextCompilationUnit; ExecutionEngine *engine = nullptr; QString finalUrlString() const { return m_compilationUnit->finalUrlString(); } @@ -109,8 +109,6 @@ public: QHash<int, IdentifierHash> namedObjectsPerComponentCache; inline IdentifierHash namedObjectsPerComponent(int componentObjectIndex); - void finalizeCompositeType(const QQmlType &type); - const QString *icRootName() const { return m_compilationUnit->icRootName.get(); } QString *icRootName() { return m_compilationUnit->icRootName.get(); } void setIcRootName(std::unique_ptr<QString> &&icRootName) diff --git a/src/qml/jsruntime/qv4resolvedtypereference_p.h b/src/qml/jsruntime/qv4resolvedtypereference_p.h index 9720c90a12..4aaafdd71c 100644 --- a/src/qml/jsruntime/qv4resolvedtypereference_p.h +++ b/src/qml/jsruntime/qv4resolvedtypereference_p.h @@ -19,7 +19,7 @@ #include <QtQml/private/qqmlrefcount_p.h> #include <QtQml/private/qqmlpropertycache_p.h> #include <QtQml/private/qqmltype_p.h> -#include <QtQml/private/qv4executablecompilationunit_p.h> +#include <QtQml/private/qv4compileddata_p.h> QT_BEGIN_NAMESPACE @@ -46,8 +46,12 @@ public: QQmlType type() const { return m_type; } void setType(QQmlType type) { m_type = std::move(type); } - QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit() { return m_compilationUnit; } - void setCompilationUnit(QQmlRefPointer<QV4::ExecutableCompilationUnit> unit) + QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit() + { + return m_compilationUnit; + } + + void setCompilationUnit(QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit) { if (m_compilationUnit == unit.data()) return; @@ -93,7 +97,7 @@ public: private: QQmlType m_type; QQmlPropertyCache::ConstPtr m_typePropertyCache; - QV4::ExecutableCompilationUnit *m_compilationUnit = nullptr; + QV4::CompiledData::CompilationUnit *m_compilationUnit = nullptr; QTypeRevision m_version = QTypeRevision::zero(); // Types such as QQmlPropertyMap can add properties dynamically at run-time and diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 877efc357b..c45291a856 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -297,7 +297,8 @@ void QQmlComponentPrivate::typeDataProgress(QQmlTypeData *, qreal p) void QQmlComponentPrivate::fromTypeData(const QQmlRefPointer<QQmlTypeData> &data) { url = data->finalUrl(); - compilationUnit.reset(data->compilationUnit()); + if (auto cu = data->compilationUnit()) + compilationUnit = engine->handle()->executableCompilationUnit(std::move(cu)); if (!compilationUnit) { Q_ASSERT(data->isError()); diff --git a/src/qml/qml/qqmldatablob_p.h b/src/qml/qml/qqmldatablob_p.h index d8b7e69ea5..87a7e8e2e8 100644 --- a/src/qml/qml/qqmldatablob_p.h +++ b/src/qml/qml/qqmldatablob_p.h @@ -17,7 +17,6 @@ #include <private/qqmlrefcount_p.h> #include <private/qqmljsdiagnosticmessage_p.h> -#include <private/qv4compileddata_p.h> #if QT_CONFIG(qml_network) #include <QtNetwork/qnetworkreply.h> diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 03058762a4..196312314c 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -632,6 +632,7 @@ void QQmlEngine::clearComponentCache() mm->runGC(); mm->gcStateMachine->timeLimit = std::move(oldLimit); + handle()->clearCompilationUnits(); d->typeLoader.lock(); d->typeLoader.clearCache(); d->typeLoader.unlock(); @@ -653,6 +654,7 @@ void QQmlEngine::clearComponentCache() void QQmlEngine::trimComponentCache() { Q_D(QQmlEngine); + handle()->trimCompilationUnits(); d->typeLoader.trimCache(); } @@ -1967,13 +1969,20 @@ void QQmlEnginePrivate::executeRuntimeFunction(const QV4::ExecutableCompilationU QV4::ExecutableCompilationUnit *QQmlEnginePrivate::compilationUnitFromUrl(const QUrl &url) { + QV4::ExecutionEngine *v4 = v4engine(); + if (auto unit = v4->compilationUnitForUrl(url)) { + if (!unit->runtimeStrings) + unit->populate(); + return unit.data(); + } + auto unit = typeLoader.getType(url)->compilationUnit(); if (!unit) return nullptr; - Q_ASSERT(unit->engine == v4engine()); - if (!unit->runtimeStrings) - unit->populate(); - return unit; + + auto executable = v4->executableCompilationUnit(std::move(unit)); + executable->populate(); + return executable.data(); } QQmlRefPointer<QQmlContextData> diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index fe0d97077b..0b6ea5c977 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -661,7 +661,7 @@ static QQmlType createTypeForUrl( } QQmlType QQmlMetaType::findCompositeType( - const QUrl &url, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, + const QUrl &url, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, CompositeTypeLookupMode mode) { const QUrl normalized = QQmlTypeLoader::normalize(url); @@ -715,7 +715,7 @@ static QQmlType doRegisterInlineComponentType(QQmlMetaTypeData *data, const QUrl } QQmlType QQmlMetaType::findInlineComponentType( - const QUrl &url, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) + const QUrl &url, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit) { QQmlMetaTypeDataPtr data; @@ -1543,7 +1543,7 @@ static bool hasActiveInlineComponents(const QQmlMetaTypeData *data, const QQmlTy static int doCountInternalCompositeTypeSelfReferences( QQmlMetaTypeData *data, - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit) { int result = 0; auto doCheck = [&](const QtPrivate::QMetaTypeInterface *iface) { @@ -1556,7 +1556,7 @@ static int doCountInternalCompositeTypeSelfReferences( }; doCheck(compilationUnit->metaType().iface()); - for (auto &&inlineData: compilationUnit->inlineComponentData()) + for (auto &&inlineData: compilationUnit->inlineComponentData) doCheck(inlineData.qmlType.typeId().iface()); return result; @@ -1575,8 +1575,7 @@ void QQmlMetaType::freeUnusedTypesAndCaches() droppedAtLeastOneComposite = false; auto it = data->compositeTypes.begin(); while (it != data->compositeTypes.end()) { - if (!(*it)->engine - || (*it)->count() <= doCountInternalCompositeTypeSelfReferences(data, *it)) { + if ((*it)->count() <= doCountInternalCompositeTypeSelfReferences(data, *it)) { it = data->compositeTypes.erase(it); droppedAtLeastOneComposite = true; } else { @@ -1931,7 +1930,7 @@ QQmlPropertyCache::ConstPtr QQmlMetaType::findPropertyCacheInCompositeTypes(QMet } void QQmlMetaType::registerInternalCompositeType( - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit) { QQmlMetaTypeDataPtr data; @@ -1946,12 +1945,12 @@ void QQmlMetaType::registerInternalCompositeType( }; doInsert(compilationUnit->metaType().iface()); - for (auto &&inlineData: compilationUnit->inlineComponentData()) + for (auto &&inlineData: compilationUnit->inlineComponentData) doInsert(inlineData.qmlType.typeId().iface()); } void QQmlMetaType::unregisterInternalCompositeType( - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit) { QQmlMetaTypeDataPtr data; @@ -1965,22 +1964,41 @@ void QQmlMetaType::unregisterInternalCompositeType( }; doRemove(compilationUnit->metaType().iface()); - for (auto &&inlineData: compilationUnit->inlineComponentData()) + for (auto &&inlineData: compilationUnit->inlineComponentData) doRemove(inlineData.qmlType.typeId().iface()); } int QQmlMetaType::countInternalCompositeTypeSelfReferences( - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit) { QQmlMetaTypeDataPtr data; return doCountInternalCompositeTypeSelfReferences(data, compilationUnit); } -QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlMetaType::obtainExecutableCompilationUnit( +QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlMetaType::obtainCompilationUnit( QMetaType type) { const QQmlMetaTypeDataPtr data; return data->compositeTypes.value(type.iface()); } +QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlMetaType::obtainCompilationUnit( + const QUrl &url) +{ + const QUrl normalized = QQmlTypeLoader::normalize(url); + QQmlMetaTypeDataPtr data; + + auto found = data->urlToType.constFind(normalized); + if (found == data->urlToType.constEnd()) { + found = data->urlToNonFileImportType.constFind(normalized); + if (found == data->urlToNonFileImportType.constEnd()) + return QQmlRefPointer<QV4::CompiledData::CompilationUnit>(); + } + + const auto composite = data->compositeTypes.constFind(found.value()->typeId.iface()); + return composite == data->compositeTypes.constEnd() + ? QQmlRefPointer<QV4::CompiledData::CompilationUnit>() + : composite.value(); +} + QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 2eabcc2d92..bb592dfa07 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -28,7 +28,11 @@ class QRecursiveMutex; class QQmlError; class QQmlValueType; -namespace QV4 { class ExecutableCompilationUnit; } +namespace QV4 { +namespace CompiledData { +struct CompilationUnit; +} +} class Q_QML_EXPORT QQmlMetaType { @@ -67,13 +71,15 @@ public: }; static QQmlType findCompositeType( - const QUrl &url, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, - CompositeTypeLookupMode mode = NonSingleton); + const QUrl &url, + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, + CompositeTypeLookupMode mode = NonSingleton); static QQmlType findInlineComponentType( - const QUrl &url, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit); + const QUrl &url, + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit); static QQmlType findInlineComponentType( const QUrl &baseUrl, const QString &name, - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit) { return findInlineComponentType(inlineComponentUrl(baseUrl, name), compilationUnit); } @@ -270,13 +276,15 @@ public: static QQmlPropertyCache::ConstPtr findPropertyCacheInCompositeTypes(QMetaType t); static void registerInternalCompositeType( - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit); + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit); static void unregisterInternalCompositeType( - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit); + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit); static int countInternalCompositeTypeSelfReferences( - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit); - static QQmlRefPointer<QV4::ExecutableCompilationUnit> obtainExecutableCompilationUnit( - QMetaType type); + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit); + static QQmlRefPointer<QV4::CompiledData::CompilationUnit> obtainCompilationUnit( + QMetaType type); + static QQmlRefPointer<QV4::CompiledData::CompilationUnit> obtainCompilationUnit( + const QUrl &url); }; Q_DECLARE_TYPEINFO(QQmlMetaType, Q_RELOCATABLE_TYPE); diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp index 198f18d1b2..bc7e762e53 100644 --- a/src/qml/qml/qqmlmetatypedata.cpp +++ b/src/qml/qml/qqmlmetatypedata.cpp @@ -244,9 +244,9 @@ static QQmlPropertyCache::ConstPtr propertyCacheForPotentialInlineComponentType( QMetaType t, const QQmlMetaTypeData::CompositeTypes::const_iterator &iter) { if (t != (*iter)->metaType()) { // this is an inline component, and what we have in the iterator is currently the parent compilation unit - for (auto &&icDatum: (*iter)->inlineComponentData()) + for (auto &&icDatum: (*iter)->inlineComponentData) if (icDatum.qmlType.typeId() == t) - return (*iter)->propertyCachesPtr()->at(icDatum.objectIndex); + return (*iter)->propertyCaches.at(icDatum.objectIndex); } return (*iter)->rootPropertyCache(); } diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h index 4af8818e91..8863bd1089 100644 --- a/src/qml/qml/qqmlmetatypedata_p.h +++ b/src/qml/qml/qqmlmetatypedata_p.h @@ -51,7 +51,7 @@ struct QQmlMetaTypeData QHash<int, QQmlValueType *> metaTypeToValueType; using CompositeTypes = QHash<const QtPrivate::QMetaTypeInterface *, - QQmlRefPointer<QV4::ExecutableCompilationUnit>>; + QQmlRefPointer<QV4::CompiledData::CompilationUnit>>; CompositeTypes compositeTypes; QHash<QUrl, QQmlType> inlineComponentTypes; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 31600e234f..ec7d0b42ce 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1276,7 +1276,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo sharedState->allCreatedObjects.push(instance); } else { - const auto compilationUnit = typeRef->compilationUnit(); + auto compilationUnit = typeRef->compilationUnit(); Q_ASSERT(compilationUnit); typeName = compilationUnit->fileName(); // compilation unit is shared between root type and its inline component types @@ -1287,8 +1287,10 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo } if (!type.isInlineComponentType()) { - QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data(), - isContextObject); + QQmlObjectCreator subCreator( + context, engine->handle()->executableCompilationUnit( + std::move(compilationUnit)), + sharedState.data(), isContextObject); instance = subCreator.create(); if (!instance) { errors += subCreator.errors; @@ -1296,25 +1298,31 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo } } else { QString subObjectName; - if (QString *icRootName = compilationUnit->icRootName()) { + if (QString *icRootName = compilationUnit->icRootName.get()) { subObjectName = type.elementName(); std::swap(*icRootName, subObjectName); } else { - compilationUnit->setIcRootName(std::make_unique<QString>(type.elementName())); + compilationUnit->icRootName = std::make_unique<QString>(type.elementName()); } const auto guard = qScopeGuard([&] { if (subObjectName.isEmpty()) - compilationUnit->setIcRootName({}); + compilationUnit->icRootName.reset(); else - std::swap(*compilationUnit->icRootName(), subObjectName); + std::swap(*compilationUnit->icRootName, subObjectName); }); - QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data(), - isContextObject); + const int inlineComponentId + = compilationUnit->inlineComponentId(*compilationUnit->icRootName); + QQmlObjectCreator subCreator( + context, + engine->handle()->executableCompilationUnit( + QQmlRefPointer<QV4::CompiledData::CompilationUnit>( + compilationUnit)), + sharedState.data(), + isContextObject); instance = subCreator.create( - compilationUnit->inlineComponentId(*compilationUnit->icRootName()), - nullptr, nullptr, CreationFlags::InlineComponent); + inlineComponentId, nullptr, nullptr, CreationFlags::InlineComponent); if (!instance) { errors += subCreator.errors; return nullptr; diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index 8b0e340736..82fd072698 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -28,15 +28,14 @@ QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(HANDLE_PRIMITIVE); } } -QQmlPropertyValidator::QQmlPropertyValidator( - QQmlEnginePrivate *enginePrivate, const QQmlImports *imports, - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) +QQmlPropertyValidator::QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, const QQmlImports *imports, + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit) : enginePrivate(enginePrivate) , compilationUnit(compilationUnit) , imports(imports) , qmlUnit(compilationUnit->unitData()) - , propertyCaches(*compilationUnit->propertyCachesPtr()) - , bindingPropertyDataPerObject(&compilationUnit->baseCompilationUnit()->bindingPropertyDataPerObject) + , propertyCaches(compilationUnit->propertyCaches) + , bindingPropertyDataPerObject(&compilationUnit->bindingPropertyDataPerObject) { bindingPropertyDataPerObject->resize(compilationUnit->objectCount()); } @@ -343,7 +342,10 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( customParser->validator = this; customParser->engine = enginePrivate; customParser->imports = imports; - customParser->verifyBindings(compilationUnit, customBindings); + customParser->verifyBindings( + enginePrivate->v4engine()->executableCompilationUnit( + QQmlRefPointer<QV4::CompiledData::CompilationUnit>(compilationUnit)), + customBindings); customParser->validator = nullptr; customParser->engine = nullptr; customParser->imports = (QQmlImports*)nullptr; @@ -637,9 +639,9 @@ bool QQmlPropertyValidator::canCoerce(QMetaType to, QQmlPropertyCache::ConstPtr // it is not properly registered at this point, as registration // only occurs after the whole file has been validated // Therefore we need to check the ICs here - for (const auto& icDatum : compilationUnit->inlineComponentData()) { + for (const auto& icDatum : compilationUnit->inlineComponentData) { if (icDatum.qmlType.typeId() == to) { - toMo = compilationUnit->propertyCachesPtr()->at(icDatum.objectIndex); + toMo = compilationUnit->propertyCaches.at(icDatum.objectIndex); break; } } @@ -747,10 +749,10 @@ QQmlError QQmlPropertyValidator::validateObjectBinding(const QQmlPropertyData *p // it is not properly registered at this point, as registration // only occurs after the whole file has been validated // Therefore we need to check the ICs here - for (const auto& icDatum: compilationUnit->inlineComponentData()) { + for (const auto& icDatum: compilationUnit->inlineComponentData) { if (icDatum.qmlType.typeId() == property->propType()) { propertyMetaObject - = compilationUnit->propertyCachesPtr()->at(icDatum.objectIndex); + = compilationUnit->propertyCaches.at(icDatum.objectIndex); break; } } diff --git a/src/qml/qml/qqmlpropertyvalidator_p.h b/src/qml/qml/qqmlpropertyvalidator_p.h index d7fea687f9..75787fcf68 100644 --- a/src/qml/qml/qqmlpropertyvalidator_p.h +++ b/src/qml/qml/qqmlpropertyvalidator_p.h @@ -28,7 +28,9 @@ class QQmlPropertyValidator { Q_DECLARE_TR_FUNCTIONS(QQmlPropertyValidator) public: - QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, const QQmlImports *imports, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit); + QQmlPropertyValidator( + QQmlEnginePrivate *enginePrivate, const QQmlImports *imports, + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit); QVector<QQmlError> validate(); @@ -58,7 +60,7 @@ private: } QQmlEnginePrivate *enginePrivate; - QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit; + QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit; const QQmlImports *imports; const QV4::CompiledData::Unit *qmlUnit; const QQmlPropertyCacheVector &propertyCaches; diff --git a/src/qml/qml/qqmlscriptblob.cpp b/src/qml/qml/qqmlscriptblob.cpp index 9b6badeb70..fa9a41e801 100644 --- a/src/qml/qml/qqmlscriptblob.cpp +++ b/src/qml/qml/qqmlscriptblob.cpp @@ -168,14 +168,6 @@ void QQmlScriptBlob::done() m_scripts.clear(); } -void QQmlScriptBlob::completed() -{ - if (m_scriptData && m_scriptData->m_precompiledScript) { - QQmlEnginePrivate::getV4Engine(typeLoader()->engine()) - ->injectCompiledModule(m_scriptData->m_precompiledScript); - } -} - QString QQmlScriptBlob::stringAt(int index) const { return m_scriptData->m_precompiledScript->stringAt(index); @@ -201,19 +193,14 @@ void QQmlScriptBlob::initializeFromCompilationUnit( m_scriptData.adopt(new QQmlScriptData()); m_scriptData->url = finalUrl(); m_scriptData->urlString = finalUrlString(); - m_scriptData->m_precompiledScript - = QQmlEnginePrivate::getV4Engine(typeLoader()->engine())->executableCompilationUnit( - std::move(unit)); + m_scriptData->m_precompiledScript = unit; m_importCache->setBaseUrl(finalUrl(), finalUrlString()); - QQmlRefPointer<QV4::CompiledData::CompilationUnit> script - = m_scriptData->m_precompiledScript->baseCompilationUnit(); - if (!m_isModule) { QList<QQmlError> errors; - for (quint32 i = 0, count = script->importCount(); i < count; ++i) { - const QV4::CompiledData::Import *import = script->importAt(i); + for (quint32 i = 0, count = unit->importCount(); i < count; ++i) { + const QV4::CompiledData::Import *import = unit->importAt(i); if (!addImport(import, {}, &errors)) { Q_ASSERT(errors.size()); QQmlError error(errors.takeFirst()); @@ -227,13 +214,13 @@ void QQmlScriptBlob::initializeFromCompilationUnit( } } - const QStringList moduleRequests = script->moduleRequests(); + const QStringList moduleRequests = unit->moduleRequests(); for (const QString &request: moduleRequests) { const QUrl relativeRequest = QUrl(request); if (m_typeLoader->injectedScript(relativeRequest)) continue; - const QUrl absoluteRequest = script->finalUrl().resolved(relativeRequest); + const QUrl absoluteRequest = unit->finalUrl().resolved(relativeRequest); QQmlRefPointer<QQmlScriptBlob> absoluteBlob = typeLoader()->getScript(absoluteRequest); if (absoluteBlob->m_scriptData && absoluteBlob->m_scriptData->m_precompiledScript) continue; diff --git a/src/qml/qml/qqmlscriptblob_p.h b/src/qml/qml/qqmlscriptblob_p.h index 356fe23675..59f969859b 100644 --- a/src/qml/qml/qqmlscriptblob_p.h +++ b/src/qml/qml/qqmlscriptblob_p.h @@ -45,7 +45,6 @@ protected: void dataReceived(const SourceCodeData &) override; void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override; void done() override; - void completed() override; QString stringAt(int index) const override; diff --git a/src/qml/qml/qqmlscriptdata.cpp b/src/qml/qml/qqmlscriptdata.cpp index 8b833eb877..9337f25c6e 100644 --- a/src/qml/qml/qqmlscriptdata.cpp +++ b/src/qml/qml/qqmlscriptdata.cpp @@ -81,7 +81,11 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext( /* scopeObject: */ nullptr); } - QV4::Scoped<QV4::Module> module(scope, m_precompiledScript->instantiate()); + QV4::Scoped<QV4::Module> module( + scope, + v4->executableCompilationUnit(QQmlRefPointer<QV4::CompiledData::CompilationUnit>( + m_precompiledScript))->instantiate()); + if (module) { if (qmlExecutionContext) { module->d()->scope->outer.set(v4, qmlExecutionContext->d()); diff --git a/src/qml/qml/qqmlscriptdata_p.h b/src/qml/qml/qqmlscriptdata_p.h index e633c13757..ad5ffb3d07 100644 --- a/src/qml/qml/qqmlscriptdata_p.h +++ b/src/qml/qml/qqmlscriptdata_p.h @@ -19,7 +19,7 @@ #include <private/qqmlscriptblob_p.h> #include <private/qv4value_p.h> #include <private/qv4persistent_p.h> -#include <private/qv4executablecompilationunit_p.h> +#include <private/qv4compileddata_p.h> #include <QtCore/qurl.h> @@ -43,7 +43,10 @@ public: QV4::ReturnedValue scriptValueForContext(const QQmlRefPointer<QQmlContextData> &parentCtxt); - QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit() const { return m_precompiledScript; } + QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit() const + { + return m_precompiledScript; + } private: friend class QQmlScriptBlob; @@ -52,7 +55,7 @@ private: const QQmlRefPointer<QQmlContextData> &parentQmlContextData); bool m_loaded = false; - QQmlRefPointer<QV4::ExecutableCompilationUnit> m_precompiledScript; + QQmlRefPointer<QV4::CompiledData::CompilationUnit> m_precompiledScript; QV4::PersistentValue m_value; }; diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index de41e733de..b3df3a862b 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -146,7 +146,7 @@ QQmlType QQmlTypePrivate::resolveCompositeBaseType(QQmlEnginePrivate *engine) co QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl())); if (td.isNull() || !td->isComplete()) return QQmlType(); - QV4::ExecutableCompilationUnit *compilationUnit = td->compilationUnit(); + QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit(); const QMetaObject *mo = compilationUnit->rootPropertyCache()->firstCppMetaObject(); return QQmlMetaType::qmlType(mo); } @@ -161,7 +161,7 @@ QQmlPropertyCache::ConstPtr QQmlTypePrivate::compositePropertyCache( QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl())); if (td.isNull() || !td->isComplete()) return nullptr; - QV4::ExecutableCompilationUnit *compilationUnit = td->compilationUnit(); + QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit(); return compilationUnit->rootPropertyCache(); } diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index f74d3752d5..b17a48568c 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -56,7 +56,7 @@ const QList<QQmlTypeData::ScriptReference> &QQmlTypeData::resolvedScripts() cons return m_scripts; } -QV4::ExecutableCompilationUnit *QQmlTypeData::compilationUnit() const +QV4::CompiledData::CompilationUnit *QQmlTypeData::compilationUnit() const { return m_compiledData.data(); } @@ -86,10 +86,6 @@ bool QQmlTypeData::tryLoadFromDiskCache() if (!readCacheFile()) return false; - QV4::ExecutionEngine *v4 = typeLoader()->engine()->handle(); - if (!v4) - return false; - auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(); { QString error; @@ -104,7 +100,7 @@ bool QQmlTypeData::tryLoadFromDiskCache() return true; } - m_compiledData = v4->executableCompilationUnit(std::move(unit)); + m_compiledData = std::move(unit); QVector<QV4::CompiledData::InlineComponent> ics; for (int i = 0, count = m_compiledData->objectCount(); i < count; ++i) { @@ -175,20 +171,20 @@ bool QQmlTypeData::tryLoadFromDiskCache() } template<> -void QQmlComponentAndAliasResolver<QV4::ExecutableCompilationUnit>::allocateNamedObjects( +void QQmlComponentAndAliasResolver<QV4::CompiledData::CompilationUnit>::allocateNamedObjects( const QV4::CompiledData::Object *object) const { Q_UNUSED(object); } template<> -bool QQmlComponentAndAliasResolver<QV4::ExecutableCompilationUnit>::markAsComponent(int index) const +bool QQmlComponentAndAliasResolver<QV4::CompiledData::CompilationUnit>::markAsComponent(int index) const { return m_compiler->objectAt(index)->hasFlag(QV4::CompiledData::Object::IsComponent); } template<> -void QQmlComponentAndAliasResolver<QV4::ExecutableCompilationUnit>::setObjectId(int index) const +void QQmlComponentAndAliasResolver<QV4::CompiledData::CompilationUnit>::setObjectId(int index) const { Q_UNUSED(index) // we cannot sanity-check the index here because bindings are sorted in a different order @@ -196,8 +192,8 @@ void QQmlComponentAndAliasResolver<QV4::ExecutableCompilationUnit>::setObjectId( } template<> -typename QQmlComponentAndAliasResolver<QV4::ExecutableCompilationUnit>::AliasResolutionResult -QQmlComponentAndAliasResolver<QV4::ExecutableCompilationUnit>::resolveAliasesInObject( +typename QQmlComponentAndAliasResolver<QV4::CompiledData::CompilationUnit>::AliasResolutionResult +QQmlComponentAndAliasResolver<QV4::CompiledData::CompilationUnit>::resolveAliasesInObject( const CompiledObject &component, int objectIndex, QQmlError *error) { const CompiledObject *obj = m_compiler->objectAt(objectIndex); @@ -226,7 +222,7 @@ QQmlComponentAndAliasResolver<QV4::ExecutableCompilationUnit>::resolveAliasesInO } template<> -bool QQmlComponentAndAliasResolver<QV4::ExecutableCompilationUnit>::wrapImplicitComponent( +bool QQmlComponentAndAliasResolver<QV4::CompiledData::CompilationUnit>::wrapImplicitComponent( const QV4::CompiledData::Binding *binding) { // This should have been done when creating the CU. @@ -239,17 +235,17 @@ QQmlError QQmlTypeData::createTypeAndPropertyCaches( const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache) { Q_ASSERT(m_compiledData); - m_compiledData->setTypeNameCache(typeNameCache); - m_compiledData->setResolvedTypes(resolvedTypeCache); - m_compiledData->setInlineComponentData(m_inlineComponentData); + m_compiledData->typeNameCache = typeNameCache; + m_compiledData->resolvedTypes = resolvedTypeCache; + m_compiledData->inlineComponentData = m_inlineComponentData; QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine()); QQmlPendingGroupPropertyBindings pendingGroupPropertyBindings; { - QQmlPropertyCacheCreator<QV4::ExecutableCompilationUnit> propertyCacheCreator( - m_compiledData->propertyCachesPtr(), &pendingGroupPropertyBindings, engine, + QQmlPropertyCacheCreator<QV4::CompiledData::CompilationUnit> propertyCacheCreator( + &m_compiledData->propertyCaches, &pendingGroupPropertyBindings, engine, m_compiledData.data(), m_importCache.data(), typeClassName()); QQmlError error = propertyCacheCreator.verifyNoICCycle(); @@ -263,21 +259,20 @@ QQmlError QQmlTypeData::createTypeAndPropertyCaches( return result.error; } else { QQmlComponentAndAliasResolver resolver( - m_compiledData.data(), engine, m_compiledData->propertyCachesPtr()); + m_compiledData.data(), engine, &m_compiledData->propertyCaches); if (const QQmlError error = resolver.resolve(result.processedRoot); error.isValid()) { return error; } pendingGroupPropertyBindings.resolveMissingPropertyCaches( - m_compiledData->propertyCachesPtr()); + &m_compiledData->propertyCaches); pendingGroupPropertyBindings.clear(); // anything that can be processed is now processed } } while (result.canResume); } - pendingGroupPropertyBindings.resolveMissingPropertyCaches( - m_compiledData->propertyCachesPtr()); + pendingGroupPropertyBindings.resolveMissingPropertyCaches(&m_compiledData->propertyCaches); return QQmlError(); } @@ -307,7 +302,8 @@ using InlineComponentData = QV4::CompiledData::InlineComponentData; template<typename ObjectContainer> void setupICs( const ObjectContainer &container, QHash<QString, InlineComponentData> *icData, - const QUrl &baseUrl, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit) { + const QUrl &baseUrl, + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit) { Q_ASSERT(icData->empty()); for (int i = 0; i != container->objectCount(); ++i) { auto root = container->objectAt(i); @@ -397,7 +393,7 @@ void QQmlTypeData::done() if (type.type.isInlineComponentType()) { const QUrl url = type.type.sourceUrl(); if (!QQmlMetaType::equalBaseUrls(url, finalUrl()) - && !QQmlMetaType::obtainExecutableCompilationUnit(type.type.typeId())) { + && !QQmlMetaType::obtainCompilationUnit(type.type.typeId())) { const QString &typeName = stringAt(it.key()); int lastDot = typeName.lastIndexOf(u'.'); createError( @@ -484,7 +480,7 @@ void QQmlTypeData::done() return; // We want to keep our resolve types ... - m_compiledData->setResolvedTypes({}); + m_compiledData->resolvedTypes.clear(); // ... but we don't want the property caches we've created for the broken CU. for (QV4::ResolvedTypeReference *ref: std::as_const(resolvedTypeCache)) { const auto compilationUnit = ref->compilationUnit(); @@ -498,7 +494,7 @@ void QQmlTypeData::done() continue; } ref->setTypePropertyCache(QQmlPropertyCache::ConstPtr()); - ref->setCompilationUnit(QQmlRefPointer<QV4::ExecutableCompilationUnit>()); + ref->setCompilationUnit(QQmlRefPointer<QV4::CompiledData::CompilationUnit>()); } m_compiledData.reset(); @@ -516,7 +512,7 @@ void QQmlTypeData::done() { QQmlEnginePrivate *const enginePrivate = QQmlEnginePrivate::get(typeLoader()->engine()); - m_compiledData->setInlineComponentData(m_inlineComponentData); + m_compiledData->inlineComponentData = m_inlineComponentData; { // Sanity check property bindings QQmlPropertyValidator validator(enginePrivate, m_importCache.data(), m_compiledData); @@ -557,7 +553,7 @@ void QQmlTypeData::done() { // Collect imported scripts - m_compiledData->dependentScriptsPtr()->reserve(m_scripts.size()); + m_compiledData->dependentScripts.reserve(m_scripts.size()); for (int scriptIndex = 0; scriptIndex < m_scripts.size(); ++scriptIndex) { const QQmlTypeData::ScriptReference &script = m_scripts.at(scriptIndex); @@ -570,10 +566,10 @@ void QQmlTypeData::done() qualifier = qualifier.mid(lastDotIndex+1); } - m_compiledData->typeNameCache()->add( + m_compiledData->typeNameCache->add( qualifier.toString(), scriptIndex, enclosingNamespace); QQmlRefPointer<QQmlScriptData> scriptData = script.script->scriptData(); - *m_compiledData->dependentScriptsPtr() << scriptData; + m_compiledData->dependentScripts << scriptData; } } } @@ -847,12 +843,11 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach } } - m_compiledData = enginePrivate->v4engine()->executableCompilationUnit( - std::move(compilationUnit)); - m_compiledData->setTypeNameCache(typeNameCache); - m_compiledData->setResolvedTypes(*resolvedTypeCache); - *m_compiledData->propertyCachesPtr() = std::move(*compiler.propertyCaches()); - Q_ASSERT(m_compiledData->propertyCachesPtr()->count() + m_compiledData = std::move(compilationUnit); + m_compiledData->typeNameCache = typeNameCache; + m_compiledData->resolvedTypes = *resolvedTypeCache; + m_compiledData->propertyCaches = std::move(*compiler.propertyCaches()); + Q_ASSERT(m_compiledData->propertyCaches.count() == static_cast<int>(m_compiledData->objectCount())); } @@ -988,7 +983,7 @@ QQmlError QQmlTypeData::buildTypeResolutionCaches( Q_ASSERT(!icName.isEmpty()); const auto compilationUnit = resolvedType->typeData->compilationUnit(); - ref->setTypePropertyCache(compilationUnit->propertyCachesPtr()->at( + ref->setTypePropertyCache(compilationUnit->propertyCaches.at( compilationUnit->inlineComponentId(icName))); ref->setType(std::move(qmlType)); Q_ASSERT(ref->type().isInlineComponentType()); @@ -1004,8 +999,8 @@ QQmlError QQmlTypeData::buildTypeResolutionCaches( // this is required for inline components in singletons const QMetaType type = qmlType.typeId(); - if (auto exUnit = QQmlMetaType::obtainExecutableCompilationUnit(type)) { - ref->setCompilationUnit(std::move(exUnit)); + if (auto unit = QQmlMetaType::obtainCompilationUnit(type)) { + ref->setCompilationUnit(std::move(unit)); ref->setTypePropertyCache(QQmlMetaType::propertyCacheForType(type)); } } diff --git a/src/qml/qml/qqmltypedata_p.h b/src/qml/qml/qqmltypedata_p.h index 57749d50cf..a0443f80c9 100644 --- a/src/qml/qml/qqmltypedata_p.h +++ b/src/qml/qml/qqmltypedata_p.h @@ -57,7 +57,7 @@ public: const QList<ScriptReference> &resolvedScripts() const; - QV4::ExecutableCompilationUnit *compilationUnit() const; + QV4::CompiledData::CompilationUnit *compilationUnit() const; // Used by QQmlComponent to get notifications struct TypeDataCallback { @@ -129,11 +129,11 @@ private: QQmlType m_qmlType; QByteArray m_typeClassName; // used for meta-object later - using ExecutableCompilationUnitPtr = QQmlRefPointer<QV4::ExecutableCompilationUnit>; + using CompilationUnitPtr = QQmlRefPointer<QV4::CompiledData::CompilationUnit>; QHash<QString, InlineComponentData> m_inlineComponentData; - ExecutableCompilationUnitPtr m_compiledData; + CompilationUnitPtr m_compiledData; QList<TypeDataCallback *> m_callbacks; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 07ec0038fb..8e27faf26b 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -1361,7 +1361,7 @@ void QQmlTypeLoader::trimCache() continue; } - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit = typeData->m_compiledData; if (compilationUnit) { if (compilationUnit->count() diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index cd0c59fc21..e9c4559527 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -18,6 +18,7 @@ #include <private/qqmldatablob_p.h> #include <private/qqmlimport_p.h> #include <private/qqmlmetatype_p.h> +#include <private/qv4compileddata_p.h> #include <QtQml/qtqmlglobal.h> #include <QtQml/qqmlerror.h> diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 6218607027..75f3a19c2f 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -409,7 +409,7 @@ static ReturnedValue instanceOfQObject(const QV4::QQmlTypeWrapper *typeWrapper, QQmlEnginePrivate *qenginepriv = QQmlEnginePrivate::get(engine->qmlEngine()); QQmlRefPointer<QQmlTypeData> td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl()); - if (ExecutableCompilationUnit *cu = td->compilationUnit()) + if (CompiledData::CompilationUnit *cu = td->compilationUnit()) myQmlType = QQmlMetaType::metaObjectForType(cu->metaType()); else return Encode(false); // It seems myQmlType has some errors, so we could not compile it. diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp index c762e34a2e..a10bbb0a15 100644 --- a/src/qmltest/quicktest.cpp +++ b/src/qmltest/quicktest.cpp @@ -299,7 +299,8 @@ public: if (component.isReady()) { QQmlRefPointer<QV4::ExecutableCompilationUnit> rootCompilationUnit = QQmlComponentPrivate::get(&component)->compilationUnit; - TestCaseEnumerationResult result = enumerateTestCases(rootCompilationUnit.data()); + TestCaseEnumerationResult result = enumerateTestCases( + rootCompilationUnit->baseCompilationUnit().data()); m_testCases = result.testCases + result.finalizedPartialTestCases(); m_errors += result.errors; } @@ -340,7 +341,7 @@ private: }; TestCaseEnumerationResult enumerateTestCases( - const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, + const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, const Object *object = nullptr) { QQmlType testCaseType; @@ -354,7 +355,7 @@ private: if (!typeQualifier.isEmpty()) testCaseTypeName = typeQualifier % QLatin1Char('.') % testCaseTypeName; - testCaseType = compilationUnit->typeNameCache()->query( + testCaseType = compilationUnit->typeNameCache->query( testCaseTypeName, QQmlTypeLoader::get(m_engine)).type; if (testCaseType.isValid()) break; diff --git a/tests/auto/qml/ecmascripttests/test262runner.cpp b/tests/auto/qml/ecmascripttests/test262runner.cpp index 1161feda8c..947ec4ed3d 100644 --- a/tests/auto/qml/ecmascripttests/test262runner.cpp +++ b/tests/auto/qml/ecmascripttests/test262runner.cpp @@ -326,7 +326,6 @@ void Test262Runner::executeTest(QV4::ExecutionEngine &vm, const QString &testDat QFileInfo(f).lastModified()); if (vm.hasException) break; - vm.injectCompiledModule(module); } else { vm.throwError(QStringLiteral("Could not load module")); break; diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp index 75a4f80c34..0aec3bd6d8 100644 --- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp +++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp @@ -1020,7 +1020,7 @@ void tst_qmldiskcache::cacheModuleScripts() QVERIFY(unitData); QVERIFY(unitData->flags & QV4::CompiledData::Unit::StaticData); QVERIFY(unitData->flags & QV4::CompiledData::Unit::IsESModule); - QVERIFY(compilationUnit->baseCompilationUnit()->backingFile); + QVERIFY(compilationUnit->backingFile); } const QSet<QString> entries = entrySet(m_qmlCacheDirectory, QStringList("*.mjsc")); diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 513e29b4f1..fadd7088be 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -2619,14 +2619,14 @@ void tst_qqmllanguage::scriptStringWithoutSourceCode() Q_ASSERT(td); QVERIFY(!td->backupSourceCode().isValid()); - QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit = td->compilationUnit(); + QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = td->compilationUnit(); readOnlyQmlUnit.reset(compilationUnit->unitData()); Q_ASSERT(readOnlyQmlUnit); QV4::CompiledData::Unit *qmlUnit = reinterpret_cast<QV4::CompiledData::Unit *>(malloc(readOnlyQmlUnit->unitSize)); memcpy(qmlUnit, readOnlyQmlUnit.data(), readOnlyQmlUnit->unitSize); qmlUnit->flags &= ~QV4::CompiledData::Unit::StaticData; - compilationUnit->baseCompilationUnit()->setUnitData(qmlUnit); + compilationUnit->setUnitData(qmlUnit); const QV4::CompiledData::Object *rootObject = compilationUnit->objectAt(/*root object*/0); QCOMPARE(compilationUnit->stringAt(rootObject->inheritedTypeNameIndex), QString("MyTypeObject")); diff --git a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp index 97e3bcc472..6503920f96 100644 --- a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp +++ b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp @@ -60,7 +60,7 @@ void tst_qqmltranslation::translation() QQmlEnginePrivate *engine = QQmlEnginePrivate::get(context->engine()); QQmlRefPointer<QQmlTypeData> typeData = engine->typeLoader.getType(context->baseUrl()); QVERIFY(!typeData->backupSourceCode().isValid()); - QV4::ExecutableCompilationUnit *compilationUnit = typeData->compilationUnit(); + QV4::CompiledData::CompilationUnit *compilationUnit = typeData->compilationUnit(); QVERIFY(compilationUnit); QSet<QString> compiledTranslations; @@ -73,7 +73,7 @@ void tst_qqmltranslation::translation() << QStringLiteral("emptyContext"); const QV4::CompiledData::Object *rootObject - = compilationUnit->qmlData()->objectAt(/*root object*/0); + = compilationUnit->qmlData->objectAt(/*root object*/0); const QV4::CompiledData::Binding *binding = rootObject->bindingTable(); for (quint32 i = 0; i < rootObject->nBindings; ++i, ++binding) { const QString propertyName = compilationUnit->stringAt(binding->propertyNameIndex); @@ -125,11 +125,11 @@ void tst_qqmltranslation::idTranslation() QQmlEnginePrivate *engine = QQmlEnginePrivate::get(context->engine()); QQmlRefPointer<QQmlTypeData> typeData = engine->typeLoader.getType(context->baseUrl()); QVERIFY(!typeData->backupSourceCode().isValid()); - QV4::ExecutableCompilationUnit *compilationUnit = typeData->compilationUnit(); + QV4::CompiledData::CompilationUnit *compilationUnit = typeData->compilationUnit(); QVERIFY(compilationUnit); const QV4::CompiledData::Object *rootObject - = compilationUnit->qmlData()->objectAt(/*root object*/0); + = compilationUnit->qmlData->objectAt(/*root object*/0); const QV4::CompiledData::Binding *binding = rootObject->bindingTable(); for (quint32 i = 0; i < rootObject->nBindings; ++i, ++binding) { const QString propertyName = compilationUnit->stringAt(binding->propertyNameIndex); diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp index 4aeb681a15..11d116904f 100644 --- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp +++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp @@ -92,7 +92,7 @@ void tst_QQMLTypeLoader::trimCache() QQmlEngine engine; QQmlTypeLoader &loader = QQmlEnginePrivate::get(&engine)->typeLoader; QVector<QQmlTypeData *> releaseLater; - QVector<QV4::ExecutableCompilationUnit *> releaseCompilationUnitLater; + QVector<QV4::CompiledData::CompilationUnit *> releaseCompilationUnitLater; for (int i = 0; i < 256; ++i) { QUrl url = testFileUrl("trim_cache.qml"); url.setQuery(QString::number(i)); @@ -685,7 +685,7 @@ static void getCompilationUnitAndRuntimeInfo(QQmlRefPointer<QV4::ExecutableCompi QVERIFY(!typeData->isError()); // this returns } - unit = typeData->compilationUnit(); + unit = engine->handle()->executableCompilationUnit(typeData->compilationUnit()); QVERIFY(unit); // the QmlIR::Document is deleted once loader.getType() is complete, so |