diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2017-03-25 10:59:43 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2017-03-25 10:59:43 +0000 |
commit | e2863c80fed06104eedfe83bce2737f2d24908a6 (patch) | |
tree | 7981bfb6f3d9ea9f74a58da688e4a26caec19aee /src | |
parent | 8bed5de48c3ec24f9ad335e5398d92d0a60c448c (diff) | |
parent | 7f325896634a3b99e778d90e5fe738a47f855526 (diff) |
Merge "Merge remote-tracking branch 'origin/5.8' into 5.9" into refs/staging/5.9
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 9 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 5 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler_p.h | 4 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 7 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 2 | ||||
-rw-r--r-- | src/qml/memory/qv4heap_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 52 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 3 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qsgsimplematerial.cpp | 12 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qsgsimplematerial.h | 1 |
12 files changed, 73 insertions, 33 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 0a6efa7867..9f2c2294ed 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1361,7 +1361,7 @@ bool IRBuilder::isRedundantNullInitializerForPropertyDeclaration(Property *prope return QQmlJS::AST::cast<QQmlJS::AST::NullExpression *>(expr); } -QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, QQmlEngine *engine, const QV4::CompiledData::ResolvedTypeReferenceMap &dependentTypes) +QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher) { QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = output.javaScriptCompilationUnit; QV4::CompiledData::Unit *jsUnit = compilationUnit->createUnitData(&output); @@ -1404,17 +1404,16 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, QQmlEngine qmlUnit->stringTableSize = output.jsGenerator.stringTable.stringCount(); #ifndef V4_BOOTSTRAP - if (!dependentTypes.isEmpty()) { + if (dependencyHasher) { QCryptographicHash hash(QCryptographicHash::Md5); - if (dependentTypes.addToHash(&hash, engine)) { + if (dependencyHasher(&hash)) { 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); + Q_UNUSED(dependencyHasher); #endif // write imports diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index b579a963a1..64bf111d9a 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -548,7 +548,7 @@ public: struct Q_QML_PRIVATE_EXPORT QmlUnitGenerator { - QV4::CompiledData::Unit *generate(Document &output, QQmlEngine *engine, const QV4::CompiledData::ResolvedTypeReferenceMap &dependentTypes); + QV4::CompiledData::Unit *generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher = QV4::CompiledData::DependentTypesHasher()); private: typedef bool (Binding::*BindingFilter)() const; diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 109eb86c2e..a3b8784fc8 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -58,10 +58,11 @@ QT_BEGIN_NAMESPACE QQmlTypeCompiler::QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *parsedQML, const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, - const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache) + const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher) : resolvedTypes(resolvedTypeCache) , engine(engine) , typeData(typeData) + , dependencyHasher(dependencyHasher) , typeNameCache(typeNameCache) , document(parsedQML) { @@ -156,7 +157,7 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile() // Generate QML compiled type data structures QmlIR::QmlUnitGenerator qmlGenerator; - QV4::CompiledData::Unit *qmlUnit = qmlGenerator.generate(*document, QQmlEnginePrivate::get(engine), resolvedTypes); + QV4::CompiledData::Unit *qmlUnit = qmlGenerator.generate(*document, dependencyHasher); Q_ASSERT(document->javaScriptCompilationUnit); // The js unit owns the data and will free the qml unit. diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index 2b59e7e42f..11261e3099 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -89,7 +89,8 @@ struct QQmlTypeCompiler { Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler) public: - QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document, const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache); + QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document, const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache, + const QV4::CompiledData::DependentTypesHasher &dependencyHasher); // --- interface used by QQmlPropertyCacheCreator typedef QmlIR::Object CompiledObject; @@ -139,6 +140,7 @@ private: QList<QQmlError> errors; QQmlEnginePrivate *engine; QQmlTypeData *typeData; + const QV4::CompiledData::DependentTypesHasher &dependencyHasher; QQmlRefPointer<QQmlTypeNameCache> typeNameCache; QmlIR::Document *document; // index is string index of type name (use obj->inheritedTypeNameIndex) diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 1805ab3f54..f1f0ec282c 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -324,10 +324,9 @@ void CompilationUnit::finalize(QQmlEnginePrivate *engine) totalObjectCount = objectCount; } -bool CompilationUnit::verifyChecksum(QQmlEngine *engine, - const ResolvedTypeReferenceMap &dependentTypes) const +bool CompilationUnit::verifyChecksum(const DependentTypesHasher &dependencyHasher) const { - if (dependentTypes.isEmpty()) { + if (!dependencyHasher) { for (size_t i = 0; i < sizeof(data->dependencyMD5Checksum); ++i) { if (data->dependencyMD5Checksum[i] != 0) return false; @@ -335,7 +334,7 @@ bool CompilationUnit::verifyChecksum(QQmlEngine *engine, return true; } QCryptographicHash hash(QCryptographicHash::Md5); - if (!dependentTypes.addToHash(&hash, engine)) + if (!dependencyHasher(&hash)) return false; QByteArray checksum = hash.result(); Q_ASSERT(checksum.size() == sizeof(data->dependencyMD5Checksum)); diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 8cf5437928..23f5e31ebe 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -786,8 +786,10 @@ struct ResolvedTypeReferenceMap: public QMap<int, ResolvedTypeReference*> { bool addToHash(QCryptographicHash *hash, QQmlEngine *engine) const; }; + +using DependentTypesHasher = std::function<bool(QCryptographicHash *)>; #else -struct ResolvedTypeReferenceMap {}; +struct DependentTypesHasher {}; #endif // index is per-object binding index @@ -860,8 +862,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public QVector<QQmlScriptData *> dependentScripts; ResolvedTypeReferenceMap resolvedTypes; - bool verifyChecksum(QQmlEngine *engine, - const ResolvedTypeReferenceMap &dependentTypes) const; + bool verifyChecksum(const DependentTypesHasher &dependencyHasher) const; int metaTypeId; int listMetaTypeId; diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 97fd533af2..43e99cf768 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1751,6 +1751,8 @@ Bool Runtime::method_compareEqual(const Value &left, const Value &right) return !left.isNaN(); if (left.type() == right.type()) { + if (left.isDouble() && left.doubleValue() == 0 && right.doubleValue() == 0) + return true; // this takes care of -0 == +0 (which obviously have different raw values) if (!left.isManaged()) return false; if (left.isString() == right.isString()) diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h index bdb5bef92b..173c0a3e20 100644 --- a/src/qml/memory/qv4heap_p.h +++ b/src/qml/memory/qv4heap_p.h @@ -133,7 +133,7 @@ struct Q_QML_EXPORT Base { else if (_livenessStatus == Destroyed) fprintf(stderr, "ERROR: use of object '%s' after call to destroy() !!\n", vtable()->className); - Q_ASSERT(_livenessStatus = Initialized); + Q_ASSERT(_livenessStatus == Initialized); } void _checkIsDestroyed() { if (_livenessStatus == Initialized) diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index eedb649ef6..f115d4227c 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -1525,7 +1525,8 @@ bool QQmlTypeLoader::Blob::qmldirDataAvailable(QQmlQmldirData *data, QList<QQmlE return false; } - *it = priority; + if (it != m_unresolvedImports.end()) + *it = priority; return true; } } @@ -2005,6 +2006,16 @@ QQmlTypeData::TypeDataCallback::~TypeDataCallback() { } +QString QQmlTypeData::TypeReference::qualifiedName() const +{ + QString result; + if (!prefix.isEmpty()) { + result = prefix + QLatin1Char('.'); + } + result.append(type->qmlTypeName()); + return result; +} + QQmlTypeData::QQmlTypeData(const QUrl &url, QQmlTypeLoader *manager) : QQmlTypeLoader::Blob(url, QmlFile, manager), m_typesResolved(false), m_implicitImportLoaded(false) @@ -2150,6 +2161,23 @@ void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeName aliasCreator.appendAliasPropertiesToMetaObjects(); } +static bool addTypeReferenceChecksumsToHash(const QList<QQmlTypeData::TypeReference> &typeRefs, QCryptographicHash *hash, QQmlEngine *engine) +{ + for (const auto &typeRef: typeRefs) { + if (typeRef.typeData) { + const auto unit = typeRef.typeData->compilationUnit(); + hash->addData(unit->data->md5Checksum, sizeof(unit->data->md5Checksum)); + } else if (typeRef.type) { + const auto propertyCache = QQmlEnginePrivate::get(engine)->cache(typeRef.type->metaObject()); + bool ok = false; + hash->addData(propertyCache->checksum(&ok)); + if (!ok) + return false; + } + } + return true; +} + void QQmlTypeData::done() { QDeferredCleanup cleanup([this]{ @@ -2230,8 +2258,14 @@ void QQmlTypeData::done() QQmlEngine *const engine = typeLoader()->engine(); + const auto dependencyHasher = [engine, resolvedTypeCache, this](QCryptographicHash *hash) { + if (!resolvedTypeCache.addToHash(hash, engine)) + return false; + return ::addTypeReferenceChecksumsToHash(m_compositeSingletons, hash, engine); + }; + // verify if any dependencies changed if we're using a cache - if (m_document.isNull() && !m_compiledData->verifyChecksum(engine, resolvedTypeCache)) { + if (m_document.isNull() && !m_compiledData->verifyChecksum(dependencyHasher)) { qCDebug(DBG_DISK_CACHE) << "Checksum mismatch for cached version of" << m_compiledData->url().toString(); if (!loadFromSource()) return; @@ -2241,7 +2275,7 @@ void QQmlTypeData::done() if (!m_document.isNull()) { // Compile component - compile(typeNameCache, resolvedTypeCache); + compile(typeNameCache, resolvedTypeCache, dependencyHasher); } else { createTypeAndPropertyCaches(typeNameCache, resolvedTypeCache); } @@ -2503,14 +2537,15 @@ QString QQmlTypeData::stringAt(int index) const return m_document->jsGenerator.stringTable.stringForIndex(index); } -void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache) +void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache, + const QV4::CompiledData::DependentTypesHasher &dependencyHasher) { 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); + QQmlTypeCompiler compiler(enginePrivate, this, m_document.data(), typeNameCache, resolvedTypeCache, dependencyHasher); m_compiledData = compiler.compile(); if (!m_compiledData) { setError(compiler.compilationErrors()); @@ -2582,6 +2617,10 @@ void QQmlTypeData::resolveTypes() } } + std::stable_sort(m_compositeSingletons.begin(), m_compositeSingletons.end(), [](const TypeReference &lhs, const TypeReference &rhs){ + return lhs.qualifiedName() < rhs.qualifiedName(); + }); + for (QV4::CompiledData::TypeReferenceMap::ConstIterator unresolvedRef = m_typeReferences.constBegin(), end = m_typeReferences.constEnd(); unresolvedRef != end; ++unresolvedRef) { @@ -2920,8 +2959,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data) irUnit.jsModule.unitFlags |= QV4::CompiledData::Unit::IsSharedLibrary; QmlIR::QmlUnitGenerator qmlGenerator; - QV4::CompiledData::ResolvedTypeReferenceMap emptyDependencies; - QV4::CompiledData::Unit *unitData = qmlGenerator.generate(irUnit, m_typeLoader->engine(), emptyDependencies); + QV4::CompiledData::Unit *unitData = qmlGenerator.generate(irUnit); 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 1bd2c7f1e1..48e7d5cba4 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -401,6 +401,7 @@ public: int minorVersion; QQmlTypeData *typeData; QString prefix; // used by CompositeSingleton types + QString qualifiedName() const; bool needsCreation; }; @@ -455,7 +456,7 @@ private: QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache ) const; void compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, - const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache); + const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher); void createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache); bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref, int lineNumber = -1, int columnNumber = -1, bool reportErrors = true); diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp index 7214a255df..f29c58ad9e 100644 --- a/src/quick/scenegraph/util/qsgsimplematerial.cpp +++ b/src/quick/scenegraph/util/qsgsimplematerial.cpp @@ -194,19 +194,15 @@ /*! \fn const char *QSGSimpleMaterialShader::uniformMatrixName() const - Reimplement this function to give a different name to the uniform for - item transformation. The default value is \c qt_Matrix. - + Returns the name for the transform matrix uniform of this item. + The default value is \c qt_Matrix. */ /*! \fn const char *QSGSimpleMaterialShader::uniformOpacityName() const - Reimplement this function to give a different name to the uniform for - item opacity. The default value is \c qt_Opacity. - - If the shader program does not implement the item opacity, the - implemented function should return a null pointer. + Returns the name for the opacity uniform of this item. + The default value is \c qt_Opacity. */ /*! diff --git a/src/quick/scenegraph/util/qsgsimplematerial.h b/src/quick/scenegraph/util/qsgsimplematerial.h index 0e7219d7bd..b5b8815b4a 100644 --- a/src/quick/scenegraph/util/qsgsimplematerial.h +++ b/src/quick/scenegraph/util/qsgsimplematerial.h @@ -71,6 +71,7 @@ public: resolveUniforms(); } + // ### Qt 6: make both virtual and fix docs const char *uniformMatrixName() const { return "qt_Matrix"; } const char *uniformOpacityName() const { return "qt_Opacity"; } |