diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2017-03-08 17:09:55 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2017-03-09 08:19:56 +0000 |
commit | e0add0b655941dcec483674594b63ce9775598be (patch) | |
tree | 874b27b2ba9f53223b9a91fa225273319964e47a | |
parent | 55e558144d6d78062dd5d04f786e7fccf4eeebb7 (diff) |
Fix relocation related errors when loading AOT caches
The original directory of the source file the cache was created from -
when generating ahead of time - is unlikely going to be identical to the
final location for example on a deployed device. Therefore when
generating caches ahead of time, don't store the source path, don't
attempt to verify it when loading and don't try to save the cache file
at run-time again.
We still need set the sourceFileIndex at load-time though, in order to
make relative path url resolution work (for example source: "my.png" in
an Image element).
Change-Id: I3d6952f5d0a165cfa2cb400191a9f6ffe6be69f4
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 15 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 5 | ||||
-rw-r--r-- | tools/qmlcachegen/qmlcachegen.cpp | 4 |
4 files changed, 21 insertions, 9 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 7854a49af9..668f20e4f2 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -480,10 +480,22 @@ Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument) return irDocument->jsGenerator.generateUnit(QV4::Compiler::JSUnitGenerator::GenerateWithoutStringTable); QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = irDocument->javaScriptCompilationUnit; - QV4::CompiledData::Unit *jsUnit = const_cast<QV4::CompiledData::Unit*>(irDocument->javaScriptCompilationUnit->data); + QV4::CompiledData::Unit *jsUnit = const_cast<QV4::CompiledData::Unit*>(compilationUnit->data); + auto ensureWritableUnit = [&jsUnit, &compilationUnit]() { + if (jsUnit == compilationUnit->data) { + char *unitCopy = (char*)malloc(jsUnit->unitSize); + memcpy(unitCopy, jsUnit, jsUnit->unitSize); + jsUnit = reinterpret_cast<QV4::CompiledData::Unit*>(unitCopy); + } + }; QV4::Compiler::StringTableGenerator &stringTable = irDocument->jsGenerator.stringTable; + if (jsUnit->sourceFileIndex == quint32(0) || jsUnit->stringAt(jsUnit->sourceFileIndex) != irDocument->jsModule.fileName) { + ensureWritableUnit(); + jsUnit->sourceFileIndex = stringTable.registerString(irDocument->jsModule.fileName); + } + // Collect signals that have had a change in signature (from onClicked to onClicked(mouse) for example) // and now need fixing in the QV4::CompiledData. Also register strings at the same time, to finalize // the string table. @@ -546,6 +558,7 @@ Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument) } if (!signalParameterNameTable.isEmpty()) { + ensureWritableUnit(); Q_ASSERT(jsUnit != compilationUnit->data); const uint signalParameterTableSize = signalParameterNameTable.count() * sizeof(quint32); uint newSize = jsUnit->unitSize + signalParameterTableSize; diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index 5687834b00..cc2f9b7cf2 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -348,11 +348,7 @@ Module::~Module() void Module::setFileName(const QString &name) { - if (fileName.isEmpty()) - fileName = name; - else { - Q_ASSERT(fileName == name); - } + fileName = name; } Function::Function(Module *module, Function *outer, const QString &name) diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index f4f04e12c0..68eb989c70 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2407,6 +2407,7 @@ void QQmlTypeData::restoreIR(QQmlRefPointer<QV4::CompiledData::CompilationUnit> m_document.reset(new QmlIR::Document(isDebugging())); QmlIR::IRLoader loader(unit->data, m_document.data()); loader.load(); + m_document->jsModule.setFileName(finalUrlString()); m_document->javaScriptCompilationUnit = unit; continueLoadFromIR(); } @@ -2507,6 +2508,8 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach { Q_ASSERT(m_compiledData.isNull()); + const bool typeRecompilation = m_document && m_document->javaScriptCompilationUnit && m_document->javaScriptCompilationUnit->data->flags & QV4::CompiledData::Unit::PendingTypeCompilation; + QQmlEnginePrivate * const enginePrivate = QQmlEnginePrivate::get(typeLoader()->engine()); QQmlTypeCompiler compiler(enginePrivate, this, m_document.data(), typeNameCache, resolvedTypeCache); m_compiledData = compiler.compile(); @@ -2515,7 +2518,7 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach return; } - const bool trySaveToDisk = (!disableDiskCache() || forceDiskCache()) && !m_document->jsModule.debugMode; + const bool trySaveToDisk = (!disableDiskCache() || forceDiskCache()) && !m_document->jsModule.debugMode && !typeRecompilation; if (trySaveToDisk) { QString errorString; if (m_compiledData->saveToDisk(url(), &errorString)) { diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp index 78159c38d1..eb2986d957 100644 --- a/tools/qmlcachegen/qmlcachegen.cpp +++ b/tools/qmlcachegen/qmlcachegen.cpp @@ -112,7 +112,7 @@ static bool compileQmlFile(const QString &inputFileName, const QString &outputFi } { - QmlIR::JSCodeGen v4CodeGen(inputFileName, irDocument.code, &irDocument.jsModule, &irDocument.jsParserEngine, irDocument.program, /*import cache*/0, &irDocument.jsGenerator.stringTable); + QmlIR::JSCodeGen v4CodeGen(/*empty input file name*/QString(), irDocument.code, &irDocument.jsModule, &irDocument.jsParserEngine, irDocument.program, /*import cache*/0, &irDocument.jsGenerator.stringTable); for (QmlIR::Object *object: qAsConst(irDocument.objects)) { if (object->functionsAndExpressions->count == 0) continue; @@ -215,7 +215,7 @@ static bool compileJSFile(const QString &inputFileName, const QString &outputFil { QmlIR::JSCodeGen v4CodeGen(inputFileName, irDocument.code, &irDocument.jsModule, &irDocument.jsParserEngine, irDocument.program, /*import cache*/0, &irDocument.jsGenerator.stringTable); - v4CodeGen.generateFromProgram(inputFileName, sourceCode, program, &irDocument.jsModule, QQmlJS::Codegen::GlobalCode); + v4CodeGen.generateFromProgram(/*empty input file name*/QString(), sourceCode, program, &irDocument.jsModule, QQmlJS::Codegen::GlobalCode); QList<QQmlJS::DiagnosticMessage> jsErrors = v4CodeGen.errors(); if (!jsErrors.isEmpty()) { for (const QQmlJS::DiagnosticMessage &e: qAsConst(jsErrors)) { |