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>
This commit is contained in:
parent
55e558144d
commit
e0add0b655
|
@ -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;
|
||||
|
|
|
@ -348,11 +348,7 @@ Module::~Module()
|
|||
|
||||
void Module::setFileName(const QString &name)
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
fileName = name;
|
||||
else {
|
||||
Q_ASSERT(fileName == name);
|
||||
}
|
||||
}
|
||||
|
||||
Function::Function(Module *module, Function *outer, const QString &name)
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Reference in New Issue