diff options
Diffstat (limited to 'src/qml/common/qv4compileddata_p.h')
-rw-r--r-- | src/qml/common/qv4compileddata_p.h | 372 |
1 files changed, 286 insertions, 86 deletions
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index be0ca3f477..413edead2a 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -120,18 +120,35 @@ struct TableIterator struct Location { - union { - quint32 _dummy; - quint32_le_bitfield<0, 20> line; - quint32_le_bitfield<20, 12> column; - }; - - Location() : _dummy(0) { } + Location() : m_data(QSpecialIntegerBitfieldZero) {} + Location(quint32 l, quint32 c) : Location() + { + m_data.set<LineField>(l); + m_data.set<ColumnField>(c); + Q_ASSERT(m_data.get<LineField>() == l); + Q_ASSERT(m_data.get<ColumnField>() == c); + } inline bool operator<(const Location &other) const { - return line < other.line || - (line == other.line && column < other.column); + return m_data.get<LineField>() < other.m_data.get<LineField>() + || (m_data.get<LineField>() == other.m_data.get<LineField>() + && m_data.get<ColumnField>() < other.m_data.get<ColumnField>()); } + + void set(quint32 line, quint32 column) + { + m_data.set<LineField>(line); + m_data.set<ColumnField>(column); + } + + quint32 line() const { return m_data.get<LineField>(); } + quint32 column() const { return m_data.get<ColumnField>(); } + +private: + using LineField = quint32_le_bitfield_member<0, 20>; + using ColumnField = quint32_le_bitfield_member<20, 12>; + + quint32_le_bitfield_union<LineField, ColumnField> m_data; }; static_assert(sizeof(Location) == 4, "Location structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -145,13 +162,21 @@ struct RegExp RegExp_Unicode = 0x08, RegExp_Sticky = 0x10 }; - union { - quint32 _dummy; - quint32_le_bitfield<0, 5> flags; - quint32_le_bitfield<5, 27> stringIndex; - }; - RegExp() : _dummy(0) { } + RegExp() : m_data(QSpecialIntegerBitfieldZero) {} + RegExp(quint32 flags, quint32 stringIndex) : RegExp() + { + m_data.set<FlagsField>(flags); + m_data.set<StringIndexField>(stringIndex); + } + + quint32 flags() const { return m_data.get<FlagsField>(); } + quint32 stringIndex() const { return m_data.get<StringIndexField>(); } + +private: + using FlagsField = quint32_le_bitfield_member<0, 5>; + using StringIndexField = quint32_le_bitfield_member<5, 27>; + quint32_le_bitfield_union<FlagsField, StringIndexField> m_data; }; static_assert(sizeof(RegExp) == 4, "RegExp structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -164,25 +189,40 @@ struct Lookup Type_QmlContextPropertyGetter = 3 }; - union { - quint32 _dummy; - quint32_le_bitfield<0, 4> type_and_flags; - quint32_le_bitfield<4, 28> nameIndex; - }; + quint32 typeAndFlags() const { return m_data.get<TypeAndFlagsField>(); } + quint32 nameIndex() const { return m_data.get<NameIndexField>(); } - Lookup() : _dummy(0) { } + Lookup() : m_data(QSpecialIntegerBitfieldZero) {} + Lookup(Type type, quint32 nameIndex) : Lookup() + { + m_data.set<TypeAndFlagsField>(type); + m_data.set<NameIndexField>(nameIndex); + } + +private: + using TypeAndFlagsField = quint32_le_bitfield_member<0, 4>; + using NameIndexField = quint32_le_bitfield_member<4, 28>; + quint32_le_bitfield_union<TypeAndFlagsField, NameIndexField> m_data; }; static_assert(sizeof(Lookup) == 4, "Lookup structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); struct JSClassMember { - union { - quint32 _dummy; - quint32_le_bitfield<0, 31> nameOffset; - quint32_le_bitfield<31, 1> isAccessor; - }; + JSClassMember() : m_data(QSpecialIntegerBitfieldZero) {} - JSClassMember() : _dummy(0) { } + void set(quint32 nameOffset, bool isAccessor) + { + m_data.set<NameOffsetField>(nameOffset); + m_data.set<IsAccessorField>(isAccessor ? 1 : 0); + } + + quint32 nameOffset() const { return m_data.get<NameOffsetField>(); } + bool isAccessor() const { return m_data.get<IsAccessorField>() != 0; } + +private: + using NameOffsetField = quint32_le_bitfield_member<0, 31>; + using IsAccessorField = quint32_le_bitfield_member<31, 1>; + quint32_le_bitfield_union<NameOffsetField, IsAccessorField> m_data; }; static_assert(sizeof(JSClassMember) == 4, "JSClassMember structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -265,11 +305,26 @@ enum class BuiltinType : unsigned int { struct ParameterType { - union { - quint32 _dummy; - quint32_le_bitfield<0, 1> indexIsBuiltinType; - quint32_le_bitfield<1, 31> typeNameIndexOrBuiltinType; - }; + void set(bool indexIsBuiltinType, quint32 typeNameIndexOrBuiltinType) + { + m_data.set<IndexIsBuiltinTypeField>(indexIsBuiltinType ? 1 : 0); + m_data.set<TypeNameIndexOrBuiltinTypeField>(typeNameIndexOrBuiltinType); + } + + bool indexIsBuiltinType() const + { + return m_data.get<IndexIsBuiltinTypeField>() != 0; + } + + quint32 typeNameIndexOrBuiltinType() const + { + return m_data.get<TypeNameIndexOrBuiltinTypeField>(); + } + +private: + using IndexIsBuiltinTypeField = quint32_le_bitfield_member<0, 1>; + using TypeNameIndexOrBuiltinTypeField = quint32_le_bitfield_member<1, 31>; + quint32_le_bitfield_union<IndexIsBuiltinTypeField, TypeNameIndexOrBuiltinTypeField> m_data; }; static_assert(sizeof(ParameterType) == 4, "ParameterType structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -448,7 +503,7 @@ struct Binding { quint32_le propertyNameIndex; - enum ValueType : unsigned int { + enum Type : unsigned int { Type_Invalid, Type_Boolean, Type_Number, @@ -462,7 +517,7 @@ struct Binding Type_GroupProperty }; - enum Flags : unsigned int { + enum Flag : unsigned int { IsSignalHandlerExpression = 0x1, IsSignalHandlerObject = 0x2, IsOnAssignment = 0x4, @@ -474,11 +529,20 @@ struct Binding IsCustomParserBinding = 0x100, IsFunctionExpression = 0x200 }; + Q_DECLARE_FLAGS(Flags, Flag); + + using FlagsField = quint32_le_bitfield_member<0, 16>; + using TypeField = quint32_le_bitfield_member<16, 16>; + quint32_le_bitfield_union<FlagsField, TypeField> flagsAndType; + + void clearFlags() { flagsAndType.set<FlagsField>(0); } + void setFlag(Flag flag) { flagsAndType.set<FlagsField>(flagsAndType.get<FlagsField>() | flag); } + bool hasFlag(Flag flag) const { return Flags(flagsAndType.get<FlagsField>()) & flag; } + Flags flags() const { return Flags(flagsAndType.get<FlagsField>()); } + + void setType(Type type) { flagsAndType.set<TypeField>(type); } + Type type() const { return Type(flagsAndType.get<TypeField>()); } - union { - quint32_le_bitfield<0, 16> flags; - quint32_le_bitfield<16, 16> type; - }; union { bool b; quint32_le constantValueIndex; @@ -492,23 +556,29 @@ struct Binding Location location; Location valueLocation; + bool hasSignalHandlerBindingFlag() const + { + const Flags bindingFlags = flags(); + return (bindingFlags & IsSignalHandlerExpression || bindingFlags & IsSignalHandlerObject); + } + bool isValueBinding() const { - if (type == Type_AttachedProperty - || type == Type_GroupProperty) + switch (type()) { + case Type_AttachedProperty: + case Type_GroupProperty: return false; - if (flags & IsSignalHandlerExpression - || flags & IsSignalHandlerObject) - return false; - return true; + default: + return !hasSignalHandlerBindingFlag(); + } } - bool isValueBindingNoAlias() const { return isValueBinding() && !(flags & IsBindingToAlias); } - bool isValueBindingToAlias() const { return isValueBinding() && (flags & IsBindingToAlias); } + bool isValueBindingNoAlias() const { return isValueBinding() && !hasFlag(IsBindingToAlias); } + bool isValueBindingToAlias() const { return isValueBinding() && hasFlag(IsBindingToAlias); } bool isSignalHandler() const { - if (flags & IsSignalHandlerExpression || flags & IsSignalHandlerObject) { + if (hasSignalHandlerBindingFlag()) { Q_ASSERT(!isValueBinding()); Q_ASSERT(!isAttachedProperty()); Q_ASSERT(!isGroupProperty()); @@ -519,7 +589,7 @@ struct Binding bool isAttachedProperty() const { - if (type == Type_AttachedProperty) { + if (type() == Type_AttachedProperty) { Q_ASSERT(!isValueBinding()); Q_ASSERT(!isSignalHandler()); Q_ASSERT(!isGroupProperty()); @@ -530,7 +600,7 @@ struct Binding bool isGroupProperty() const { - if (type == Type_GroupProperty) { + if (type() == Type_GroupProperty) { Q_ASSERT(!isValueBinding()); Q_ASSERT(!isSignalHandler()); Q_ASSERT(!isAttachedProperty()); @@ -539,7 +609,7 @@ struct Binding return false; } - bool isFunctionExpression() const { return (flags & IsFunctionExpression); } + bool isFunctionExpression() const { return hasFlag(IsFunctionExpression); } //reverse of Lexer::singleEscape() static QString escapedString(const QString &string) @@ -584,16 +654,19 @@ struct Binding return tmp; } - bool isTranslationBinding() const { return type == Type_Translation || type == Type_TranslationById; } - bool evaluatesToString() const { return type == Type_String || isTranslationBinding(); } + bool isTranslationBinding() const + { + const Binding::Type bindingType = type(); + return bindingType == Type_Translation || bindingType == Type_TranslationById; + } + bool evaluatesToString() const { return type() == Type_String || isTranslationBinding(); } bool valueAsBoolean() const { - if (type == Type_Boolean) + if (type() == Type_Boolean) return value.b; return false; } - }; static_assert(sizeof(Binding) == 24, "Binding structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -666,32 +739,57 @@ static_assert(sizeof(Signal) == 12, "Signal structure needs to have the expected struct Property { - quint32_le nameIndex; - union { - quint32_le_bitfield<0, 28> builtinTypeOrTypeNameIndex; - quint32_le_bitfield<28, 1> isRequired; - quint32_le_bitfield<29, 1> isBuiltinType; - quint32_le_bitfield<30, 1> isList; - quint32_le_bitfield<31, 1> isReadOnly; - }; +private: + using BuiltinTypeOrTypeNameIndexField = quint32_le_bitfield_member<0, 28>; + using IsRequiredField = quint32_le_bitfield_member<28, 1>; + using IsBuiltinTypeField = quint32_le_bitfield_member<29, 1>; + using IsListField = quint32_le_bitfield_member<30, 1>; + using IsReadOnlyField = quint32_le_bitfield_member<31, 1>; +public: + quint32_le nameIndex; + quint32_le_bitfield_union< + BuiltinTypeOrTypeNameIndexField, + IsRequiredField, + IsBuiltinTypeField, + IsListField, + IsReadOnlyField> data; Location location; void setBuiltinType(BuiltinType t) { - builtinTypeOrTypeNameIndex = static_cast<quint32>(t); - isBuiltinType = true; + data.set<BuiltinTypeOrTypeNameIndexField>(static_cast<quint32>(t)); + data.set<IsBuiltinTypeField>(true); } + BuiltinType builtinType() const { - if (isBuiltinType) - return static_cast<BuiltinType>(quint32(builtinTypeOrTypeNameIndex)); + if (data.get<IsBuiltinTypeField>() != 0) + return BuiltinType(data.get<BuiltinTypeOrTypeNameIndexField>()); return BuiltinType::InvalidBuiltin; } + void setCustomType(int nameIndex) { - builtinTypeOrTypeNameIndex = nameIndex; - isBuiltinType = false; + data.set<BuiltinTypeOrTypeNameIndexField>(nameIndex); + data.set<IsBuiltinTypeField>(false); } + + int customType() const + { + return data.get<IsBuiltinTypeField>() ? -1 : data.get<BuiltinTypeOrTypeNameIndexField>(); + } + + bool isBuiltinType() const { return data.get<IsBuiltinTypeField>(); } + uint builtinTypeOrTypeNameIndex() const { return data.get<BuiltinTypeOrTypeNameIndexField>(); } + + bool isList() const { return data.get<IsListField>(); } + void setIsList(bool isList) { data.set<IsListField>(isList); } + + bool isRequired() const { return data.get<IsRequiredField>(); } + void setIsRequired(bool isRequired) { data.set<IsRequiredField>(isRequired); } + + bool isReadOnly() const { return data.get<IsReadOnlyField>(); } + void setIsReadOnly(bool isReadOnly) { data.set<IsReadOnlyField>(isReadOnly); } }; static_assert(sizeof(Property) == 12, "Property structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); @@ -702,20 +800,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; @@ -724,16 +833,67 @@ 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"); struct Object { - enum Flags : unsigned int { +private: + using FlagsField = quint32_le_bitfield_member<0, 15>; + using DefaultPropertyIsAliasField = quint32_le_bitfield_member<15, 1>; + using IdField = quint32_le_bitfield_member<16, 16, qint32>; +public: + enum Flag : unsigned int { NoFlag = 0x0, IsComponent = 0x1, // object was identified to be an explicit or implicit component boundary HasDeferredBindings = 0x2, // any of the bindings are deferred @@ -741,17 +901,15 @@ struct Object IsInlineComponentRoot = 0x8, InPartOfInlineComponent = 0x10 }; + Q_DECLARE_FLAGS(Flags, Flag); // Depending on the use, this may be the type name to instantiate before instantiating this // object. For grouped properties the type name will be empty and for attached properties // it will be the name of the attached type. quint32_le inheritedTypeNameIndex; quint32_le idNameIndex; - union { - quint32_le_bitfield<0, 15> flags; - quint32_le_bitfield<15, 1> defaultPropertyIsAlias; - qint32_le_bitfield<16, 16> id; - }; + quint32_le_bitfield_union<FlagsField, DefaultPropertyIsAliasField, IdField> + flagsAndDefaultPropertyIsAliasAndId; qint32_le indexOfDefaultPropertyOrAlias; // -1 means no default property declared in this object quint16_le nFunctions; quint16_le nProperties; @@ -780,6 +938,48 @@ struct Object // InlineComponent[] // RequiredPropertyExtraData[] + Flags flags() const + { + return Flags(flagsAndDefaultPropertyIsAliasAndId.get<FlagsField>()); + } + + bool hasFlag(Flag flag) const + { + return flagsAndDefaultPropertyIsAliasAndId.get<FlagsField>() & flag; + } + + void setFlag(Flag flag) + { + flagsAndDefaultPropertyIsAliasAndId.set<FlagsField>( + flagsAndDefaultPropertyIsAliasAndId.get<FlagsField>() | flag); + } + + void setFlags(Flags flags) + { + flagsAndDefaultPropertyIsAliasAndId.set<FlagsField>(flags); + } + + bool hasAliasAsDefaultProperty() const + { + return flagsAndDefaultPropertyIsAliasAndId.get<DefaultPropertyIsAliasField>(); + } + + void setHasAliasAsDefaultProperty(bool defaultAlias) + { + flagsAndDefaultPropertyIsAliasAndId.set<DefaultPropertyIsAliasField>(defaultAlias); + } + + qint32 objectId() const + { + return flagsAndDefaultPropertyIsAliasAndId.get<IdField>(); + } + + void setObjectId(qint32 id) + { + flagsAndDefaultPropertyIsAliasAndId.set<IdField>(id); + } + + static int calculateSizeExcludingSignalsAndEnums(int nFunctions, int nProperties, int nAliases, int nEnums, int nSignals, int nBindings, int nNamedObjectsInComponent, int nInlineComponents, int nRequiredPropertyExtraData) { return ( sizeof(Object) @@ -1129,8 +1329,8 @@ struct TypeReferenceMap : QHash<int, TypeReference> auto prop = obj->propertiesBegin(); auto const propEnd = obj->propertiesEnd(); for ( ; prop != propEnd; ++prop) { - if (!prop->isBuiltinType) { - TypeReference &r = this->add(prop->builtinTypeOrTypeNameIndex, prop->location); + if (!prop->isBuiltinType()) { + TypeReference &r = this->add(prop->builtinTypeOrTypeNameIndex(), prop->location); r.errorWhenNotFound = true; } } @@ -1138,7 +1338,7 @@ struct TypeReferenceMap : QHash<int, TypeReference> auto binding = obj->bindingsBegin(); auto const bindingEnd = obj->bindingsEnd(); for ( ; binding != bindingEnd; ++binding) { - if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) + if (binding->type() == QV4::CompiledData::Binding::Type_AttachedProperty) this->add(binding->propertyNameIndex, binding->location); } |