diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/compiler/qqmlpropertycachecreator_p.h | 40 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetype.cpp | 29 |
4 files changed, 56 insertions, 23 deletions
diff --git a/src/qml/compiler/qqmlpropertycachecreator_p.h b/src/qml/compiler/qqmlpropertycachecreator_p.h index 6bee599c0a..074dc98648 100644 --- a/src/qml/compiler/qqmlpropertycachecreator_p.h +++ b/src/qml/compiler/qqmlpropertycachecreator_p.h @@ -692,11 +692,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; @@ -704,11 +699,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/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index dc5466371d..e6d079fe36 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -471,8 +471,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); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index f506e4015e..4c5e124cb0 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1547,6 +1547,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/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index e92488f9f6..6fd0f0d37c 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -81,19 +81,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) |