aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4compileddata.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2018-07-20 09:22:47 -0700
committerSimon Hausmann <simon.hausmann@qt.io>2018-07-27 04:56:14 +0000
commit447e2e024609a22fe052cf458c27efdef2e3d3eb (patch)
treef2665cfdea84b9d85044a3221658eb8ce10e7d9a /src/qml/compiler/qv4compileddata.cpp
parent65fd9165162a8498c5bbe71e5372b65770c240b0 (diff)
Try to load QML cache from CacheLocation if side-by-side fails
This could happen if the .qmlc file is stale or corrupt for some reason. In that case, we should try to load a cache file from the user's CacheLocation. Change-Id: Id2be776c7ae0467c9d9ffffd1543204272a531d1 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4compileddata.cpp')
-rw-r--r--src/qml/compiler/qv4compileddata.cpp44
1 files changed, 28 insertions, 16 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 02aee47eea..0c81a5b3c6 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -76,7 +76,18 @@ namespace QV4 {
namespace CompiledData {
+#if defined(QML_COMPILE_HASH)
+# ifdef Q_OS_LINUX
+// Place on a separate section on Linux so it's easier to check from outside
+// what the hash version is.
+__attribute__((section(".qml_compile_hash")))
+# endif
+const char qml_compile_hash[48 + 1] = QML_COMPILE_HASH;
static_assert(sizeof(Unit::libraryVersionHash) >= QML_COMPILE_HASH_LENGTH + 1, "Compile hash length exceeds reserved size in data structure. Please adjust and bump the format version");
+#else
+# error "QML_COMPILE_HASH must be defined for the build of QtDeclarative to ensure version checking for cache files"
+#endif
+
CompilationUnit::CompilationUnit(const Unit *unitData)
{
@@ -351,26 +362,27 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeS
const QString sourcePath = QQmlFile::urlToLocalFileOrQrc(url);
QScopedPointer<CompilationUnitMapper> cacheFile(new CompilationUnitMapper());
- QString cachePath = sourcePath + QLatin1Char('c');
- if (!QFile::exists(cachePath))
- cachePath = localCacheFilePath(url);
+ const QStringList cachePaths = { sourcePath + QLatin1Char('c'), localCacheFilePath(url) };
+ for (const QString &cachePath : cachePaths) {
+ CompiledData::Unit *mappedUnit = cacheFile->open(cachePath, sourceTimeStamp, errorString);
+ if (!mappedUnit)
+ continue;
- CompiledData::Unit *mappedUnit = cacheFile->open(cachePath, sourceTimeStamp, errorString);
- if (!mappedUnit)
- return false;
+ const Unit * const oldDataPtr = (data && !(data->flags & QV4::CompiledData::Unit::StaticData)) ? data : nullptr;
+ QScopedValueRollback<const Unit *> dataPtrChange(data, mappedUnit);
- const Unit * const oldDataPtr = (data && !(data->flags & QV4::CompiledData::Unit::StaticData)) ? data : nullptr;
- QScopedValueRollback<const Unit *> dataPtrChange(data, mappedUnit);
+ if (data->sourceFileIndex != 0 && sourcePath != QQmlFile::urlToLocalFileOrQrc(stringAt(data->sourceFileIndex))) {
+ *errorString = QStringLiteral("QML source file has moved to a different location.");
+ continue;
+ }
- if (data->sourceFileIndex != 0 && sourcePath != QQmlFile::urlToLocalFileOrQrc(stringAt(data->sourceFileIndex))) {
- *errorString = QStringLiteral("QML source file has moved to a different location.");
- return false;
+ dataPtrChange.commit();
+ free(const_cast<Unit*>(oldDataPtr));
+ backingFile.reset(cacheFile.take());
+ return true;
}
- dataPtrChange.commit();
- free(const_cast<Unit*>(oldDataPtr));
- backingFile.reset(cacheFile.take());
- return true;
+ return false;
}
void CompilationUnit::linkBackendToEngine(ExecutionEngine *engine)
@@ -783,7 +795,7 @@ bool Unit::verifyHeader(QDateTime expectedSourceTimeStamp, QString *errorString)
}
#if defined(QML_COMPILE_HASH)
- if (qstrcmp(QML_COMPILE_HASH, libraryVersionHash) != 0) {
+ if (qstrcmp(CompiledData::qml_compile_hash, libraryVersionHash) != 0) {
*errorString = QStringLiteral("QML library version mismatch. Expected compile hash does not match");
return false;
}