diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2016-07-28 17:40:32 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2016-08-02 07:22:26 +0000 |
commit | 54ee6994e66936c1d532f7718c858c9b18e3c91d (patch) | |
tree | cd4620b0d41dfe3f20164e570ed64faa8fa663ac /src/qml | |
parent | fa53d4e35433cc59e99b24f16f18c713683c1a80 (diff) |
Add a checksum to the generated QML compilation units
Change-Id: Icd5b1d805059981cbbb4c0eb2a5c842d59223839
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 16 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 13 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 10 | ||||
-rw-r--r-- | src/qml/compiler/qv4compiler.cpp | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 4 |
8 files changed, 45 insertions, 6 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index f736e04b88..31250d0d57 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1359,7 +1359,7 @@ bool IRBuilder::isRedundantNullInitializerForPropertyDeclaration(Property *prope return QQmlJS::AST::cast<QQmlJS::AST::NullExpression *>(expr); } -QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output) +QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, QQmlEngine *engine, const QV4::CompiledData::ResolvedTypeReferenceMap &dependentTypes) { QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = output.javaScriptCompilationUnit; QV4::CompiledData::Unit *jsUnit = compilationUnit->createUnitData(&output); @@ -1402,6 +1402,20 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output) qmlUnit->offsetToStringTable = totalSize - output.jsGenerator.stringTable.sizeOfTableAndData(); qmlUnit->stringTableSize = output.jsGenerator.stringTable.stringCount(); +#ifndef V4_BOOTSTRAP + if (!dependentTypes.isEmpty()) { + QCryptographicHash hash(QCryptographicHash::Md5); + if (dependentTypes.addToHash(&hash, engine)) { + QByteArray checksum = hash.result(); + Q_ASSERT(checksum.size() == sizeof(qmlUnit->dependencyMD5Checksum)); + memcpy(qmlUnit->dependencyMD5Checksum, checksum.constData(), sizeof(qmlUnit->dependencyMD5Checksum)); + } + } +#else + Q_UNUSED(dependentTypes); + Q_UNUSED(engine); +#endif + // write imports char *importPtr = data + qmlUnit->offsetToImports; foreach (const QV4::CompiledData::Import *imp, output.imports) { diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index 821a6bba6d..eedc262e7a 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -549,7 +549,7 @@ public: struct Q_QML_PRIVATE_EXPORT QmlUnitGenerator { - QV4::CompiledData::Unit *generate(Document &output); + QV4::CompiledData::Unit *generate(Document &output, QQmlEngine *engine, const QV4::CompiledData::ResolvedTypeReferenceMap &dependentTypes); private: typedef bool (Binding::*BindingFilter)() const; diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index a0b219e28e..68de9aee44 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -156,7 +156,7 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile() // Generate QML compiled type data structures QmlIR::QmlUnitGenerator qmlGenerator; - QV4::CompiledData::Unit *qmlUnit = qmlGenerator.generate(*document); + QV4::CompiledData::Unit *qmlUnit = qmlGenerator.generate(*document, QQmlEnginePrivate::get(engine), resolvedTypes); Q_ASSERT(document->javaScriptCompilationUnit); // The js unit owns the data and will free the qml unit. diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 2aab1743cc..83ae9c56df 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -579,6 +579,19 @@ void ResolvedTypeReference::doDynamicTypeCheck() mo = compilationUnit->rootPropertyCache()->firstCppMetaObject(); isFullyDynamicType = qtTypeInherits<QQmlPropertyMap>(mo); } + +bool ResolvedTypeReferenceMap::addToHash(QCryptographicHash *hash, QQmlEngine *engine) const +{ + for (auto it = constBegin(), end = constEnd(); it != end; ++it) { + QQmlPropertyCache *pc = it.value()->createPropertyCache(engine); + bool ok = false; + hash->addData(pc->checksum(&ok)); + if (!ok) + return false; + } + return true; +} + #endif } diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 82e303f27d..519708f089 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -611,6 +611,7 @@ struct Unit LEUInt32 architectureIndex; // string index to QSysInfo::buildAbi() LEUInt32 codeGeneratorIndex; + char dependencyMD5Checksum[16]; enum : unsigned int { IsJavascript = 0x1, @@ -788,7 +789,14 @@ struct ResolvedTypeReference void doDynamicTypeCheck(); }; // map from name index -typedef QHash<int, ResolvedTypeReference*> ResolvedTypeReferenceMap; +// While this could be a hash, a map is chosen here to provide a stable +// order, which is used to calculating a check-sum on dependent meta-objects. +struct ResolvedTypeReferenceMap: public QMap<int, ResolvedTypeReference*> +{ + bool addToHash(QCryptographicHash *hash, QQmlEngine *engine) const; +}; +#else +struct ResolvedTypeReferenceMap {}; #endif // index is per-object binding index diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index 768a4ffcd3..8503317430 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -361,6 +361,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp unit.qtVersion = QT_VERSION; unit.architectureIndex = registerString(QSysInfo::buildAbi()); unit.codeGeneratorIndex = registerString(codeGeneratorName); + memset(unit.dependencyMD5Checksum, 0, sizeof(unit.dependencyMD5Checksum)); quint32 nextOffset = sizeof(CompiledData::Unit); diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index c54af43a6f..9f94aa41ec 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2910,7 +2910,8 @@ void QQmlScriptBlob::dataReceived(const Data &data) irUnit.unitFlags |= QV4::CompiledData::Unit::IsSharedLibrary; QmlIR::QmlUnitGenerator qmlGenerator; - QV4::CompiledData::Unit *unitData = qmlGenerator.generate(irUnit); + QV4::CompiledData::ResolvedTypeReferenceMap emptyDependencies; + QV4::CompiledData::Unit *unitData = qmlGenerator.generate(irUnit, m_typeLoader->engine(), emptyDependencies); Q_ASSERT(!unit->data); // The js unit owns the data and will free the qml unit. unit->data = unitData; diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index ab6b046fcf..5f754df1fc 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -463,7 +463,9 @@ private: QList<TypeReference> m_compositeSingletons; // map from name index to resolved type - QHash<int, TypeReference> m_resolvedTypes; + // While this could be a hash, a map is chosen here to provide a stable + // order, which is used to calculating a check-sum on dependent meta-objects. + QMap<int, TypeReference> m_resolvedTypes; bool m_typesResolved:1; QQmlRefPointer<QV4::CompiledData::CompilationUnit> m_compiledData; |