diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/qml/common/qv4compileddata_p.h | 52 | ||||
| -rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 2 | ||||
| -rw-r--r-- | src/qml/compiler/qqmlirbuilder_p.h | 3 | ||||
| -rw-r--r-- | src/quicktestutils/qml/qmlutils.cpp | 35 | ||||
| -rw-r--r-- | src/quicktestutils/qml/qmlutils_p.h | 54 |
5 files changed, 138 insertions, 8 deletions
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h index 01121bd008..e00e3aedd0 100644 --- a/src/qml/common/qv4compileddata_p.h +++ b/src/qml/common/qv4compileddata_p.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE // Also change the comment behind the number to describe the latest change. This has the added // benefit that if another patch changes the version too, it will result in a merge conflict, and // not get removed silently. -#define QV4_DATA_STRUCTURE_VERSION 0x48 // Hotfix 6.10 - meta object change +#define QV4_DATA_STRUCTURE_VERSION 0x49 // Added isVirtual and isOverride fields to property class QIODevice; class QQmlTypeNameCache; @@ -788,19 +788,43 @@ struct Signal }; static_assert(sizeof(Signal) == 12, "Signal structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); +/* + * We aim to minimize the size of a struct as much as possible, while preserving at least 28 bits + * for each index. + * + * Note that Name and Type indices are provided by StringTableGenerator, containing a hashmap + * (and a list) of unique strings within one Compilation Unit. It sounds rather unrealistic to have + * 2^28 (260+ million) unique strings within 1 CU (even if it's some form of global registry), not + * to mention the amount of memory needed to maintain such a StringTableGenerator. + * Therefore, after some preliminary analysis, it seems that even 20 bits + * should be a rather conservative cap. + * + * However it doesn't seem to easily provide many benefits atm other than better (logically) grouped + * unions like, let's say nameIndexAndAttributes. + * + * Atm 32-bit member nameIndexAndVirtSpecifiers looks smth like this: + * + * NameIndexField IsVirtualField IsOverrideField IsFinalField + * |10100000101000111000001110000| 0 | 1 | 0 | + * + */ struct Property { private: - using NameIndexField = quint32_le_bitfield_member<0, 31>; - using FinalField = quint32_le_bitfield_member<31, 1>; + using NameIndexField = quint32_le_bitfield_member<0, 29>; + using IsVirtualField = quint32_le_bitfield_member<29, 1>; + using IsOverrideField = quint32_le_bitfield_member<30, 1>; + using IsFinalField = quint32_le_bitfield_member<31, 1>; using CommonTypeOrTypeNameIndexField = quint32_le_bitfield_member<0, 28>; using IsRequiredField = quint32_le_bitfield_member<28, 1>; using IsCommonTypeField = 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_bitfield_union<NameIndexField, FinalField> nameIndexAndFinal; + quint32_le_bitfield_union<NameIndexField, IsVirtualField, IsOverrideField, IsFinalField> + nameIndexAndVirtSpecifiers; quint32_le_bitfield_union< CommonTypeOrTypeNameIndexField, IsRequiredField, @@ -809,11 +833,23 @@ public: IsReadOnlyField> data; Location location; - quint32 nameIndex() const { return nameIndexAndFinal.get<NameIndexField>(); } - void setNameIndex(int nameIndex) { nameIndexAndFinal.set<NameIndexField>(nameIndex); } + quint32 nameIndex() const { return nameIndexAndVirtSpecifiers.get<NameIndexField>(); } + void setNameIndex(int nameIndex) { nameIndexAndVirtSpecifiers.set<NameIndexField>(nameIndex); } + + bool isVirtual() const { return nameIndexAndVirtSpecifiers.get<IsVirtualField>(); } + void setIsVirtual(bool isVirtual) + { + nameIndexAndVirtSpecifiers.set<IsVirtualField>(isVirtual ? 1 : 0); + } + + bool isOverride() const { return nameIndexAndVirtSpecifiers.get<IsOverrideField>(); } + void setIsOverride(bool isOverride) + { + nameIndexAndVirtSpecifiers.set<IsOverrideField>(isOverride ? 1 : 0); + } - bool isFinal() const { return nameIndexAndFinal.get<FinalField>(); } - void setIsFinal(bool final) { nameIndexAndFinal.set<FinalField>(final ? 1 : 0); } + bool isFinal() const { return nameIndexAndVirtSpecifiers.get<IsFinalField>(); } + void setIsFinal(bool isFinal) { nameIndexAndVirtSpecifiers.set<IsFinalField>(isFinal ? 1 : 0); } void setCommonType(CommonType t) { diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index bf124a2272..1605ab5f59 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1045,6 +1045,8 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) Property *property = New<Property>(); property->setIsReadOnly(node->isReadonly()); property->setIsRequired(node->isRequired()); + property->setIsVirtual(node->isVirtual()); + property->setIsOverride(node->isOverride()); property->setIsFinal(node->isFinal()); const QV4::CompiledData::CommonType builtinPropertyType diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index 68b2b462f6..441830e33b 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -464,6 +464,9 @@ struct Q_QML_COMPILER_EXPORT Pragma struct Q_QML_COMPILER_EXPORT Document { + // disable it explicitly, it's implicitly deleted because of the Engine::_pool + Q_DISABLE_COPY_MOVE(Document) + Document(const QString &fileName, const QString &finalUrl, bool debugMode); QString code; QQmlJS::Engine jsParserEngine; diff --git a/src/quicktestutils/qml/qmlutils.cpp b/src/quicktestutils/qml/qmlutils.cpp index 5f573e790b..528a843f17 100644 --- a/src/quicktestutils/qml/qmlutils.cpp +++ b/src/quicktestutils/qml/qmlutils.cpp @@ -137,6 +137,41 @@ void gc(QQmlEngine &engine, GCFlags flags) gc(*engine.handle(), flags); } +namespace Syntax { + +auto stringView(const Word &word) -> QLatin1StringView +{ + return std::holds_alternative<Token>(word) ? spellFor(std::get<Token>(word)) + : std::get<QLatin1StringView>(word); +} + +auto toString(const Phrase &phrase) -> QString +{ + QString result; + for (const auto &word : phrase) { + result += stringView(word) + QLatin1Char(' '); + } + return result; +} + +// comfort +auto operator+(const Word &word, const Phrase &phrase) -> Phrase +{ + return Phrase{ word } + phrase; +}; + +auto operator+(const Word &word1, const Word &word2) -> Phrase +{ + return Phrase{ word1, word2 }; +}; + +auto objectDeclaration(Phrase &&objectMember, QLatin1StringView objName) -> Phrase +{ + return Phrase{} << Word(objName) << Word(Token::T_LBRACE) << std::move(objectMember) + << Word(Token::T_RBRACE); +} + +} // namespace Syntax QT_END_NAMESPACE diff --git a/src/quicktestutils/qml/qmlutils_p.h b/src/quicktestutils/qml/qmlutils_p.h index d8d28256ac..d4fc83c270 100644 --- a/src/quicktestutils/qml/qmlutils_p.h +++ b/src/quicktestutils/qml/qmlutils_p.h @@ -22,6 +22,7 @@ #include <QtCore/QStringList> #include <QtTest/QTest> #include <QtCore/private/qglobal_p.h> +#include <private/qqmljsgrammar_p.h> QT_BEGIN_NAMESPACE @@ -122,6 +123,59 @@ void gc(QV4::ExecutionEngine &engine, GCFlags flags = GCFlags::None); bool gcDone(QQmlEngine *engine); void gc(QQmlEngine &engine, GCFlags flags = GCFlags::None); +namespace Syntax { +using Token = QQmlJSGrammar::VariousConstants; +// TODO(QTBUG-138020) +constexpr auto spellFor(Token token) -> QLatin1StringView +{ + switch (token) { + case Token::T_COLON: + return QLatin1StringView(":"); + case Token::T_LBRACE: + return QLatin1StringView("{"); + case Token::T_RBRACE: + return QLatin1StringView("}"); + case Token::T_VAR: + return QLatin1StringView("var"); + case Token::T_PROPERTY: + return QLatin1StringView("property"); + case Token::T_DEFAULT: + return QLatin1StringView("default"); + case Token::T_READONLY: + return QLatin1StringView("readonly"); + case Token::T_REQUIRED: + return QLatin1StringView("required"); + case Token::T_FINAL: + return QLatin1StringView("final"); + case Token::T_VIRTUAL: + return QLatin1StringView("virtual"); + case Token::T_OVERRIDE: + return QLatin1StringView("override"); + default: + break; + } + Q_UNREACHABLE_RETURN({}); +} + +using Word = std::variant<Token, QLatin1StringView>; +auto stringView(const Word &word) -> QLatin1StringView; + +using Phrase = QList<Word>; +auto toString(const Phrase &phrase) -> QString; + +// comfort +auto operator+(const Word &word, const Phrase &phrase) -> Phrase; +auto operator+(const Word &word1, const Word &word2) -> Phrase; + +// if such declaration generating functions start to grow it might be worth creating a dedicated +// more optimized generator + +// can probably be generalized later to accept QList<Phrase> if needed +auto objectDeclaration(Phrase &&objectMember = {}, + QLatin1StringView objName = QLatin1StringView("QtObject")) -> Phrase; + +} // namespace Syntax + QT_END_NAMESPACE #endif // QQMLTESTUTILS_P_H |
