aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/common/qv4compileddata_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/common/qv4compileddata_p.h')
-rw-r--r--src/qml/common/qv4compileddata_p.h472
1 files changed, 325 insertions, 147 deletions
diff --git a/src/qml/common/qv4compileddata_p.h b/src/qml/common/qv4compileddata_p.h
index cd96067769..c21fc19fa9 100644
--- a/src/qml/common/qv4compileddata_p.h
+++ b/src/qml/common/qv4compileddata_p.h
@@ -16,21 +16,29 @@
#include <functional>
+#include <QtCore/qcryptographichash.h>
+#include <QtCore/qhash.h>
#include <QtCore/qhashfunctions.h>
-#include <QtCore/qstring.h>
+#include <QtCore/qlocale.h>
#include <QtCore/qscopeguard.h>
-#include <QtCore/qvector.h>
+#include <QtCore/qstring.h>
#include <QtCore/qstringlist.h>
-#include <QtCore/qhash.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qvector.h>
#include <QtCore/qversionnumber.h>
-#include <QtCore/qlocale.h>
#if QT_CONFIG(temporaryfile)
#include <QtCore/qsavefile.h>
#endif
#include <private/qendian_p.h>
+#include <private/qqmlnullablevalue_p.h>
+#include <private/qqmlpropertycachevector_p.h>
+#include <private/qqmlrefcount_p.h>
+#include <private/qqmltype_p.h>
+#include <private/qv4compilationunitmapper_p.h>
#include <private/qv4staticvalue_p.h>
+
#include <functional>
#include <limits.h>
@@ -43,15 +51,17 @@ 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 0x3B // Add isList flag to method parameters and return types
+#define QV4_DATA_STRUCTURE_VERSION 0x42 // Change metatype computation of AOT-compiled functions
class QIODevice;
class QQmlTypeNameCache;
class QQmlType;
class QQmlEngine;
+class QQmlPropertyData;
+class QQmlScriptData;
namespace QQmlPrivate {
-struct TypedFunction;
+struct AOTCompiledFunction;
}
namespace QmlIR {
@@ -67,9 +77,19 @@ struct InternalClass;
struct Function;
class EvalISelFactory;
+class ResolvedTypeReference;
namespace CompiledData {
+// index is per-object binding index
+using BindingPropertyData = QVector<const QQmlPropertyData *>;
+
+// map from name index
+struct ResolvedTypeReferenceMap: public QHash<int, ResolvedTypeReference*>
+{
+ bool addToHash(QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums) const;
+};
+
struct String;
struct Function;
struct Lookup;
@@ -141,8 +161,8 @@ struct RegExp
RegExp_Global = 0x01,
RegExp_IgnoreCase = 0x02,
RegExp_Multiline = 0x04,
- RegExp_Unicode = 0x08,
- RegExp_Sticky = 0x10
+ RegExp_Sticky = 0x08,
+ RegExp_Unicode = 0x10,
};
RegExp() : m_data(QSpecialIntegerBitfieldZero) {}
@@ -268,31 +288,48 @@ struct Block
};
static_assert(sizeof(Block) == 12, "Block structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
-enum class BuiltinType : unsigned int {
- Var = 0, Int, Bool, Real, String, Url,
- Time, Date, DateTime, Rect, Point, Size,
- InvalidBuiltin
+enum class NamedBuiltin: unsigned int {
+ Void, Var, Int, Bool, Real, String, Url, DateTime, RegExp
+};
+
+enum class CommonType : unsigned int {
+ // Actual named builtins
+ Void = uint(NamedBuiltin::Void),
+ Var = uint(NamedBuiltin::Var),
+ Int = uint(NamedBuiltin::Int),
+ Bool = uint(NamedBuiltin::Bool),
+ Real = uint(NamedBuiltin::Real),
+ String = uint(NamedBuiltin::String),
+ Url = uint(NamedBuiltin::Url),
+ DateTime = uint(NamedBuiltin::DateTime),
+ RegExp = uint(NamedBuiltin::RegExp),
+
+ // Optimization for very common other types
+ Time, Date, Rect, Point, Size,
+
+ // No type specified or not recognized
+ Invalid
};
struct ParameterType
{
enum Flag {
NoFlag = 0x0,
- Builtin = 0x1,
+ Common = 0x1,
List = 0x2,
};
Q_DECLARE_FLAGS(Flags, Flag);
- void set(Flags flags, quint32 typeNameIndexOrBuiltinType)
+ void set(Flags flags, quint32 typeNameIndexOrCommonType)
{
m_data.set<IsListField>(flags.testFlag(List) ? 1 : 0);
- m_data.set<IndexIsBuiltinTypeField>(flags.testFlag(Builtin) ? 1 : 0);
- m_data.set<TypeNameIndexOrBuiltinTypeField>(typeNameIndexOrBuiltinType);
+ m_data.set<IndexIsCommonTypeField>(flags.testFlag(Common) ? 1 : 0);
+ m_data.set<TypeNameIndexOrCommonTypeField>(typeNameIndexOrCommonType);
}
- bool indexIsBuiltinType() const
+ bool indexIsCommonType() const
{
- return m_data.get<IndexIsBuiltinTypeField>() != 0;
+ return m_data.get<IndexIsCommonTypeField>() != 0;
}
bool isList() const
@@ -300,16 +337,16 @@ struct ParameterType
return m_data.get<IsListField>() != 0;
}
- quint32 typeNameIndexOrBuiltinType() const
+ quint32 typeNameIndexOrCommonType() const
{
- return m_data.get<TypeNameIndexOrBuiltinTypeField>();
+ return m_data.get<TypeNameIndexOrCommonTypeField>();
}
private:
- using IndexIsBuiltinTypeField = quint32_le_bitfield_member<0, 1>;
+ using IndexIsCommonTypeField = quint32_le_bitfield_member<0, 1>;
using IsListField = quint32_le_bitfield_member<1, 1>;
- using TypeNameIndexOrBuiltinTypeField = quint32_le_bitfield_member<2, 30>;
- quint32_le_bitfield_union<IndexIsBuiltinTypeField, IsListField, TypeNameIndexOrBuiltinTypeField> m_data;
+ using TypeNameIndexOrCommonTypeField = quint32_le_bitfield_member<2, 30>;
+ quint32_le_bitfield_union<IndexIsCommonTypeField, IsListField, TypeNameIndexOrCommonTypeField> 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");
@@ -497,6 +534,7 @@ static_assert(sizeof(ImportEntry) == 16, "ImportEntry structure needs to have th
struct TranslationData
{
+ enum { NoContextIndex = std::numeric_limits<quint32>::max() };
quint32_le stringIndex;
quint32_le commentIndex;
qint32_le number;
@@ -669,6 +707,8 @@ struct Binding
}
bool evaluatesToString() const { return type() == Type_String || isTranslationBinding(); }
+ bool isNumberBinding() const { return type() == Type_Number; }
+
bool valueAsBoolean() const
{
if (type() == Type_Boolean)
@@ -748,47 +788,47 @@ static_assert(sizeof(Signal) == 12, "Signal structure needs to have the expected
struct Property
{
private:
- using BuiltinTypeOrTypeNameIndexField = quint32_le_bitfield_member<0, 28>;
+ using CommonTypeOrTypeNameIndexField = quint32_le_bitfield_member<0, 28>;
using IsRequiredField = quint32_le_bitfield_member<28, 1>;
- using IsBuiltinTypeField = quint32_le_bitfield_member<29, 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 nameIndex;
quint32_le_bitfield_union<
- BuiltinTypeOrTypeNameIndexField,
+ CommonTypeOrTypeNameIndexField,
IsRequiredField,
- IsBuiltinTypeField,
+ IsCommonTypeField,
IsListField,
IsReadOnlyField> data;
Location location;
- void setBuiltinType(BuiltinType t)
+ void setCommonType(CommonType t)
{
- data.set<BuiltinTypeOrTypeNameIndexField>(static_cast<quint32>(t));
- data.set<IsBuiltinTypeField>(true);
+ data.set<CommonTypeOrTypeNameIndexField>(static_cast<quint32>(t));
+ data.set<IsCommonTypeField>(true);
}
- BuiltinType builtinType() const {
- if (data.get<IsBuiltinTypeField>() != 0)
- return BuiltinType(data.get<BuiltinTypeOrTypeNameIndexField>());
- return BuiltinType::InvalidBuiltin;
+ CommonType commonType() const {
+ if (data.get<IsCommonTypeField>() != 0)
+ return CommonType(data.get<CommonTypeOrTypeNameIndexField>());
+ return CommonType::Invalid;
}
- void setCustomType(int nameIndex)
+ void setTypeNameIndex(int nameIndex)
{
- data.set<BuiltinTypeOrTypeNameIndexField>(nameIndex);
- data.set<IsBuiltinTypeField>(false);
+ data.set<CommonTypeOrTypeNameIndexField>(nameIndex);
+ data.set<IsCommonTypeField>(false);
}
- int customType() const
+ int typeNameIndex() const
{
- return data.get<IsBuiltinTypeField>() ? -1 : data.get<BuiltinTypeOrTypeNameIndexField>();
+ return data.get<IsCommonTypeField>() ? -1 : data.get<CommonTypeOrTypeNameIndexField>();
}
- bool isBuiltinType() const { return data.get<IsBuiltinTypeField>(); }
- uint builtinTypeOrTypeNameIndex() const { return data.get<BuiltinTypeOrTypeNameIndexField>(); }
+ bool isCommonType() const { return data.get<IsCommonTypeField>(); }
+ uint commonTypeOrTypeNameIndex() const { return data.get<CommonTypeOrTypeNameIndexField>(); }
bool isList() const { return data.get<IsListField>(); }
void setIsList(bool isList) { data.set<IsListField>(isList); }
@@ -1080,6 +1120,7 @@ public:
const Binding *bindingsBegin() const { return bindingTable(); }
const Binding *bindingsEnd() const { return bindingTable() + nBindings; }
+ int bindingCount() const { return nBindings; }
const Property *propertiesBegin() const { return propertyTable(); }
const Property *propertiesEnd() const { return propertyTable() + nProperties; }
@@ -1182,9 +1223,11 @@ struct Unit
ListPropertyAssignReplace
= ListPropertyAssignReplaceIfDefault | ListPropertyAssignReplaceIfNotDefault,
ComponentsBound = 0x200,
- FunctionSignaturesEnforced = 0x400,
+ FunctionSignaturesIgnored = 0x400,
NativeMethodsAcceptThisObject = 0x800,
ValueTypesCopied = 0x1000,
+ ValueTypesAddressable = 0x2000,
+ ValueTypesAssertable = 0x4000,
};
quint32_le flags;
quint32_le stringTableSize;
@@ -1238,8 +1281,8 @@ struct Unit
}
/* end QML specific fields*/
- QString stringAtInternal(int idx) const {
- Q_ASSERT(idx < int(stringTableSize));
+ QString stringAtInternal(uint idx) const {
+ Q_ASSERT(idx < stringTableSize);
const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToStringTable);
const quint32_le offset = offsetTable[idx];
const String *str = reinterpret_cast<const String*>(reinterpret_cast<const char *>(this) + offset);
@@ -1311,12 +1354,28 @@ struct Unit
return reinterpret_cast<const TranslationData *>(reinterpret_cast<const char *>(this) + offsetToTranslationTable);
}
+ const quint32_le *translationContextIndex() const{
+ if ( translationTableSize == 0)
+ return nullptr;
+ return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this))
+ + offsetToTranslationTable
+ + translationTableSize * sizeof(CompiledData::TranslationData)); }
+
+ quint32_le *translationContextIndex() {
+ if ( translationTableSize == 0)
+ return nullptr;
+ return reinterpret_cast<quint32_le*>((reinterpret_cast<char *>(this))
+ + offsetToTranslationTable
+ + translationTableSize * sizeof(CompiledData::TranslationData)); }
+
const ImportEntry *importEntryTable() const { return reinterpret_cast<const ImportEntry *>(reinterpret_cast<const char *>(this) + offsetToImportEntryTable); }
const ExportEntry *localExportEntryTable() const { return reinterpret_cast<const ExportEntry *>(reinterpret_cast<const char *>(this) + offsetToLocalExportEntryTable); }
const ExportEntry *indirectExportEntryTable() const { return reinterpret_cast<const ExportEntry *>(reinterpret_cast<const char *>(this) + offsetToIndirectExportEntryTable); }
const ExportEntry *starExportEntryTable() const { return reinterpret_cast<const ExportEntry *>(reinterpret_cast<const char *>(this) + offsetToStarExportEntryTable); }
const quint32_le *moduleRequestTable() const { return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToModuleRequestTable); }
+
+ bool verifyHeader(QDateTime expectedSourceTimeStamp, QString *errorString) const;
};
static_assert(sizeof(Unit) == 248, "Unit structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
@@ -1355,8 +1414,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->isCommonType()) {
+ TypeReference &r = this->add(prop->commonTypeOrTypeNameIndex(), prop->location);
r.errorWhenNotFound = true;
}
}
@@ -1385,118 +1444,92 @@ struct TypeReferenceMap : QHash<int, TypeReference>
using DependentTypesHasher = std::function<QByteArray()>;
-// This is how this hooks into the existing structures:
-
-struct CompilationUnitBase
-{
- Q_DISABLE_COPY(CompilationUnitBase)
-
- CompilationUnitBase() = default;
- ~CompilationUnitBase() = default;
-
- CompilationUnitBase(CompilationUnitBase &&other) noexcept { *this = std::move(other); }
-
- CompilationUnitBase &operator=(CompilationUnitBase &&other) noexcept
- {
- if (this != &other) {
- runtimeStrings = other.runtimeStrings;
- other.runtimeStrings = nullptr;
- constants = other.constants;
- other.constants = nullptr;
- runtimeRegularExpressions = other.runtimeRegularExpressions;
- other.runtimeRegularExpressions = nullptr;
- runtimeClasses = other.runtimeClasses;
- other.runtimeClasses = nullptr;
- imports = other.imports;
- other.imports = nullptr;
- }
- return *this;
- }
+struct InlineComponentData {
+
+ InlineComponentData() = default;
+ InlineComponentData(
+ const QQmlType &qmlType, int objectIndex, int nameIndex, int totalObjectCount,
+ int totalBindingCount, int totalParserStatusCount)
+ : qmlType(qmlType)
+ , objectIndex(objectIndex)
+ , nameIndex(nameIndex)
+ , totalObjectCount(totalObjectCount)
+ , totalBindingCount(totalBindingCount)
+ , totalParserStatusCount(totalParserStatusCount)
+ {}
- // pointers either to data->constants() or little-endian memory copy.
- Heap::String **runtimeStrings = nullptr; // Array
- const StaticValue* constants = nullptr;
- QV4::StaticValue *runtimeRegularExpressions = nullptr;
- Heap::InternalClass **runtimeClasses = nullptr;
- const StaticValue** imports = nullptr;
+ QQmlType qmlType;
+ int objectIndex = -1;
+ int nameIndex = -1;
+ int totalObjectCount = 0;
+ int totalBindingCount = 0;
+ int totalParserStatusCount = 0;
};
-Q_STATIC_ASSERT(std::is_standard_layout<CompilationUnitBase>::value);
-Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeStrings) == 0);
-Q_STATIC_ASSERT(offsetof(CompilationUnitBase, constants) == sizeof(QV4::Heap::String **));
-Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeRegularExpressions) == offsetof(CompilationUnitBase, constants) + sizeof(const StaticValue *));
-Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeClasses) == offsetof(CompilationUnitBase, runtimeRegularExpressions) + sizeof(const StaticValue *));
-Q_STATIC_ASSERT(offsetof(CompilationUnitBase, imports) == offsetof(CompilationUnitBase, runtimeClasses) + sizeof(const StaticValue *));
-
-struct CompilationUnit : public CompilationUnitBase
+struct CompilationUnit final : public QQmlRefCounted<CompilationUnit>
{
- Q_DISABLE_COPY(CompilationUnit)
+ Q_DISABLE_COPY_MOVE(CompilationUnit)
const Unit *data = nullptr;
const QmlUnit *qmlData = nullptr;
QStringList dynamicStrings;
- const QQmlPrivate::TypedFunction *aotCompiledFunctions = nullptr;
+ const QQmlPrivate::AOTCompiledFunction *aotCompiledFunctions = nullptr;
+
+ // pointers either to data->constants() or little-endian memory copy.
+ const StaticValue *constants = nullptr;
+
+ std::unique_ptr<CompilationUnitMapper> backingFile;
+
+ int m_totalBindingsCount = 0; // Number of bindings used in this type
+ int m_totalParserStatusCount = 0; // Number of instantiated types that are QQmlParserStatus subclasses
+ int m_totalObjectCount = 0; // Number of objects explicitly instantiated
+
+ std::unique_ptr<QString> icRootName;
+ QHash<QString, InlineComponentData> inlineComponentData;
+
+ // index is object index. This allows fast access to the
+ // property data when initializing bindings, avoiding expensive
+ // lookups by string (property name).
+ QVector<BindingPropertyData> bindingPropertyDataPerObject;
+
+ ResolvedTypeReferenceMap resolvedTypes;
+ QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
+
+ QQmlPropertyCacheVector propertyCaches;
+
+ QQmlType qmlType;
+
+ QVector<QQmlRefPointer<QQmlScriptData>> dependentScripts;
+
public:
- using CompiledObject = CompiledData::Object;
+ // --- interface for QQmlPropertyCacheCreator
+ using CompiledObject = const CompiledData::Object;
+ using CompiledFunction = const CompiledData::Function;
+ using CompiledBinding = const CompiledData::Binding;
- CompilationUnit(const Unit *unitData = nullptr, const QString &fileName = QString(),
- const QString &finalUrlString = QString())
+ // Empty dummy. We don't need to do this when loading from cache.
+ class IdToObjectMap
{
- setUnitData(unitData, nullptr, fileName, finalUrlString);
- }
+ public:
+ void insert(int, int) {}
+ void clear() {}
- explicit CompilationUnit(const Unit *unitData, const QQmlPrivate::TypedFunction *aotCompiledFunctions,
+ // We have already checked uniqueness of IDs when creating the CU
+ bool contains(int) { return false; }
+ };
+
+ explicit CompilationUnit(const Unit *unitData, const QQmlPrivate::AOTCompiledFunction *aotCompiledFunctions,
const QString &fileName = QString(), const QString &finalUrlString = QString())
: CompilationUnit(unitData, fileName, finalUrlString)
{
this->aotCompiledFunctions = aotCompiledFunctions;
}
- ~CompilationUnit()
- {
- if (data) {
- if (data->qmlUnit() != qmlData)
- free(const_cast<QmlUnit *>(qmlData));
- qmlData = nullptr;
-
- if (!(data->flags & QV4::CompiledData::Unit::StaticData))
- free(const_cast<Unit *>(data));
- }
- data = nullptr;
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- delete [] constants;
- constants = nullptr;
-#endif
-
- delete [] imports;
- imports = nullptr;
- }
-
- CompilationUnit(CompilationUnit &&other) noexcept
- {
- *this = std::move(other);
- }
+ Q_QML_EXPORT CompilationUnit(
+ const Unit *unitData = nullptr, const QString &fileName = QString(),
+ const QString &finalUrlString = QString());
- CompilationUnit &operator=(CompilationUnit &&other) noexcept
- {
- if (this != &other) {
- data = other.data;
- other.data = nullptr;
- qmlData = other.qmlData;
- other.qmlData = nullptr;
- dynamicStrings = std::move(other.dynamicStrings);
- aotCompiledFunctions = other.aotCompiledFunctions;
- other.dynamicStrings.clear();
- m_fileName = std::move(other.m_fileName);
- other.m_fileName.clear();
- m_finalUrlString = std::move(other.m_finalUrlString);
- other.m_finalUrlString.clear();
- m_module = other.m_module;
- other.m_module = nullptr;
- CompilationUnitBase::operator=(std::move(other));
- }
- return *this;
- }
+ Q_QML_EXPORT ~CompilationUnit();
const Unit *unitData() const { return data; }
@@ -1530,19 +1563,19 @@ public:
m_finalUrlString = !finalUrlString.isEmpty() ? finalUrlString : stringAt(data->finalUrlIndex);
}
- QString stringAt(int index) const
+ QString stringAt(uint index) const
{
- if (uint(index) >= data->stringTableSize)
- return dynamicStrings.at(index - data->stringTableSize);
- return data->stringAtInternal(index);
+ if (index < data->stringTableSize)
+ return data->stringAtInternal(index);
+
+ const qsizetype dynamicIndex = index - data->stringTableSize;
+ Q_ASSERT(dynamicIndex < dynamicStrings.size());
+ return dynamicStrings.at(dynamicIndex);
}
QString fileName() const { return m_fileName; }
QString finalUrlString() const { return m_finalUrlString; }
- Heap::Module *module() const { return m_module; }
- void setModule(Heap::Module *module) { m_module = module; }
-
QString bindingValueAsString(const CompiledData::Binding *binding) const
{
using namespace CompiledData;
@@ -1581,11 +1614,156 @@ public:
return constants[binding->value.constantValueIndex].doubleValue();
}
+ Q_QML_EXPORT static QString localCacheFilePath(const QUrl &url);
+ Q_QML_EXPORT bool loadFromDisk(
+ const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString);
+ Q_QML_EXPORT bool saveToDisk(const QUrl &unitUrl, QString *errorString);
+
+ int importCount() const { return qmlData->nImports; }
+ const CompiledData::Import *importAt(int index) const { return qmlData->importAt(index); }
+
+ Q_QML_EXPORT QStringList moduleRequests() const;
+
+ // url() and fileName() shall be used to load the actual QML/JS code or to show errors or
+ // warnings about that code. They include any potential URL interceptions and thus represent the
+ // "physical" location of the code.
+ //
+ // finalUrl() and finalUrlString() shall be used to resolve further URLs referred to in the code
+ // They are _not_ intercepted and thus represent the "logical" name for the code.
+
+ QUrl url() const
+ {
+ if (!m_url.isValid())
+ m_url = QUrl(fileName());
+ return m_url;
+ }
+
+ QUrl finalUrl() const
+ {
+ if (!m_finalUrl.isValid())
+ m_finalUrl = QUrl(finalUrlString());
+ return m_finalUrl;
+ }
+
+ ResolvedTypeReference *resolvedType(int id) const { return resolvedTypes.value(id); }
+ ResolvedTypeReference *resolvedType(QMetaType type) const;
+
+ QQmlPropertyCache::ConstPtr rootPropertyCache() const
+ {
+ return propertyCaches.at(/*root object*/0);
+ }
+
+ int objectCount() const { return qmlData->nObjects; }
+ const CompiledObject *objectAt(int index) const { return qmlData->objectAt(index); }
+
+ int totalBindingsCount() const;
+ int totalParserStatusCount() const;
+ int totalObjectCount() const;
+
+ int inlineComponentId(const QString &inlineComponentName) const
+ {
+ for (uint i = 0; i < qmlData->nObjects; ++i) {
+ auto *object = qmlData->objectAt(i);
+ for (auto it = object->inlineComponentsBegin(), end = object->inlineComponentsEnd();
+ it != end; ++it) {
+ if (stringAt(it->nameIndex) == inlineComponentName)
+ return it->objectIndex;
+ }
+ }
+ return -1;
+ }
+
+ void finalizeCompositeType(const QQmlType &type);
+
+ bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const;
+
+ enum class ListPropertyAssignBehavior { Append, Replace, ReplaceIfNotDefault };
+ ListPropertyAssignBehavior listPropertyAssignBehavior() const
+ {
+ if (unitData()->flags & CompiledData::Unit::ListPropertyAssignReplace)
+ return ListPropertyAssignBehavior::Replace;
+ if (unitData()->flags & CompiledData::Unit::ListPropertyAssignReplaceIfNotDefault)
+ return ListPropertyAssignBehavior::ReplaceIfNotDefault;
+ return ListPropertyAssignBehavior::Append;
+ }
+
+ bool ignoresFunctionSignature() const
+ {
+ return unitData()->flags & CompiledData::Unit::FunctionSignaturesIgnored;
+ }
+
+ bool nativeMethodsAcceptThisObjects() const
+ {
+ return unitData()->flags & CompiledData::Unit::NativeMethodsAcceptThisObject;
+ }
+
+ bool valueTypesAreCopied() const
+ {
+ return unitData()->flags & CompiledData::Unit::ValueTypesCopied;
+ }
+
+ bool valueTypesAreAddressable() const
+ {
+ return unitData()->flags & CompiledData::Unit::ValueTypesAddressable;
+ }
+
+ bool valueTypesAreAssertable() const
+ {
+ return unitData()->flags & CompiledData::Unit::ValueTypesAssertable;
+ }
+
+ bool componentsAreBound() const
+ {
+ return unitData()->flags & CompiledData::Unit::ComponentsBound;
+ }
+
+ bool isESModule() const
+ {
+ return unitData()->flags & CompiledData::Unit::IsESModule;
+ }
+
+ bool isSharedLibrary() const
+ {
+ return unitData()->flags & CompiledData::Unit::IsSharedLibrary;
+ }
+
+ struct FunctionIterator
+ {
+ FunctionIterator(const CompiledData::Unit *unit, const CompiledObject *object, int index)
+ : unit(unit), object(object), index(index) {}
+ const CompiledData::Unit *unit;
+ const CompiledObject *object;
+ int index;
+
+ const CompiledFunction *operator->() const
+ {
+ return unit->functionAt(object->functionOffsetTable()[index]);
+ }
+
+ void operator++() { ++index; }
+ bool operator==(const FunctionIterator &rhs) const { return index == rhs.index; }
+ bool operator!=(const FunctionIterator &rhs) const { return index != rhs.index; }
+ };
+
+ FunctionIterator objectFunctionsBegin(const CompiledObject *object) const
+ {
+ return FunctionIterator(unitData(), object, 0);
+ }
+
+ FunctionIterator objectFunctionsEnd(const CompiledObject *object) const
+ {
+ return FunctionIterator(unitData(), object, object->nFunctions);
+ }
+
+ QQmlType qmlTypeForComponent(const QString &inlineComponentName = QString()) const;
+ QMetaType metaType() const { return qmlType.typeId(); }
+
private:
QString m_fileName; // initialized from data->sourceFileIndex
QString m_finalUrlString; // initialized from data->finalUrlIndex
- Heap::Module *m_module = nullptr;
+ mutable QQmlNullableValue<QUrl> m_url;
+ mutable QQmlNullableValue<QUrl> m_finalUrl;
};
class SaveableUnitPointer