diff options
| author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-04-18 01:00:17 +0200 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-04-18 08:01:45 +0200 |
| commit | 934f25028a232c9bccdb842f53fa67959cc8dffc (patch) | |
| tree | a78fef6197d63feab3194eb7f4cd2e10934b18ee /src/qml | |
| parent | f8e90c61c5da4ca5e0aec24d42b2962877289ab2 (diff) | |
| parent | 2bdbf216fe7b6cf9d404b80ac405bd3969f5c07f (diff) | |
Merge remote-tracking branch 'origin/5.13' into dev
Conflicts:
src/qml/qml/qqmlimport.cpp
Change-Id: I6add6267297ea50a646d43d212027a168dca8916
Diffstat (limited to 'src/qml')
| -rw-r--r-- | src/qml/compiler/qqmlpropertycachecreator_p.h | 40 | ||||
| -rw-r--r-- | src/qml/compiler/qqmlpropertyvalidator.cpp | 5 | ||||
| -rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 8 | ||||
| -rw-r--r-- | src/qml/compiler/qv4compilercontext_p.h | 1 | ||||
| -rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions.cpp | 27 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 4 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4global_p.h | 3 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4identifiertable.cpp | 2 | ||||
| -rw-r--r-- | src/qml/jsruntime/qv4stringobject.cpp | 3 | ||||
| -rw-r--r-- | src/qml/qml/qqmlimport.cpp | 2 | ||||
| -rw-r--r-- | src/qml/qml/qqmlvaluetype.cpp | 29 |
11 files changed, 82 insertions, 42 deletions
diff --git a/src/qml/compiler/qqmlpropertycachecreator_p.h b/src/qml/compiler/qqmlpropertycachecreator_p.h index 7d416561bb..a1e93702d1 100644 --- a/src/qml/compiler/qqmlpropertycachecreator_p.h +++ b/src/qml/compiler/qqmlpropertycachecreator_p.h @@ -693,11 +693,6 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::property const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion, QQmlPropertyData::Flags *propertyFlags) { - const int targetObjectIndex = objectForId(component, alias.targetObjectId); - Q_ASSERT(targetObjectIndex >= 0); - - const CompiledObject &targetObject = *objectContainer->objectAt(targetObjectIndex); - *type = 0; bool writable = false; bool resettable = false; @@ -705,11 +700,36 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::property propertyFlags->isAlias = true; if (alias.aliasToLocalAlias) { - auto targetAlias = targetObject.aliasesBegin(); - for (uint i = 0; i < alias.localAliasIndex; ++i) - ++targetAlias; - return propertyDataForAlias(component, *targetAlias, type, minorVersion, propertyFlags); - } else if (alias.encodedMetaPropertyIndex == -1) { + const QV4::CompiledData::Alias *lastAlias = &alias; + QVarLengthArray<const QV4::CompiledData::Alias *, 4> seenAliases({lastAlias}); + + do { + const CompiledObject *targetObject = objectContainer->objectAt( + objectForId(component, lastAlias->targetObjectId)); + Q_ASSERT(targetObject); + + auto nextAlias = targetObject->aliasesBegin(); + for (uint i = 0; i < lastAlias->localAliasIndex; ++i) + ++nextAlias; + + const QV4::CompiledData::Alias *targetAlias = &(*nextAlias); + if (seenAliases.contains(targetAlias)) { + return QQmlCompileError(targetAlias->location, + QQmlPropertyCacheCreatorBase::tr("Cyclic alias")); + } + + seenAliases.append(targetAlias); + lastAlias = targetAlias; + } while (lastAlias->aliasToLocalAlias); + + return propertyDataForAlias(component, *lastAlias, type, minorVersion, propertyFlags); + } + + const int targetObjectIndex = objectForId(component, alias.targetObjectId); + Q_ASSERT(targetObjectIndex >= 0); + const CompiledObject &targetObject = *objectContainer->objectAt(targetObjectIndex); + + if (alias.encodedMetaPropertyIndex == -1) { Q_ASSERT(alias.flags & QV4::CompiledData::Alias::AliasPointsToPointerObject); auto *typeRef = objectContainer->resolvedType(targetObject.inheritedTypeNameIndex); if (!typeRef) { diff --git a/src/qml/compiler/qqmlpropertyvalidator.cpp b/src/qml/compiler/qqmlpropertyvalidator.cpp index 4714f505a7..8c06760d42 100644 --- a/src/qml/compiler/qqmlpropertyvalidator.cpp +++ b/src/qml/compiler/qqmlpropertyvalidator.cpp @@ -693,7 +693,10 @@ QQmlCompileError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData * } else if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject && property->isFunction()) { return noError; } else if (QQmlValueTypeFactory::isValueType(property->propType())) { - return QQmlCompileError(binding->location, tr("Unexpected object assignment for property \"%1\"").arg(propertyName)); + auto typeName = QMetaType::typeName(property->propType()); + return QQmlCompileError(binding->location, tr("Can not assign value of type \"%1\" to property \"%2\", expecting an object") + .arg(typeName ? QString::fromLatin1(typeName) : QString::fromLatin1("<unknown type>")) + .arg(propertyName)); } else if (property->propType() == qMetaTypeId<QQmlScriptString>()) { return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected")); } else { diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index f280994d54..a78094f17c 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -470,8 +470,10 @@ Heap::Module *CompilationUnit::instantiate(ExecutionEngine *engine) ScopedString importName(scope); const uint importCount = data->importEntryTableSize; - imports = new const Value *[importCount]; - memset(imports, 0, importCount * sizeof(Value *)); + if (importCount > 0) { + imports = new const Value *[importCount]; + memset(imports, 0, importCount * sizeof(Value *)); + } for (uint i = 0; i < importCount; ++i) { const CompiledData::ImportEntry &entry = data->importEntryTable()[i]; auto dependentModuleUnit = engine->loadModule(QUrl(stringAt(entry.moduleRequest)), this); @@ -897,6 +899,8 @@ bool ResolvedTypeReference::addToHash(QCryptographicHash *hash, QQmlEngine *engi hash->addData(createPropertyCache(engine)->checksum(&ok)); return ok; } + if (!compilationUnit) + return false; hash->addData(compilationUnit->unitData()->md5Checksum, sizeof(compilationUnit->unitData()->md5Checksum)); return true; } diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h index cb20ea9d57..57ef4be36e 100644 --- a/src/qml/compiler/qv4compilercontext_p.h +++ b/src/qml/compiler/qv4compilercontext_p.h @@ -217,7 +217,6 @@ struct Context { bool usesThis = false; bool innerFunctionAccessesThis = false; bool innerFunctionAccessesNewTarget = false; - bool hasTry = false; bool returnsClosure = false; mutable bool argumentsCanEscape = false; bool requiresExecutionContext = false; diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index 04593f202a..8984b6931e 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -741,9 +741,9 @@ void ScanFunctions::calcEscapingVariables() if (c->contextType != ContextType::ESModule) continue; for (const auto &entry: c->exportEntries) { - auto m = c->members.find(entry.localName); - if (m != c->members.end()) - m->canEscape = true; + auto mIt = c->members.constFind(entry.localName); + if (mIt != c->members.constEnd()) + mIt->canEscape = true; } break; } @@ -759,8 +759,8 @@ void ScanFunctions::calcEscapingVariables() } Q_ASSERT(c != inner); while (c) { - Context::MemberMap::const_iterator it = c->members.find(var); - if (it != c->members.end()) { + Context::MemberMap::const_iterator it = c->members.constFind(var); + if (it != c->members.constEnd()) { if (c->parent || it->isLexicallyScoped()) { it->canEscape = true; c->requiresExecutionContext = true; @@ -816,15 +816,17 @@ void ScanFunctions::calcEscapingVariables() // add an escaping 'this' variable c->addLocalVar(QStringLiteral("this"), Context::VariableDefinition, VariableScope::Let); c->requiresExecutionContext = true; - auto m = c->members.find(QStringLiteral("this")); - m->canEscape = true; + auto mIt = c->members.constFind(QStringLiteral("this")); + Q_ASSERT(mIt != c->members.constEnd()); + mIt->canEscape = true; } if (c->innerFunctionAccessesNewTarget) { // add an escaping 'new.target' variable c->addLocalVar(QStringLiteral("new.target"), Context::VariableDefinition, VariableScope::Let); c->requiresExecutionContext = true; - auto m = c->members.find(QStringLiteral("new.target")); - m->canEscape = true; + auto mIt = c->members.constFind(QStringLiteral("new.target")); + Q_ASSERT(mIt != c->members.constEnd()); + mIt->canEscape = true; } if (c->allVarsEscape && c->contextType == ContextType::Block && c->members.isEmpty()) c->allVarsEscape = false; @@ -845,8 +847,9 @@ void ScanFunctions::calcEscapingVariables() } if (c->contextType == ContextType::Block && c->isCatchBlock) { c->requiresExecutionContext = true; - auto m = c->members.find(c->caughtVariable); - m->canEscape = true; + auto mIt = c->members.constFind(c->caughtVariable); + Q_ASSERT(mIt != c->members.constEnd()); + mIt->canEscape = true; } const QLatin1String exprForOn("expression for on"); if (c->contextType == ContextType::Binding && c->name.length() > exprForOn.size() && @@ -855,7 +858,7 @@ void ScanFunctions::calcEscapingVariables() // we don't know if the code is a signal handler or not. c->requiresExecutionContext = true; if (c->allVarsEscape) { - for (auto &m : c->members) + for (const auto &m : qAsConst(c->members)) m.canEscape = true; } } diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 5bc81de472..18927c637c 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1544,6 +1544,10 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) case QMetaType::QLocale: return QQmlLocale::wrap(this, *reinterpret_cast<const QLocale*>(ptr)); #endif + case QMetaType::QPixmap: + case QMetaType::QImage: + // Scarce value types + return QV4::Encode(newVariantObject(variant)); default: break; } diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index 44adac26cd..d47393b3bb 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -94,7 +94,8 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); } #elif defined(Q_PROCESSOR_X86_64) && (QT_POINTER_SIZE == 8) \ && (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_MAC) || defined(Q_OS_FREEBSD)) # define V4_ENABLE_JIT -#elif defined(Q_PROCESSOR_ARM_32) && (QT_POINTER_SIZE == 4) +#elif defined(Q_PROCESSOR_ARM_32) && (QT_POINTER_SIZE == 4) \ + && (defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD) || defined(Q_OS_INTEGRITY)) # if defined(thumb2) || defined(__thumb2__) || ((defined(__thumb) || defined(__thumb__)) && __TARGET_ARCH_THUMB-0 == 4) # define V4_ENABLE_JIT # elif defined(__ARM_ARCH_ISA_THUMB) && __ARM_ARCH_ISA_THUMB == 2 // clang 3.5 and later will set this if the core supports the Thumb-2 ISA. diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp index 102c06d9b0..ae937b2889 100644 --- a/src/qml/jsruntime/qv4identifiertable.cpp +++ b/src/qml/jsruntime/qv4identifiertable.cpp @@ -70,7 +70,7 @@ IdentifierTable::~IdentifierTable() { free(entriesByHash); free(entriesById); - for (auto &h : idHashes) + for (const auto &h : qAsConst(idHashes)) h->identifierTable = nullptr; } diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 1c6dfe0fdb..227df4014e 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -766,9 +766,8 @@ static void appendReplacementString(QString *result, const QString &input, const i += skip; if (substStart != JSC::Yarr::offsetNoMatch && substEnd != JSC::Yarr::offsetNoMatch) *result += input.midRef(substStart, substEnd - substStart); - else { + else if (skip == 0) // invalid capture reference. Taken as literal value *result += replaceValue.at(i); - } } else { *result += replaceValue.at(i); } diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index d2d37164a7..9d5801bbc6 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -796,7 +796,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt *typeRecursionDetected = true; } else { QQmlType returnType = QQmlMetaType::typeForUrl( - qmlUrl, type, registrationType == QQmlType::CompositeSingletonType, nullptr); + qmlUrl, type, registrationType == QQmlType::CompositeSingletonType, errors); if (type_return) *type_return = returnType; return returnType.isValid(); diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index 21505754bb..f08005fd20 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -80,19 +80,26 @@ QQmlValueTypeFactoryImpl::~QQmlValueTypeFactoryImpl() bool QQmlValueTypeFactoryImpl::isValueType(int idx) { - if (idx >= (int)QVariant::UserType) { - return (valueType(idx) != nullptr); - } else if (idx >= 0 - && idx != QVariant::StringList - && idx != QMetaType::QObjectStar - && idx != QMetaType::VoidStar - && idx != QMetaType::Nullptr - && idx != QMetaType::QVariant - && idx != QMetaType::QLocale) { + if (idx >= QMetaType::User) + return valueType(idx) != nullptr; + + if (idx < 0) + return false; + + // Qt internal types + switch (idx) { + case QMetaType::QStringList: + case QMetaType::QObjectStar: + case QMetaType::VoidStar: + case QMetaType::Nullptr: + case QMetaType::QVariant: + case QMetaType::QLocale: + case QMetaType::QImage: // scarce type, keep as QVariant + case QMetaType::QPixmap: // scarce type, keep as QVariant + return false; + default: return true; } - - return false; } const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t) |
