aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-04-18 01:00:17 +0200
committerUlf Hermann <ulf.hermann@qt.io>2019-04-18 08:01:45 +0200
commit934f25028a232c9bccdb842f53fa67959cc8dffc (patch)
treea78fef6197d63feab3194eb7f4cd2e10934b18ee /src/qml
parentf8e90c61c5da4ca5e0aec24d42b2962877289ab2 (diff)
parent2bdbf216fe7b6cf9d404b80ac405bd3969f5c07f (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.h40
-rw-r--r--src/qml/compiler/qqmlpropertyvalidator.cpp5
-rw-r--r--src/qml/compiler/qv4compileddata.cpp8
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h1
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions.cpp27
-rw-r--r--src/qml/jsruntime/qv4engine.cpp4
-rw-r--r--src/qml/jsruntime/qv4global_p.h3
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp2
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp3
-rw-r--r--src/qml/qml/qqmlimport.cpp2
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp29
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)