diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/common/qv4compileddata_p.h | 75 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycachecreator_p.h | 27 | ||||
-rw-r--r-- | src/qml/qml/qqmltypecompiler.cpp | 20 | ||||
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject.cpp | 18 |
6 files changed, 114 insertions, 50 deletions
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index fb4c13c81d..97b4d8466d 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -767,20 +767,31 @@ struct RequiredPropertyExtraData { static_assert (sizeof(RequiredPropertyExtraData) == 4, "RequiredPropertyExtraData structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); struct Alias { - enum Flags : unsigned int { +private: + using NameIndexField = quint32_le_bitfield_member<0, 29>; + using FlagsField = quint32_le_bitfield_member<29, 3>; + + // object id index (in QQmlContextData::idValues) + using TargetObjectIdField = quint32_le_bitfield_member<0, 31>; + using AliasToLocalAliasField = quint32_le_bitfield_member<31, 1>; + +public: + + enum Flag : unsigned int { IsReadOnly = 0x1, Resolved = 0x2, AliasPointsToPointerObject = 0x4 }; - union { - quint32_le_bitfield<0, 29> nameIndex; - quint32_le_bitfield<29, 3> flags; - }; + Q_DECLARE_FLAGS(Flags, Flag) + + quint32_le_bitfield_union<NameIndexField, FlagsField> nameIndexAndFlags; + union { quint32_le idIndex; // string index - quint32_le_bitfield<0, 31> targetObjectId; // object id index (in QQmlContextData::idValues) - quint32_le_bitfield<31, 1> aliasToLocalAlias; + quint32_le_bitfield_union<TargetObjectIdField, AliasToLocalAliasField> + targetObjectIdAndAliasToLocalAlias; }; + union { quint32_le propertyNameIndex; // string index qint32_le encodedMetaPropertyIndex; @@ -789,10 +800,56 @@ struct Alias { Location location; Location referenceLocation; - bool isObjectAlias() const { - Q_ASSERT(flags & Resolved); + bool hasFlag(Flag flag) const + { + return nameIndexAndFlags.get<FlagsField>() & flag; + } + + void setFlag(Flag flag) + { + nameIndexAndFlags.set<FlagsField>(nameIndexAndFlags.get<FlagsField>() | flag); + } + + void clearFlags() + { + nameIndexAndFlags.set<FlagsField>(0); + } + + quint32 nameIndex() const + { + return nameIndexAndFlags.get<NameIndexField>(); + } + + void setNameIndex(quint32 nameIndex) + { + nameIndexAndFlags.set<NameIndexField>(nameIndex); + } + + bool isObjectAlias() const + { + Q_ASSERT(hasFlag(Resolved)); return encodedMetaPropertyIndex == -1; } + + bool isAliasToLocalAlias() const + { + return targetObjectIdAndAliasToLocalAlias.get<AliasToLocalAliasField>(); + } + + void setIsAliasToLocalAlias(bool isAliasToLocalAlias) + { + targetObjectIdAndAliasToLocalAlias.set<AliasToLocalAliasField>(isAliasToLocalAlias); + } + + quint32 targetObjectId() const + { + return targetObjectIdAndAliasToLocalAlias.get<TargetObjectIdField>(); + } + + void setTargetObjectId(quint32 targetObjectId) + { + targetObjectIdAndAliasToLocalAlias.set<TargetObjectIdField>(targetObjectId); + } }; static_assert(sizeof(Alias) == 20, "Alias structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 20c6b9d290..ed5f3032d5 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -257,7 +257,7 @@ QString Object::appendProperty(Property *prop, const QString &propertyName, bool return tr("Duplicate property name"); for (Alias *a = target->aliases->first; a; a = a->next) - if (a->nameIndex == prop->nameIndex) + if (a->nameIndex() == prop->nameIndex) return tr("Property duplicates alias name"); if (propertyName.constData()->isUpper()) @@ -281,13 +281,13 @@ QString Object::appendAlias(Alias *alias, const QString &aliasName, bool isDefau target = this; const auto aliasWithSameName = std::find_if(target->aliases->begin(), target->aliases->end(), [&alias](const Alias &targetAlias){ - return targetAlias.nameIndex == alias->nameIndex; + return targetAlias.nameIndex() == alias->nameIndex(); }); if (aliasWithSameName != target->aliases->end()) return tr("Duplicate alias name"); const auto aliasSameAsProperty = std::find_if(target->properties->begin(), target->properties->end(), [&alias](const Property &targetProp){ - return targetProp.nameIndex == alias->nameIndex; + return targetProp.nameIndex == alias->nameIndex(); }); if (aliasSameAsProperty != target->properties->end()) @@ -1308,12 +1308,12 @@ void IRBuilder::appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocatio bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node) { Alias *alias = New<Alias>(); - alias->flags = 0; + alias->clearFlags(); if (node->isReadonly()) - alias->flags |= QV4::CompiledData::Alias::IsReadOnly; + alias->setFlag(QV4::CompiledData::Alias::IsReadOnly); const QString propName = node->name.toString(); - alias->nameIndex = registerString(propName); + alias->setNameIndex(registerString(propName)); QQmlJS::SourceLocation loc = node->firstSourceLocation(); alias->location.line = loc.startLine; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index a4140e8a57..cb7c15c678 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1668,12 +1668,12 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * for (int aliasIndex = 0; aliasIndex != _compiledObject->aliasCount(); ++aliasIndex) { const QV4::CompiledData::Alias* alias = _compiledObject->aliasesBegin() + aliasIndex; const auto originalAlias = alias; - while (alias->aliasToLocalAlias) + while (alias->isAliasToLocalAlias()) alias = _compiledObject->aliasesBegin() + alias->localAliasIndex; - Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved); + Q_ASSERT(alias->hasFlag(QV4::CompiledData::Alias::Resolved)); if (!context->isIdValueSet(0)) // TODO: Do we really want 0 here? continue; - QObject *target = context->idValue(alias->targetObjectId); + QObject *target = context->idValue(alias->targetObjectId()); if (!target) continue; QQmlData *targetDData = QQmlData::get(target, /*create*/false); @@ -1685,7 +1685,11 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * continue; auto it = sharedState->requiredProperties.find(targetProperty); if (it != sharedState->requiredProperties.end()) - it->aliasesToRequired.push_back(AliasToRequiredInfo {compilationUnit->stringAt(originalAlias->nameIndex), compilationUnit->finalUrl()}); + it->aliasesToRequired.push_back( + AliasToRequiredInfo { + compilationUnit->stringAt(originalAlias->nameIndex()), + compilationUnit->finalUrl() + }); } qSwap(_vmeMetaObject, vmeMetaObject); diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index f6d85f9214..044c01f203 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -496,7 +496,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int auto aend = obj->aliasesEnd(); for ( ; a != aend; ++a) { bool notInRevision = false; - QQmlPropertyData *d = resolver.property(stringAt(a->nameIndex), ¬InRevision); + QQmlPropertyData *d = resolver.property(stringAt(a->nameIndex()), ¬InRevision); if (d && d->isFinal()) return qQmlCompileError(a->location, QQmlPropertyCacheCreatorBase::tr("Cannot override FINAL property")); } @@ -544,7 +544,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int for ( ; a != aend; ++a) { auto flags = QQmlPropertyData::defaultSignalFlags(); - QString changedSigName = stringAt(a->nameIndex) + QLatin1String("Changed"); + QString changedSigName = stringAt(a->nameIndex()) + QLatin1String("Changed"); seenSignals.insert(changedSigName); cache->appendSignal(changedSigName, flags, effectiveMethodIndex++); @@ -828,12 +828,12 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertie auto alias = object.aliasesBegin(); auto end = object.aliasesEnd(); for ( ; alias != end; ++alias) { - Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved); + Q_ASSERT(alias->hasFlag(QV4::CompiledData::Alias::Resolved)); - const int targetObjectIndex = objectForId(component, alias->targetObjectId); + const int targetObjectIndex = objectForId(component, alias->targetObjectId()); Q_ASSERT(targetObjectIndex >= 0); - if (alias->aliasToLocalAlias) + if (alias->isAliasToLocalAlias()) continue; if (alias->encodedMetaPropertyIndex == -1) @@ -906,12 +906,12 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor propertyFlags->setIsAlias(true); - if (alias.aliasToLocalAlias) { + if (alias.isAliasToLocalAlias()) { const QV4::CompiledData::Alias *lastAlias = &alias; QVarLengthArray<const QV4::CompiledData::Alias *, 4> seenAliases({lastAlias}); do { - const int targetObjectIndex = objectForId(component, lastAlias->targetObjectId); + const int targetObjectIndex = objectForId(component, lastAlias->targetObjectId()); Q_ASSERT(targetObjectIndex >= 0); const CompiledObject *targetObject = objectContainer->objectAt(targetObjectIndex); Q_ASSERT(targetObject); @@ -928,17 +928,17 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor seenAliases.append(targetAlias); lastAlias = targetAlias; - } while (lastAlias->aliasToLocalAlias); + } while (lastAlias->isAliasToLocalAlias()); return propertyDataForAlias(component, *lastAlias, type, version, propertyFlags, enginePriv); } - const int targetObjectIndex = objectForId(component, alias.targetObjectId); + 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); + Q_ASSERT(alias.hasFlag(QV4::CompiledData::Alias::AliasPointsToPointerObject)); auto *typeRef = objectContainer->resolvedType(targetObject.inheritedTypeNameIndex); if (!typeRef) { // Can be caused by the alias target not being a valid id or property. E.g.: @@ -1012,7 +1012,8 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor } } - propertyFlags->setIsWritable(!(alias.flags & QV4::CompiledData::Alias::IsReadOnly) && writable); + propertyFlags->setIsWritable(!(alias.hasFlag(QV4::CompiledData::Alias::IsReadOnly)) + && writable); propertyFlags->setIsResettable(resettable); propertyFlags->setIsBindable(bindable); return QQmlError(); @@ -1036,7 +1037,7 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesTo auto alias = object.aliasesBegin(); auto end = object.aliasesEnd(); for ( ; alias != end; ++alias, ++aliasIndex) { - Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved); + Q_ASSERT(alias->hasFlag(QV4::CompiledData::Alias::Resolved)); QMetaType type; QTypeRevision version = QTypeRevision::zero(); @@ -1046,7 +1047,7 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesTo if (error.isValid()) return error; - const QString propertyName = objectContainer->stringAt(alias->nameIndex); + const QString propertyName = objectContainer->stringAt(alias->nameIndex()); if (object.hasAliasAsDefaultProperty() && aliasIndex == object.indexOfDefaultPropertyOrAlias) propertyCache->_defaultPropertyName = propertyName; diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index 34ea7db029..b633f2fb6f 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -1075,7 +1075,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex) if (!atLeastOneAliasResolved && !_objectsWithAliases.isEmpty()) { const QmlIR::Object *obj = qmlObjects->at(_objectsWithAliases.first()); for (auto alias = obj->aliasesBegin(), end = obj->aliasesEnd(); alias != end; ++alias) { - if (!(alias->flags & QV4::CompiledData::Alias::Resolved)) { + if (!alias->hasFlag(QV4::CompiledData::Alias::Resolved)) { recordError(alias->location, tr("Circular alias reference detected")); return false; } @@ -1097,7 +1097,7 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, bool seenUnresolvedAlias = false; for (QmlIR::Alias *alias = obj->firstAlias(); alias; alias = alias->next) { - if (alias->flags & QV4::CompiledData::Alias::Resolved) + if (alias->hasFlag(QV4::CompiledData::Alias::Resolved)) continue; seenUnresolvedAlias = true; @@ -1113,8 +1113,8 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, const QmlIR::Object *targetObject = qmlObjects->at(targetObjectIndex); Q_ASSERT(targetObject->id >= 0); - alias->targetObjectId = targetObject->id; - alias->aliasToLocalAlias = false; + alias->setTargetObjectId(targetObject->id); + alias->setIsAliasToLocalAlias(false); const QString aliasPropertyValue = stringAt(alias->propertyNameIndex); @@ -1131,7 +1131,7 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, QQmlPropertyIndex propIdx; if (property.isEmpty()) { - alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject; + alias->setFlag(QV4::CompiledData::Alias::AliasPointsToPointerObject); } else { QQmlPropertyCache *targetCache = propertyCaches.at(targetObjectIndex); if (!targetCache) { @@ -1150,7 +1150,7 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, bool aliasPointsToOtherAlias = false; int localAliasIndex = 0; for (auto targetAlias = targetObject->aliasesBegin(), end = targetObject->aliasesEnd(); targetAlias != end; ++targetAlias, ++localAliasIndex) { - if (stringAt(targetAlias->nameIndex) == property) { + if (stringAt(targetAlias->nameIndex()) == property) { aliasPointsToOtherAlias = true; break; } @@ -1158,8 +1158,8 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, if (aliasPointsToOtherAlias) { if (targetObjectIndex == objectIndex) { alias->localAliasIndex = localAliasIndex; - alias->aliasToLocalAlias = true; - alias->flags |= QV4::CompiledData::Alias::Resolved; + alias->setIsAliasToLocalAlias(true); + alias->setFlag(QV4::CompiledData::Alias::Resolved); ++numResolvedAliases; continue; } @@ -1221,12 +1221,12 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, } } else { if (targetProperty->isQObject()) - alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject; + alias->setFlag(QV4::CompiledData::Alias::AliasPointsToPointerObject); } } alias->encodedMetaPropertyIndex = propIdx.toEncoded(); - alias->flags |= QV4::CompiledData::Alias::Resolved; + alias->setFlag(QV4::CompiledData::Alias::Resolved); numResolvedAliases++; } diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 056ada9a8d..9988294f29 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -237,7 +237,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect() const QV4::CompiledData::Alias *aliasData = &metaObject->compiledObject->aliasTable()[aliasId]; if (!aliasData->isObjectAlias()) { QQmlRefPointer<QQmlContextData> ctxt = metaObject->ctxt; - QObject *target = ctxt->idValue(aliasData->targetObjectId); + QObject *target = ctxt->idValue(aliasData->targetObjectId()); if (!target) return; @@ -888,16 +888,18 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * if (id < aliasCount) { const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[id]; - if ((aliasData->flags & QV4::CompiledData::Alias::AliasPointsToPointerObject) && c == QMetaObject::ReadProperty) - *reinterpret_cast<void **>(a[0]) = nullptr; + if (aliasData->hasFlag(QV4::CompiledData::Alias::AliasPointsToPointerObject) + && c == QMetaObject::ReadProperty){ + *reinterpret_cast<void **>(a[0]) = nullptr; + } if (ctxt.isNull()) return -1; - while (aliasData->aliasToLocalAlias) + while (aliasData->isAliasToLocalAlias()) aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex]; - QObject *target = ctxt->idValue(aliasData->targetObjectId); + QObject *target = ctxt->idValue(aliasData->targetObjectId()); if (!target) return -1; @@ -1244,9 +1246,9 @@ bool QQmlVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex, const int aliasId = index - propOffset() - compiledObject->nProperties; const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[aliasId]; - while (aliasData->aliasToLocalAlias) + while (aliasData->isAliasToLocalAlias()) aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex]; - *target = ctxt->idValue(aliasData->targetObjectId); + *target = ctxt->idValue(aliasData->targetObjectId()); if (!*target) return false; @@ -1274,7 +1276,7 @@ void QQmlVMEMetaObject::connectAlias(int aliasId) } endpoint->metaObject = this; - endpoint->connect(ctxt->idValueBindings(aliasData->targetObjectId)); + endpoint->connect(ctxt->idValueBindings(aliasData->targetObjectId())); endpoint->tryConnect(); } |