diff options
author | Ulf Hermann <[email protected]> | 2023-12-21 16:53:36 +0100 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2024-01-10 11:22:37 +0100 |
commit | be6d1499af75228341227d15441284e07cfe1e41 (patch) | |
tree | 99c5b1e3dc7f1b99d8c141f1b8138feacd29e020 | |
parent | cfdc612c3022b3f35545fd5e4e0bcd2661f657f1 (diff) |
QtQml: Always link executable CU on creation
We don't want floating unlinked executable CUs. They should always be
tied to an engine, and the engine should not change. This gives us one
definite point where to register them with the engine (to be done in
subsequent change).
Unfortunately, due to the refcounting, we need to remove the engine from
any still-referenced CUs when the engine itself is destructed. We will
be able to drop the refcounting and make the engine fully own its
executable CUs once we can hold base CUs in most places.
Change-Id: I9a53e83d5c4746c2b2bca896b51baa4fe7fee757
Reviewed-by: Fabian Kosmale <[email protected]>
-rw-r--r-- | src/qml/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/qml/common/qv4compileddata.cpp | 114 | ||||
-rw-r--r-- | src/qml/common/qv4compileddata_p.h | 8 | ||||
-rw-r--r-- | src/qml/jsapi/qjsengine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 20 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit.cpp | 151 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit_p.h | 44 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4generatorobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4script.cpp | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlscriptblob.cpp | 25 | ||||
-rw-r--r-- | src/qml/qml/qqmlscriptdata.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmltypecompiler.cpp | 19 | ||||
-rw-r--r-- | src/qml/qml/qqmltypecompiler_p.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmltypedata.cpp | 28 | ||||
-rw-r--r-- | src/qmlworkerscript/qquickworkerscript.cpp | 2 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/test262runner.cpp | 2 | ||||
-rw-r--r-- | tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp | 32 | ||||
-rw-r--r-- | tools/qmljs/qmljs.cpp | 12 |
21 files changed, 266 insertions, 231 deletions
diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt index 9e8da459eb..c6136f27f1 100644 --- a/src/qml/CMakeLists.txt +++ b/src/qml/CMakeLists.txt @@ -169,7 +169,7 @@ qt_internal_add_qml_module(Qml common/qqmljssourcelocation_p.h common/qv4alloca_p.h common/qv4calldata_p.h - common/qv4compileddata_p.h + common/qv4compileddata.cpp common/qv4compileddata_p.h common/qv4staticvalue_p.h common/qv4stringtoarrayindex_p.h common/qqmltranslation.cpp common/qqmltranslation_p.h diff --git a/src/qml/common/qv4compileddata.cpp b/src/qml/common/qv4compileddata.cpp new file mode 100644 index 0000000000..4ed53e6907 --- /dev/null +++ b/src/qml/common/qv4compileddata.cpp @@ -0,0 +1,114 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qv4compileddata_p.h" + +#include <QtQml/qqmlfile.h> + +#include <QtCore/qcryptographichash.h> +#include <QtCore/qdir.h> +#include <QtCore/qscopeguard.h> +#include <QtCore/qstandardpaths.h> + +QT_BEGIN_NAMESPACE + +namespace QV4 { +namespace CompiledData { + +QString CompilationUnit::localCacheFilePath(const QUrl &url) +{ + static const QByteArray envCachePath = qgetenv("QML_DISK_CACHE_PATH"); + + const QString localSourcePath = QQmlFile::urlToLocalFileOrQrc(url); + const QString cacheFileSuffix + = QFileInfo(localSourcePath + QLatin1Char('c')).completeSuffix(); + QCryptographicHash fileNameHash(QCryptographicHash::Sha1); + fileNameHash.addData(localSourcePath.toUtf8()); + QString directory = envCachePath.isEmpty() + ? QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + + QLatin1String("/qmlcache/") + : QString::fromLocal8Bit(envCachePath) + QLatin1String("/"); + QDir::root().mkpath(directory); + return directory + QString::fromUtf8(fileNameHash.result().toHex()) + + QLatin1Char('.') + cacheFileSuffix; +} + +bool CompilationUnit::loadFromDisk( + const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString) +{ + if (!QQmlFile::isLocalFile(url)) { + *errorString = QStringLiteral("File has to be a local file."); + return false; + } + + const QString sourcePath = QQmlFile::urlToLocalFileOrQrc(url); + auto cacheFile = std::make_unique<CompilationUnitMapper>(); + + const QStringList cachePaths = { sourcePath + QLatin1Char('c'), localCacheFilePath(url) }; + for (const QString &cachePath : cachePaths) { + Unit *mappedUnit = cacheFile->get(cachePath, sourceTimeStamp, errorString); + if (!mappedUnit) + continue; + + const Unit *oldData = unitData(); + const Unit * const oldDataPtr + = (oldData && !(oldData->flags & Unit::StaticData)) + ? oldData + : nullptr; + + auto dataPtrRevert = qScopeGuard([this, oldData](){ + setUnitData(oldData); + }); + setUnitData(mappedUnit); + + if (mappedUnit->sourceFileIndex != 0) { + if (mappedUnit->sourceFileIndex >= + mappedUnit->stringTableSize + dynamicStrings.size()) { + *errorString = QStringLiteral("QML source file index is invalid."); + continue; + } + if (sourcePath != + QQmlFile::urlToLocalFileOrQrc(stringAt(mappedUnit->sourceFileIndex))) { + *errorString = QStringLiteral("QML source file has moved to a different location."); + continue; + } + } + + dataPtrRevert.dismiss(); + free(const_cast<Unit*>(oldDataPtr)); + backingFile = std::move(cacheFile); + return true; + } + + return false; +} + +bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString) +{ + if (unitData()->sourceTimeStamp == 0) { + *errorString = QStringLiteral("Missing time stamp for source file"); + return false; + } + + if (!QQmlFile::isLocalFile(unitUrl)) { + *errorString = QStringLiteral("File has to be a local file."); + return false; + } + + return SaveableUnitPointer(unitData()).saveToDisk<char>( + [&unitUrl, errorString](const char *data, quint32 size) { + const QString cachePath = localCacheFilePath(unitUrl); + if (SaveableUnitPointer::writeDataToFile( + cachePath, data, size, errorString)) { + CompilationUnitMapper::invalidate(cachePath); + return true; + } + + return false; + }); +} + +} // namespace CompiledData +} // namespace QV4 + +QT_END_NAMESPACE diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index 82424c1c9d..f7654661e2 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -32,6 +32,7 @@ #include <private/qendian_p.h> #include <private/qqmlrefcount_p.h> #include <private/qv4staticvalue_p.h> +#include <private/qv4compilationunitmapper_p.h> #include <functional> #include <limits.h> @@ -1434,6 +1435,8 @@ struct CompilationUnit final : public QQmlRefCounted<CompilationUnit> // pointers either to data->constants() or little-endian memory copy. const StaticValue *constants = nullptr; + + std::unique_ptr<CompilationUnitMapper> backingFile; public: using CompiledObject = CompiledData::Object; @@ -1550,6 +1553,11 @@ public: return constants[binding->value.constantValueIndex].doubleValue(); } + Q_QML_EXPORT static QString localCacheFilePath(const QUrl &url); + Q_QML_EXPORT bool loadFromDisk( + const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString); + Q_QML_EXPORT bool saveToDisk(const QUrl &unitUrl, QString *errorString); + private: QString m_fileName; // initialized from data->sourceFileIndex QString m_finalUrlString; // initialized from data->finalUrlIndex diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index 8f1496a8d4..8c40d95961 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -576,7 +576,7 @@ QJSValue QJSEngine::importModule(const QString &fileName) QV4::Scope scope(m_v4Engine); if (const auto compiled = module.compiled) { - QV4::Scoped<QV4::Module> moduleNamespace(scope, compiled->instantiate(m_v4Engine)); + QV4::Scoped<QV4::Module> moduleNamespace(scope, compiled->instantiate()); if (m_v4Engine->hasException) return QJSValuePrivate::fromReturnedValue(m_v4Engine->catchException()); compiled->evaluate(); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 344f57b638..378306a7c9 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -860,8 +860,13 @@ ExecutionEngine::~ExecutionEngine() delete memoryManager; // Take a temporary reference to the CU so that it doesn't disappear during unlinking. - while (!compilationUnits.isEmpty()) - QQmlRefPointer<ExecutableCompilationUnit>(*compilationUnits.begin())->unlink(); + while (!compilationUnits.isEmpty()) { + QQmlRefPointer<ExecutableCompilationUnit> cu(*compilationUnits.begin()); + Q_ASSERT(cu->engine == this); + cu->clear(); + cu->engine = nullptr; + cu->nextCompilationUnit.remove(); + } delete bumperPointerAllocator; delete regExpCache; @@ -2075,11 +2080,10 @@ QQmlRefPointer<ExecutableCompilationUnit> ExecutionEngine::compileModule(const Q &cacheError) : nullptr) { return ExecutableCompilationUnit::create( - QQmlRefPointer<QV4::CompiledData::CompilationUnit>( - new QV4::CompiledData::CompilationUnit( - cachedUnit->qmlData, cachedUnit->aotCompiledFunctions, - url.fileName(), url.toString()), - QQmlRefPointer<QV4::CompiledData::CompilationUnit>::Adopt)); + QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>( + cachedUnit->qmlData, cachedUnit->aotCompiledFunctions, url.fileName(), + url.toString()), + this); } QFile f(QQmlFile::urlToLocalFileOrQrc(url)); @@ -2113,7 +2117,7 @@ QQmlRefPointer<ExecutableCompilationUnit> ExecutionEngine::compileModule( } } - return ExecutableCompilationUnit::create(std::move(unit)); + return ExecutableCompilationUnit::create(std::move(unit), this); } void ExecutionEngine::injectCompiledModule(const QQmlRefPointer<ExecutableCompilationUnit> &moduleUnit) diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index a622c14362..ebd0ae3d4a 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -23,15 +23,10 @@ #include <private/qv4resolvedtypereference_p.h> #include <private/qv4objectiterator_p.h> -#include <QtQml/qqmlfile.h> #include <QtQml/qqmlpropertymap.h> -#include <QtCore/qdir.h> -#include <QtCore/qstandardpaths.h> #include <QtCore/qfileinfo.h> -#include <QtCore/qscopeguard.h> #include <QtCore/qcryptographichash.h> -#include <QtCore/QScopedValueRollback> static_assert(QV4::CompiledData::QmlCompileHashSpace > QML_COMPILE_HASH_LENGTH); @@ -63,23 +58,8 @@ ExecutableCompilationUnit::ExecutableCompilationUnit( ExecutableCompilationUnit::~ExecutableCompilationUnit() { - delete [] imports; - unlink(); -} - -QString ExecutableCompilationUnit::localCacheFilePath(const QUrl &url) -{ - static const QByteArray envCachePath = qgetenv("QML_DISK_CACHE_PATH"); - - const QString localSourcePath = QQmlFile::urlToLocalFileOrQrc(url); - const QString cacheFileSuffix = QFileInfo(localSourcePath + QLatin1Char('c')).completeSuffix(); - QCryptographicHash fileNameHash(QCryptographicHash::Sha1); - fileNameHash.addData(localSourcePath.toUtf8()); - QString directory = envCachePath.isEmpty() - ? QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1String("/qmlcache/") - : QString::fromLocal8Bit(envCachePath) + QLatin1String("/"); - QDir::root().mkpath(directory); - return directory + QString::fromUtf8(fileNameHash.result().toHex()) + QLatin1Char('.') + cacheFileSuffix; + clear(); + nextCompilationUnit.remove(); } static QString toString(QV4::ReturnedValue v) @@ -107,14 +87,12 @@ static void dumpConstantTable(const StaticValue *constants, uint count) } } -QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine) +void ExecutableCompilationUnit::populate() { - this->engine = engine; - engine->compilationUnits.insert(this); - const CompiledData::Unit *data = m_compilationUnit->data; Q_ASSERT(!runtimeStrings); + Q_ASSERT(engine); Q_ASSERT(data); const quint32 stringCount = totalStringCount(); // strings need to be 0 in case a GC run happens while we're within the loop below @@ -235,16 +213,13 @@ QV4::Function *ExecutableCompilationUnit::linkToEngine(ExecutionEngine *engine) << (data->indexOfRootFunction != -1 ? data->indexOfRootFunction : 0); } - - if (data->indexOfRootFunction != -1) - return runtimeFunctions[data->indexOfRootFunction]; - else - return nullptr; } Heap::Object *ExecutableCompilationUnit::templateObjectAt(int index) const { const CompiledData::Unit *data = m_compilationUnit->data; + Q_ASSERT(data); + Q_ASSERT(engine); Q_ASSERT(index < int(data->templateObjectTableSize)); if (!templateObjects.size()) @@ -274,10 +249,10 @@ Heap::Object *ExecutableCompilationUnit::templateObjectAt(int index) const return templateObjects.at(index); } -void ExecutableCompilationUnit::unlink() +void ExecutableCompilationUnit::clear() { - if (engine) - nextCompilationUnit.remove(); + delete [] imports; + imports = nullptr; // Clear the QQmlTypes but not the property caches. // The property caches may still be necessary to resolve further types. @@ -298,8 +273,6 @@ void ExecutableCompilationUnit::unlink() qDeleteAll(resolvedTypes); resolvedTypes.clear(); - engine = nullptr; - delete [] runtimeLookups; runtimeLookups = nullptr; @@ -391,6 +364,17 @@ void processInlinComponentType( } } +QQmlRefPointer<ExecutableCompilationUnit> ExecutableCompilationUnit::create( + QQmlRefPointer<CompiledData::CompilationUnit> &&compilationUnit, ExecutionEngine *engine) +{ + auto result = QQmlRefPointer<ExecutableCompilationUnit>( + 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 @@ -561,7 +545,7 @@ QStringList ExecutableCompilationUnit::moduleRequests() const return requests; } -Heap::Module *ExecutableCompilationUnit::instantiate(ExecutionEngine *engine) +Heap::Module *ExecutableCompilationUnit::instantiate() { const CompiledData::Unit *data = m_compilationUnit->data; @@ -571,8 +555,9 @@ Heap::Module *ExecutableCompilationUnit::instantiate(ExecutionEngine *engine) if (data->indexOfRootFunction < 0) return nullptr; - if (!this->engine) - linkToEngine(engine); + Q_ASSERT(engine); + if (!runtimeStrings) + populate(); Scope scope(engine); Scoped<Module> module(scope, engine->memoryManager->allocate<Module>(engine, this)); @@ -586,7 +571,7 @@ Heap::Module *ExecutableCompilationUnit::instantiate(ExecutionEngine *engine) if (engine->hasException) return nullptr; if (dependentModuleUnit.compiled) - dependentModuleUnit.compiled->instantiate(engine); + dependentModuleUnit.compiled->instantiate(); } ScopedString importName(scope); @@ -701,6 +686,10 @@ const Value *ExecutableCompilationUnit::resolveExportRecursively( return &module()->self; const CompiledData::Unit *data = m_compilationUnit->data; + + Q_ASSERT(data); + Q_ASSERT(engine); + Scope scope(engine); if (auto localExport = lookupNameInExportTable( @@ -813,6 +802,9 @@ void ExecutableCompilationUnit::getExportedNamesRecursively( const CompiledData::Unit *data = m_compilationUnit->data; + Q_ASSERT(data); + Q_ASSERT(engine); + for (uint i = 0; i < data->localExportEntryTableSize; ++i) { const CompiledData::ExportEntry &entry = data->localExportEntryTable()[i]; append(stringAt(entry.exportName)); @@ -845,6 +837,8 @@ void ExecutableCompilationUnit::getExportedNamesRecursively( void ExecutableCompilationUnit::evaluate() { + Q_ASSERT(engine); + QV4::Scope scope(engine); QV4::Scoped<Module> mod(scope, module()); mod->evaluate(); @@ -852,6 +846,8 @@ void ExecutableCompilationUnit::evaluate() void ExecutableCompilationUnit::evaluateModuleRequests() { + Q_ASSERT(engine); + for (const QString &request: moduleRequests()) { auto dependentModule = engine->loadModule(QUrl(request), this); if (dependentModule.native) @@ -867,81 +863,6 @@ void ExecutableCompilationUnit::evaluateModuleRequests() } } -bool ExecutableCompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString) -{ - if (!QQmlFile::isLocalFile(url)) { - *errorString = QStringLiteral("File has to be a local file."); - return false; - } - - const QString sourcePath = QQmlFile::urlToLocalFileOrQrc(url); - auto cacheFile = std::make_unique<CompilationUnitMapper>(); - - const QStringList cachePaths = { sourcePath + QLatin1Char('c'), localCacheFilePath(url) }; - for (const QString &cachePath : cachePaths) { - CompiledData::Unit *mappedUnit = cacheFile->get(cachePath, sourceTimeStamp, errorString); - if (!mappedUnit) - continue; - - const CompiledData::Unit *oldData = unitData(); - const CompiledData::Unit * const oldDataPtr - = (oldData && !(oldData->flags & QV4::CompiledData::Unit::StaticData)) - ? oldData - : nullptr; - - auto dataPtrRevert = qScopeGuard([this, oldData](){ - m_compilationUnit->setUnitData(oldData); - }); - m_compilationUnit->setUnitData(mappedUnit); - - if (mappedUnit->sourceFileIndex != 0) { - if (mappedUnit->sourceFileIndex >= - mappedUnit->stringTableSize + m_compilationUnit->dynamicStrings.size()) { - *errorString = QStringLiteral("QML source file index is invalid."); - continue; - } - if (sourcePath != - QQmlFile::urlToLocalFileOrQrc(stringAt(mappedUnit->sourceFileIndex))) { - *errorString = QStringLiteral("QML source file has moved to a different location."); - continue; - } - } - - dataPtrRevert.dismiss(); - free(const_cast<CompiledData::Unit*>(oldDataPtr)); - backingFile = std::move(cacheFile); - CompilationUnitRuntimeData::constants = m_compilationUnit->constants; - return true; - } - - return false; -} - -bool ExecutableCompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString) -{ - if (unitData()->sourceTimeStamp == 0) { - *errorString = QStringLiteral("Missing time stamp for source file"); - return false; - } - - if (!QQmlFile::isLocalFile(unitUrl)) { - *errorString = QStringLiteral("File has to be a local file."); - return false; - } - - return CompiledData::SaveableUnitPointer(unitData()).saveToDisk<char>( - [&unitUrl, errorString](const char *data, quint32 size) { - const QString cachePath = localCacheFilePath(unitUrl); - if (CompiledData::SaveableUnitPointer::writeDataToFile( - cachePath, data, size, errorString)) { - CompilationUnitMapper::invalidate(cachePath); - return true; - } - - return false; - }); -} - /*! \internal This function creates a temporary key vector and sorts it to guarantuee a stable diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h index f52989ec25..69cac2974c 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit_p.h +++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h @@ -100,22 +100,8 @@ public: friend class QQmlRefPointer<ExecutableCompilationUnit>; static QQmlRefPointer<ExecutableCompilationUnit> create( - QQmlRefPointer<CompiledData::CompilationUnit> &&compilationUnit) - { - return QQmlRefPointer<ExecutableCompilationUnit>( - new ExecutableCompilationUnit(std::move(compilationUnit)), - QQmlRefPointer<ExecutableCompilationUnit>::Adopt); - } - - static QQmlRefPointer<ExecutableCompilationUnit> create() - { - return QQmlRefPointer<ExecutableCompilationUnit>( - new ExecutableCompilationUnit( - QQmlRefPointer<CompiledData::CompilationUnit>( - new CompiledData::CompilationUnit, - QQmlRefPointer<CompiledData::CompilationUnit>::Adopt)), - QQmlRefPointer<ExecutableCompilationUnit>::Adopt); - } + QQmlRefPointer<CompiledData::CompilationUnit> &&compilationUnit, + ExecutionEngine *engine); QIntrusiveListNode nextCompilationUnit; ExecutionEngine *engine = nullptr; @@ -200,8 +186,6 @@ public: return -1; } - std::unique_ptr<CompilationUnitMapper> backingFile; - // --- interface for QQmlPropertyCacheCreator using CompiledObject = const CompiledData::Object; using CompiledFunction = const CompiledData::Function; @@ -306,7 +290,7 @@ public: } QStringList moduleRequests() const; - Heap::Module *instantiate(ExecutionEngine *engine); + Heap::Module *instantiate(); const Value *resolveExport(QV4::String *exportName) { QVector<ResolveSetEntry> resolveSet; @@ -327,16 +311,8 @@ public: void evaluate(); void evaluateModuleRequests(); - QV4::Function *linkToEngine(QV4::ExecutionEngine *engine); - void unlink(); - void markObjects(MarkStack *markStack); - bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString); - - static QString localCacheFilePath(const QUrl &url); - bool saveToDisk(const QUrl &unitUrl, QString *errorString); - QString bindingValueAsString(const CompiledData::Binding *binding) const; double bindingValueAsNumber(const CompiledData::Binding *binding) const { @@ -371,6 +347,20 @@ public: return m_compilationUnit; } + QV4::Function *rootFunction() + { + if (!runtimeStrings) + populate(); + + const auto *data = unitData(); + return data->indexOfRootFunction != -1 + ? runtimeFunctions[data->indexOfRootFunction] + : nullptr; + } + + void populate(); + void clear(); + protected: quint32 totalStringCount() const { return unitData()->stringTableSize; } diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 0b11cdfe20..aff4a02115 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -256,7 +256,7 @@ QQmlRefPointer<ExecutableCompilationUnit> FunctionCtor::parse(ExecutionEngine *e if (engine->hasException) return nullptr; - return ExecutableCompilationUnit::create(cg.generateCompilationUnit()); + return ExecutableCompilationUnit::create(cg.generateCompilationUnit(), engine); } ReturnedValue FunctionCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget) @@ -268,7 +268,7 @@ ReturnedValue FunctionCtor::virtualCallAsConstructor(const FunctionObject *f, co if (engine->hasException) return Encode::undefined(); - Function *vmf = compilationUnit->linkToEngine(engine); + Function *vmf = compilationUnit->rootFunction(); ExecutionContext *global = engine->scriptContext(); ReturnedValue o = Encode(FunctionObject::createScriptFunction(global, vmf)); diff --git a/src/qml/jsruntime/qv4generatorobject.cpp b/src/qml/jsruntime/qv4generatorobject.cpp index cd2d83cff9..e7a63ba185 100644 --- a/src/qml/jsruntime/qv4generatorobject.cpp +++ b/src/qml/jsruntime/qv4generatorobject.cpp @@ -26,7 +26,7 @@ ReturnedValue GeneratorFunctionCtor::virtualCallAsConstructor(const FunctionObje if (engine->hasException) return Encode::undefined(); - Function *vmf = compilationUnit->linkToEngine(engine); + Function *vmf = compilationUnit->rootFunction(); ExecutionContext *global = engine->scriptContext(); ReturnedValue o = Encode(GeneratorFunction::create(global, vmf)); diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index ab0e6ca813..4fee617c7f 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -33,7 +33,7 @@ Script::Script(ExecutionEngine *v4, QmlContext *qml, const QQmlRefPointer<Execut parsed = true; - vmFunction = compilationUnit ? compilationUnit->linkToEngine(v4) : nullptr; + vmFunction = compilationUnit ? compilationUnit->rootFunction() : nullptr; } Script::~Script() @@ -94,8 +94,9 @@ void Script::parse() if (v4->hasException) return; - compilationUnit = QV4::ExecutableCompilationUnit::create(cg.generateCompilationUnit()); - vmFunction = compilationUnit->linkToEngine(v4); + compilationUnit = QV4::ExecutableCompilationUnit::create( + cg.generateCompilationUnit(), v4); + vmFunction = compilationUnit->rootFunction(); } if (!vmFunction) { @@ -198,10 +199,8 @@ Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlCo : nullptr) { QQmlRefPointer<QV4::ExecutableCompilationUnit> jsUnit = QV4::ExecutableCompilationUnit::create( - QQmlRefPointer<QV4::CompiledData::CompilationUnit>( - new QV4::CompiledData::CompilationUnit( - cachedUnit->qmlData, cachedUnit->aotCompiledFunctions), - QQmlRefPointer<QV4::CompiledData::CompilationUnit>::Adopt)); + QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>( + cachedUnit->qmlData, cachedUnit->aotCompiledFunctions), engine); return new QV4::Script(engine, qmlContext, jsUnit); } diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index c51aafc7e6..d2a4aaf5a7 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1959,8 +1959,9 @@ QV4::ExecutableCompilationUnit *QQmlEnginePrivate::compilationUnitFromUrl(const auto unit = typeLoader.getType(url)->compilationUnit(); if (!unit) return nullptr; - if (!unit->engine) - unit->linkToEngine(v4engine()); + Q_ASSERT(unit->engine == v4engine()); + if (!unit->runtimeStrings) + unit->populate(); return unit; } diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 10255b5f8f..206a4ecc44 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -103,8 +103,10 @@ void QQmlObjectCreator::init(QQmlRefPointer<QQmlContextData> providedParentConte engine = parentContext->engine(); v4 = engine->handle(); - if (compilationUnit && !compilationUnit->engine) - compilationUnit->linkToEngine(v4); + Q_ASSERT(compilationUnit); + Q_ASSERT(compilationUnit->engine == v4); + if (!compilationUnit->runtimeStrings) + compilationUnit->populate(); qmlUnit = compilationUnit->unitData(); _qobject = nullptr; diff --git a/src/qml/qml/qqmlscriptblob.cpp b/src/qml/qml/qqmlscriptblob.cpp index 6d7be99555..c0117cb24a 100644 --- a/src/qml/qml/qqmlscriptblob.cpp +++ b/src/qml/qml/qqmlscriptblob.cpp @@ -34,12 +34,13 @@ QQmlRefPointer<QQmlScriptData> QQmlScriptBlob::scriptData() const void QQmlScriptBlob::dataReceived(const SourceCodeData &data) { + auto *v4 = QQmlEnginePrivate::getV4Engine(typeLoader()->engine()); if (readCacheFile()) { - QQmlRefPointer<QV4::ExecutableCompilationUnit> unit - = QV4::ExecutableCompilationUnit::create(); + auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(); QString error; if (unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) { - initializeFromCompilationUnit(unit); + initializeFromCompilationUnit( + QV4::ExecutableCompilationUnit::create(std::move(unit), v4)); return; } else { qCDebug(DBG_DISK_CACHE()) << "Error loading" << urlString() << "from disk cache:" << error; @@ -96,32 +97,28 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data) unit = std::move(irUnit.javaScriptCompilationUnit); } - auto executableUnit = QV4::ExecutableCompilationUnit::create(std::move(unit)); - if (writeCacheFile()) { QString errorString; - if (executableUnit->saveToDisk(url(), &errorString)) { + if (unit->saveToDisk(url(), &errorString)) { QString error; - if (!executableUnit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) { + if (!unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) { // ignore error, keep using the in-memory compilation unit. } } else { qCDebug(DBG_DISK_CACHE()) << "Error saving cached version of" - << executableUnit->fileName() << "to disk:" << errorString; + << unit->fileName() << "to disk:" << errorString; } } - initializeFromCompilationUnit(executableUnit); + initializeFromCompilationUnit(QV4::ExecutableCompilationUnit::create(std::move(unit), v4)); } void QQmlScriptBlob::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) { initializeFromCompilationUnit(QV4::ExecutableCompilationUnit::create( - QQmlRefPointer<QV4::CompiledData::CompilationUnit>( - new QV4::CompiledData::CompilationUnit( - unit->qmlData, unit->aotCompiledFunctions, - urlString(), finalUrlString()), - QQmlRefPointer<QV4::CompiledData::CompilationUnit>::Adopt))); + QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>( + unit->qmlData, unit->aotCompiledFunctions, urlString(), finalUrlString()), + QQmlEnginePrivate::getV4Engine(typeLoader()->engine()))); } void QQmlScriptBlob::done() diff --git a/src/qml/qml/qqmlscriptdata.cpp b/src/qml/qml/qqmlscriptdata.cpp index 563392889c..8b833eb877 100644 --- a/src/qml/qml/qqmlscriptdata.cpp +++ b/src/qml/qml/qqmlscriptdata.cpp @@ -81,7 +81,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext( /* scopeObject: */ nullptr); } - QV4::Scoped<QV4::Module> module(scope, m_precompiledScript->instantiate(v4)); + QV4::Scoped<QV4::Module> module(scope, m_precompiledScript->instantiate()); if (module) { if (qmlExecutionContext) { module->d()->scope->outer.set(v4, qmlExecutionContext->d()); diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index 03779b33eb..12663b608b 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -24,19 +24,19 @@ DEFINE_BOOL_CONFIG_OPTION( Q_LOGGING_CATEGORY(lcQmlTypeCompiler, "qt.qml.typecompiler"); -QQmlTypeCompiler::QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, - QmlIR::Document *parsedQML, const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, - QV4::ResolvedTypeReferenceMap *resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher) +QQmlTypeCompiler::QQmlTypeCompiler( + QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *parsedQML, + QV4::ResolvedTypeReferenceMap *resolvedTypeCache, + const QV4::CompiledData::DependentTypesHasher &dependencyHasher) : resolvedTypes(resolvedTypeCache) , engine(engine) , dependencyHasher(dependencyHasher) , document(parsedQML) - , typeNameCache(typeNameCache) , typeData(typeData) { } -QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile() +QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlTypeCompiler::compile() { // Build property caches and VME meta object data @@ -142,14 +142,7 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile() if (!errors.isEmpty()) return nullptr; - QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit - = QV4::ExecutableCompilationUnit::create(std::move( - document->javaScriptCompilationUnit)); - compilationUnit->typeNameCache = typeNameCache; - compilationUnit->resolvedTypes = *resolvedTypes; - compilationUnit->propertyCaches = std::move(m_propertyCaches); - Q_ASSERT(compilationUnit->propertyCaches.count() == static_cast<int>(compilationUnit->objectCount())); - return compilationUnit; + return std::move(document->javaScriptCompilationUnit); } void QQmlTypeCompiler::recordError(const QV4::CompiledData::Location &location, const QString &description) diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h index 2e183ed837..aba3b45d43 100644 --- a/src/qml/qml/qqmltypecompiler_p.h +++ b/src/qml/qml/qqmltypecompiler_p.h @@ -46,7 +46,6 @@ public: QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document, - const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, QV4::ResolvedTypeReferenceMap *resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher); @@ -75,7 +74,7 @@ public: } // --- - QQmlRefPointer<QV4::ExecutableCompilationUnit> compile(); + QQmlRefPointer<QV4::CompiledData::CompilationUnit> compile(); QList<QQmlError> compilationErrors() const { return errors; } void recordError(const QV4::CompiledData::Location &location, const QString &description); @@ -130,7 +129,6 @@ private: // index in first hash is component index, vector inside contains object indices of objects with id property QQmlPropertyCacheVector m_propertyCaches; - QQmlRefPointer<QQmlTypeNameCache> typeNameCache; QQmlTypeData *typeData; }; diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index e69f21c930..597683f77b 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -90,7 +90,7 @@ bool QQmlTypeData::tryLoadFromDiskCache() if (!v4) return false; - QQmlRefPointer<QV4::ExecutableCompilationUnit> unit = QV4::ExecutableCompilationUnit::create(); + auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(); { QString error; if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), &error)) { @@ -100,11 +100,11 @@ bool QQmlTypeData::tryLoadFromDiskCache() } if (unit->unitData()->flags & QV4::CompiledData::Unit::PendingTypeCompilation) { - restoreIR(unit->baseCompilationUnit()); + restoreIR(unit); return true; } - m_compiledData = unit; + m_compiledData = QV4::ExecutableCompilationUnit::create(std::move(unit), v4); QVector<QV4::CompiledData::InlineComponent> ics; for (int i = 0, count = m_compiledData->objectCount(); i < count; ++i) { @@ -819,9 +819,10 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach & QV4::CompiledData::Unit::PendingTypeCompilation); QQmlEnginePrivate * const enginePrivate = QQmlEnginePrivate::get(typeLoader()->engine()); - QQmlTypeCompiler compiler(enginePrivate, this, m_document.data(), typeNameCache, resolvedTypeCache, dependencyHasher); - m_compiledData = compiler.compile(); - if (!m_compiledData) { + QQmlTypeCompiler compiler( + enginePrivate, this, m_document.data(), resolvedTypeCache, dependencyHasher); + auto compilationUnit = compiler.compile(); + if (!compilationUnit) { qDeleteAll(*resolvedTypeCache); resolvedTypeCache->clear(); setError(compiler.compilationErrors()); @@ -831,15 +832,24 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach const bool trySaveToDisk = writeCacheFile() && !typeRecompilation; if (trySaveToDisk) { QString errorString; - if (m_compiledData->saveToDisk(url(), &errorString)) { + if (compilationUnit->saveToDisk(url(), &errorString)) { QString error; - if (!m_compiledData->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), &error)) { + if (!compilationUnit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), &error)) { // ignore error, keep using the in-memory compilation unit. } } else { - qCDebug(DBG_DISK_CACHE) << "Error saving cached version of" << m_compiledData->fileName() << "to disk:" << errorString; + qCDebug(DBG_DISK_CACHE) << "Error saving cached version of" + << compilationUnit->fileName() << "to disk:" << errorString; } } + + m_compiledData = QV4::ExecutableCompilationUnit::create( + std::move(compilationUnit), enginePrivate->v4engine()); + 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())); } void QQmlTypeData::resolveTypes() diff --git a/src/qmlworkerscript/qquickworkerscript.cpp b/src/qmlworkerscript/qquickworkerscript.cpp index f57d39b0c7..6f09d4357d 100644 --- a/src/qmlworkerscript/qquickworkerscript.cpp +++ b/src/qmlworkerscript/qquickworkerscript.cpp @@ -255,7 +255,7 @@ void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url) if (fileName.endsWith(QLatin1String(".mjs"))) { auto module = engine->loadModule(url); if (module.compiled) { - if (module.compiled->instantiate(engine)) + if (module.compiled->instantiate()) module.compiled->evaluate(); } else if (module.native) { // Nothing to do. There is no global code in a native module. diff --git a/tests/auto/qml/ecmascripttests/test262runner.cpp b/tests/auto/qml/ecmascripttests/test262runner.cpp index 4c39dd661f..7c1931bfa4 100644 --- a/tests/auto/qml/ecmascripttests/test262runner.cpp +++ b/tests/auto/qml/ecmascripttests/test262runner.cpp @@ -342,7 +342,7 @@ void Test262Runner::executeTest(QV4::ExecutionEngine &vm, const QString &testDat if (!vm.hasException) { const auto rootModule = vm.loadModule(rootModuleUrl); - if (rootModule.compiled && rootModule.compiled->instantiate(&vm)) + if (rootModule.compiled && rootModule.compiled->instantiate()) rootModule.compiled->evaluate(); } } else { diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp index 6f899f21c7..af4b60a84b 100644 --- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp +++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp @@ -103,7 +103,7 @@ struct TestCompiler { closeMapping(); testFilePath = baseDirectory + QStringLiteral("/test.qml"); - cacheFilePath = QV4::ExecutableCompilationUnit::localCacheFilePath( + cacheFilePath = QV4::CompiledData::CompilationUnit::localCacheFilePath( QUrl::fromLocalFile(testFilePath)); mappedFile.setFileName(cacheFilePath); } @@ -175,7 +175,7 @@ struct TestCompiler return false; } - const QString targetCacheFilePath = QV4::ExecutableCompilationUnit::localCacheFilePath( + const QString targetCacheFilePath = QV4::CompiledData::CompilationUnit::localCacheFilePath( QUrl::fromLocalFile(targetTestFilePath)); QFile source(cacheFilePath); @@ -202,16 +202,14 @@ struct TestCompiler { const QString path = fileName.isEmpty() ? testFilePath : tempDir.path() + "/" + fileName; - QQmlRefPointer<QV4::ExecutableCompilationUnit> unit - = QV4::ExecutableCompilationUnit::create(); + auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(); return unit->loadFromDisk(QUrl::fromLocalFile(path), QFileInfo(path).lastModified(), &lastErrorString); } quintptr unitData() { - QQmlRefPointer<QV4::ExecutableCompilationUnit> unit - = QV4::ExecutableCompilationUnit::create(); + auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(); return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), QFileInfo(testFilePath).lastModified(), &lastErrorString) ? quintptr(unit->unitData()) @@ -294,12 +292,12 @@ void tst_qmldiskcache::loadLocalAsFallback() f.write(reinterpret_cast<const char *>(&unit), sizeof(unit)); } - QQmlRefPointer<QV4::ExecutableCompilationUnit> unit = QV4::ExecutableCompilationUnit::create(); + auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(); bool loaded = unit->loadFromDisk(QUrl::fromLocalFile(testCompiler.testFilePath), QFileInfo(testCompiler.testFilePath).lastModified(), &testCompiler.lastErrorString); QVERIFY2(loaded, qPrintable(testCompiler.lastErrorString)); - QCOMPARE(unit->objectCount(), 1); + QCOMPARE(unit->qmlData->nObjects, 1u); } void tst_qmldiskcache::regenerateAfterChange() @@ -611,7 +609,7 @@ void tst_qmldiskcache::fileSelectors() QVERIFY(!obj.isNull()); QCOMPARE(obj->property("value").toInt(), 42); - QFile cacheFile(QV4::ExecutableCompilationUnit::localCacheFilePath( + QFile cacheFile(QV4::CompiledData::CompilationUnit::localCacheFilePath( QUrl::fromLocalFile(testFilePath))); QVERIFY2(cacheFile.exists(), qPrintable(cacheFile.fileName())); } @@ -627,7 +625,7 @@ void tst_qmldiskcache::fileSelectors() QVERIFY(!obj.isNull()); QCOMPARE(obj->property("value").toInt(), 100); - QFile cacheFile(QV4::ExecutableCompilationUnit::localCacheFilePath( + QFile cacheFile(QV4::CompiledData::CompilationUnit::localCacheFilePath( QUrl::fromLocalFile(selectedTestFilePath))); QVERIFY2(cacheFile.exists(), qPrintable(cacheFile.fileName())); } @@ -836,7 +834,7 @@ void tst_qmldiskcache::stableOrderOfDependentCompositeTypes() QVERIFY2(firstDependentTypeClassName.contains("QMLTYPE"), firstDependentTypeClassName.constData()); QVERIFY2(secondDependentTypeClassName.contains("QMLTYPE"), secondDependentTypeClassName.constData()); - const QString testFileCachePath = QV4::ExecutableCompilationUnit::localCacheFilePath( + const QString testFileCachePath = QV4::CompiledData::CompilationUnit::localCacheFilePath( QUrl::fromLocalFile(testFilePath)); QVERIFY(QFile::exists(testFileCachePath)); QDateTime initialCacheTimeStamp = QFileInfo(testFileCachePath).lastModified(); @@ -915,7 +913,7 @@ void tst_qmldiskcache::singletonDependency() QCOMPARE(obj->property("value").toInt(), 42); } - const QString testFileCachePath = QV4::ExecutableCompilationUnit::localCacheFilePath( + const QString testFileCachePath = QV4::CompiledData::CompilationUnit::localCacheFilePath( QUrl::fromLocalFile(testFilePath)); QVERIFY(QFile::exists(testFileCachePath)); QDateTime initialCacheTimeStamp = QFileInfo(testFileCachePath).lastModified(); @@ -973,7 +971,7 @@ void tst_qmldiskcache::cppRegisteredSingletonDependency() QCOMPARE(value.toInt(), 42); } - const QString testFileCachePath = QV4::ExecutableCompilationUnit::localCacheFilePath( + const QString testFileCachePath = QV4::CompiledData::CompilationUnit::localCacheFilePath( QUrl::fromLocalFile(testFilePath)); QVERIFY(QFile::exists(testFileCachePath)); QDateTime initialCacheTimeStamp = QFileInfo(testFileCachePath).lastModified(); @@ -1021,7 +1019,7 @@ void tst_qmldiskcache::cacheModuleScripts() QVERIFY(unitData); QVERIFY(unitData->flags & QV4::CompiledData::Unit::StaticData); QVERIFY(unitData->flags & QV4::CompiledData::Unit::IsESModule); - QVERIFY(compilationUnit->backingFile); + QVERIFY(compilationUnit->baseCompilationUnit()->backingFile); } const QSet<QString> entries = entrySet(m_qmlCacheDirectory, QStringList("*.mjsc")); @@ -1138,8 +1136,7 @@ void tst_qmldiskcache::invalidateSaveLoadCache() } QString errorString; - QQmlRefPointer<QV4::ExecutableCompilationUnit> oldUnit - = QV4::ExecutableCompilationUnit::create(); + auto oldUnit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(); QVERIFY2(oldUnit->loadFromDisk(url, QFileInfo(fileName).lastModified(), &errorString), qPrintable(errorString)); // Produce a checksum mismatch. @@ -1182,8 +1179,7 @@ void tst_qmldiskcache::invalidateSaveLoadCache() // The cache should have been invalidated after all. // So, now we should be able to load a freshly written CU. - QQmlRefPointer<QV4::ExecutableCompilationUnit> unit - = QV4::ExecutableCompilationUnit::create(); + auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(); QVERIFY2(unit->loadFromDisk(url, QFileInfo(fileName).lastModified(), &errorString), qPrintable(errorString)); QVERIFY(unit->unitData() != oldUnit->unitData()); diff --git a/tools/qmljs/qmljs.cpp b/tools/qmljs/qmljs.cpp index 2b12c4fc9d..99de7f528c 100644 --- a/tools/qmljs/qmljs.cpp +++ b/tools/qmljs/qmljs.cpp @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) if (runAsModule) { auto module = vm.loadModule(QUrl::fromLocalFile(QFileInfo(fn).absoluteFilePath())); if (module.compiled) { - if (module.compiled->instantiate(&vm)) + if (module.compiled->instantiate()) module.compiled->evaluate(); } else if (module.native) { // Nothing to do. Native modules have no global code. @@ -120,11 +120,12 @@ int main(int argc, char *argv[]) } QScopedPointer<QV4::Script> script; if (useCache && QFile::exists(fn + QLatin1Char('c'))) { - QQmlRefPointer<QV4::ExecutableCompilationUnit> unit - = QV4::ExecutableCompilationUnit::create(); + auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>(); QString error; if (unit->loadFromDisk(QUrl::fromLocalFile(fn), QFileInfo(fn).lastModified(), &error)) { - script.reset(new QV4::Script(&vm, nullptr, unit)); + script.reset(new QV4::Script( + &vm, nullptr, QV4::ExecutableCompilationUnit::create( + std::move(unit), &vm))); } else { std::cout << "Error loading" << qPrintable(fn) << "from disk cache:" << qPrintable(error) << std::endl; } @@ -145,7 +146,8 @@ int main(int argc, char *argv[]) const_cast<QV4::CompiledData::Unit*>(unit->unitData())->sourceTimeStamp = QFileInfo(fn).lastModified().toMSecsSinceEpoch(); } QString saveError; - if (!unit->saveToDisk(QUrl::fromLocalFile(fn), &saveError)) { + if (!unit->baseCompilationUnit()->saveToDisk( + QUrl::fromLocalFile(fn), &saveError)) { std::cout << "Error saving JS cache file: " << qPrintable(saveError) << std::endl; } } |