diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2019-07-10 10:46:05 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-07-11 17:22:52 +0200 |
commit | de0d91abbbcf58a66018a08ca77bb4d63a5efda1 (patch) | |
tree | e960c18118f09b793b54c6767d0ffd4633da7d9d /src/qml/compiler/qv4compileddata_p.h | |
parent | 1948139d4c7c76817e13334e8528b01093afa69d (diff) |
Split compiler and runtime more clearly
Provide different export macros and different top level headers for
each, don't include runtime headers from compiler sources.
Change-Id: I7dc3f8c95839a00a871ba045ec65af87123154be
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4compileddata_p.h')
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 1326 |
1 files changed, 0 insertions, 1326 deletions
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h deleted file mode 100644 index 60d0c50599..0000000000 --- a/src/qml/compiler/qv4compileddata_p.h +++ /dev/null @@ -1,1326 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QV4COMPILEDDATA_P_H -#define QV4COMPILEDDATA_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <functional> - -#include <QtCore/qstring.h> -#include <QtCore/qscopeguard.h> -#include <QtCore/qvector.h> -#include <QtCore/qstringlist.h> -#include <QtCore/qhash.h> - -#if QT_CONFIG(temporaryfile) -#include <QtCore/qsavefile.h> -#endif - -#include <private/qendian_p.h> -#include <private/qv4staticvalue_p.h> - -QT_BEGIN_NAMESPACE - -// Bump this whenever the compiler data structures change in an incompatible way. -// -// IMPORTANT: -// -// 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 0x24 // Collect function parameter types - -class QIODevice; -class QQmlTypeNameCache; -class QQmlType; -class QQmlEngine; - -namespace QmlIR { -struct Document; -} - -namespace QV4 { -namespace Heap { -struct Module; -struct String; -struct InternalClass; -}; - -struct Function; -class EvalISelFactory; - -namespace CompiledData { - -struct String; -struct Function; -struct Lookup; -struct RegExp; -struct Unit; - -template <typename ItemType, typename Container, const ItemType *(Container::*IndexedGetter)(int index) const> -struct TableIterator -{ - TableIterator(const Container *container, int index) : container(container), index(index) {} - const Container *container; - int index; - - const ItemType *operator->() { return (container->*IndexedGetter)(index); } - void operator++() { ++index; } - bool operator==(const TableIterator &rhs) const { return index == rhs.index; } - bool operator!=(const TableIterator &rhs) const { return index != rhs.index; } -}; - -struct Location -{ - union { - quint32 _dummy; - quint32_le_bitfield<0, 20> line; - quint32_le_bitfield<20, 12> column; - }; - - Location() : _dummy(0) { } - - inline bool operator<(const Location &other) const { - return line < other.line || - (line == other.line && column < other.column); - } -}; -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"); - -struct RegExp -{ - enum Flags : unsigned int { - RegExp_NoFlags = 0x0, - RegExp_Global = 0x01, - RegExp_IgnoreCase = 0x02, - RegExp_Multiline = 0x04, - RegExp_Unicode = 0x08, - RegExp_Sticky = 0x10 - }; - union { - quint32 _dummy; - quint32_le_bitfield<0, 5> flags; - quint32_le_bitfield<5, 27> stringIndex; - }; - - RegExp() : _dummy(0) { } -}; -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"); - -struct Lookup -{ - enum Type : unsigned int { - Type_Getter = 0, - Type_Setter = 1, - Type_GlobalGetter = 2, - Type_QmlContextPropertyGetter = 3 - }; - - union { - quint32 _dummy; - quint32_le_bitfield<0, 4> type_and_flags; - quint32_le_bitfield<4, 28> nameIndex; - }; - - Lookup() : _dummy(0) { } -}; -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() : _dummy(0) { } -}; -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"); - -struct JSClass -{ - quint32_le nMembers; - // JSClassMember[nMembers] - - static int calculateSize(int nMembers) { return (sizeof(JSClass) + nMembers * sizeof(JSClassMember) + 7) & ~7; } -}; -static_assert(sizeof(JSClass) == 4, "JSClass structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -// This data structure is intended to be binary compatible with QStringData/QStaticStringData on -// 64-bit and 32-bit little-endian architectures, in all directions. So the same structure mapped -// from a file must be castable to a QStringData regardless of the pointer size. With the first -// few fields that's easy, they're always 32-bit. However the offset field of QArrayData is a -// ptrdiff_t and thus variable in size. -// On 64-bit systems compilers enforce an 8-byte alignment and thus place it at offset 16, while -// on 32-bit systems offset 12 is sufficient. Therefore the two values don't overlap and contain -// the same value. -struct String -{ - qint32_le refcount; // -1 - qint32_le size; - quint32_le allocAndCapacityReservedFlag; // 0 - quint32_le offsetOn32Bit; - quint64_le offsetOn64Bit; - // uint16 strdata[] - - static int calculateSize(const QString &str) { - return (sizeof(String) + (str.length() + 1) * sizeof(quint16) + 7) & ~0x7; - } -}; -static_assert(sizeof(String) == 24, "String structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -// Ensure compatibility with QString -static_assert(offsetof(QArrayData, ref) == offsetof(String, refcount), "refcount must be at the same location"); -static_assert(offsetof(QArrayData, size) == offsetof(String, size), "size must be at the same location"); -static_assert(offsetof(String, offsetOn64Bit) == 16, "offset must be at 8-byte aligned location"); -static_assert(offsetof(String, offsetOn32Bit) == 12, "offset must be at 4-byte aligned location"); -#if QT_POINTER_SIZE == 8 -static_assert(offsetof(QArrayData, offset) == offsetof(String, offsetOn64Bit), "offset must be at the same location"); -#else -static_assert(offsetof(QArrayData, offset) == offsetof(String, offsetOn32Bit), "offset must be at the same location"); -#endif - -struct CodeOffsetToLine { - quint32_le codeOffset; - quint32_le line; -}; -static_assert(sizeof(CodeOffsetToLine) == 8, "CodeOffsetToLine structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -struct Block -{ - quint32_le nLocals; - quint32_le localsOffset; - quint16_le sizeOfLocalTemporalDeadZone; - quint16_le padding; - - const quint32_le *localsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + localsOffset); } - - static int calculateSize(int nLocals) { - int trailingData = nLocals*sizeof (quint32); - size_t size = align(align(sizeof(Block)) + size_t(trailingData)); - Q_ASSERT(size < INT_MAX); - return int(size); - } - - static size_t align(size_t a) { - return (a + 7) & ~size_t(7); - } -}; -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, Variant, Int, Bool, Real, String, Url, Color, - Font, Time, Date, DateTime, Rect, Point, Size, - Vector2D, Vector3D, Vector4D, Matrix4x4, Quaternion, InvalidBuiltin -}; - -struct ParameterType -{ - union { - quint32 _dummy; - quint32_le_bitfield<0, 1> indexIsBuiltinType; - quint32_le_bitfield<1, 31> typeNameIndexOrBuiltinType; - }; -}; -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"); - -struct Parameter -{ - quint32_le nameIndex; - ParameterType type; -}; -static_assert(sizeof(Parameter) == 8, "Parameter structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -// Function is aligned on an 8-byte boundary to make sure there are no bus errors or penalties -// for unaligned access. The ordering of the fields is also from largest to smallest. -struct Function -{ - enum Flags : unsigned int { - IsStrict = 0x1, - IsArrowFunction = 0x2, - IsGenerator = 0x4 - }; - - // Absolute offset into file where the code for this function is located. - quint32_le codeOffset; - quint32_le codeSize; - - quint32_le nameIndex; - quint16_le length; - quint16_le nFormals; - quint32_le formalsOffset; // Can't turn this into a calculated offset because of the mutation in CompilationUnit::createUnitData. - ParameterType returnType; - quint32_le localsOffset; - quint16_le nLocals; - quint16_le nLineNumbers; - size_t lineNumberOffset() const { return localsOffset + nLocals * sizeof(quint32); } - quint32_le nestedFunctionIndex; // for functions that only return a single closure, used in signal handlers - quint16_le sizeOfLocalTemporalDeadZone; - quint16_le firstTemporalDeadZoneRegister; - quint16_le sizeOfRegisterTemporalDeadZone; - quint16_le nRegisters; - Location location; - - quint32_le nLabelInfos; - size_t labelInfosOffset() const { return lineNumberOffset() + nLineNumbers * sizeof(CodeOffsetToLine); } - - // Keep all unaligned data at the end - quint8 flags; - quint8 padding1; - - // quint32 formalsIndex[nFormals] - // quint32 localsIndex[nLocals] - - const Parameter *formalsTable() const { return reinterpret_cast<const Parameter *>(reinterpret_cast<const char *>(this) + formalsOffset); } - const quint32_le *localsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + localsOffset); } - const CodeOffsetToLine *lineNumberTable() const { return reinterpret_cast<const CodeOffsetToLine *>(reinterpret_cast<const char *>(this) + lineNumberOffset()); } - - // --- QQmlPropertyCacheCreator interface - const Parameter *formalsBegin() const { return formalsTable(); } - const Parameter *formalsEnd() const { return formalsTable() + nFormals; } - // --- - - const quint32_le *labelInfoTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + labelInfosOffset()); } - - const char *code() const { return reinterpret_cast<const char *>(this) + codeOffset; } - - static int calculateSize(int nFormals, int nLocals, int nLines, int nInnerfunctions, int labelInfoSize, int codeSize) { - int trailingData = nFormals * sizeof(Parameter) + (nLocals + nInnerfunctions + labelInfoSize)*sizeof (quint32) - + nLines*sizeof(CodeOffsetToLine); - size_t size = align(align(sizeof(Function)) + size_t(trailingData)) + align(codeSize); - Q_ASSERT(size < INT_MAX); - return int(size); - } - - static size_t align(size_t a) { - return (a + 7) & ~size_t(7); - } -}; -static_assert(sizeof(Function) == 56, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -struct Method { - enum Type { - Regular, - Getter, - Setter - }; - - quint32_le name; - quint32_le type; - quint32_le function; -}; -static_assert(sizeof(Method) == 12, "Method structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -struct Class -{ - quint32_le nameIndex; - quint32_le scopeIndex; - quint32_le constructorFunction; - quint32_le nStaticMethods; - quint32_le nMethods; - quint32_le methodTableOffset; - - const Method *methodTable() const { return reinterpret_cast<const Method *>(reinterpret_cast<const char *>(this) + methodTableOffset); } - - static int calculateSize(int nStaticMethods, int nMethods) { - int trailingData = (nStaticMethods + nMethods) * sizeof(Method); - size_t size = align(sizeof(Class) + trailingData); - Q_ASSERT(size < INT_MAX); - return int(size); - } - - static size_t align(size_t a) { - return (a + 7) & ~size_t(7); - } -}; -static_assert(sizeof(Class) == 24, "Class structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -struct TemplateObject -{ - quint32_le size; - - static int calculateSize(int size) { - int trailingData = 2 * size * sizeof(quint32_le); - size_t s = align(sizeof(TemplateObject) + trailingData); - Q_ASSERT(s < INT_MAX); - return int(s); - } - - static size_t align(size_t a) { - return (a + 7) & ~size_t(7); - } - - const quint32_le *stringTable() const { - return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this + 1)); - } - - uint stringIndexAt(uint i) const { - return stringTable()[i]; - } - uint rawStringIndexAt(uint i) const { - return stringTable()[size + i]; - } -}; -static_assert(sizeof(TemplateObject) == 4, "Template object structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -struct ExportEntry -{ - quint32_le exportName; - quint32_le moduleRequest; - quint32_le importName; - quint32_le localName; - Location location; -}; -static_assert(sizeof(ExportEntry) == 20, "ExportEntry structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -struct ImportEntry -{ - quint32_le moduleRequest; - quint32_le importName; - quint32_le localName; - Location location; -}; -static_assert(sizeof(ImportEntry) == 16, "ImportEntry structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -// Qml data structures - -struct TranslationData -{ - quint32_le stringIndex; - quint32_le commentIndex; - qint32_le number; - quint32_le padding; -}; -static_assert(sizeof(TranslationData) == 16, "TranslationData structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -struct Binding -{ - quint32_le propertyNameIndex; - - enum ValueType : unsigned int { - Type_Invalid, - Type_Boolean, - Type_Number, - Type_String, - Type_Null, - Type_Translation, - Type_TranslationById, - Type_Script, - Type_Object, - Type_AttachedProperty, - Type_GroupProperty - }; - - enum Flags : unsigned int { - IsSignalHandlerExpression = 0x1, - IsSignalHandlerObject = 0x2, - IsOnAssignment = 0x4, - InitializerForReadOnlyDeclaration = 0x8, - IsResolvedEnum = 0x10, - IsListItem = 0x20, - IsBindingToAlias = 0x40, - IsDeferredBinding = 0x80, - IsCustomParserBinding = 0x100, - IsFunctionExpression = 0x200 - }; - - union { - quint32_le_bitfield<0, 16> flags; - quint32_le_bitfield<16, 16> type; - }; - union { - bool b; - quint32_le constantValueIndex; - quint32_le compiledScriptIndex; // used when Type_Script - quint32_le objectIndex; - quint32_le translationDataIndex; // used when Type_Translation - quint32 nullMarker; - } value; - quint32_le stringIndex; // Set for Type_String and Type_Script (the latter because of script strings) - - Location location; - Location valueLocation; - - bool isValueBinding() const - { - if (type == Type_AttachedProperty - || type == Type_GroupProperty) - return false; - if (flags & IsSignalHandlerExpression - || flags & IsSignalHandlerObject) - return false; - return true; - } - - bool isValueBindingNoAlias() const { return isValueBinding() && !(flags & IsBindingToAlias); } - bool isValueBindingToAlias() const { return isValueBinding() && (flags & IsBindingToAlias); } - - bool isSignalHandler() const - { - if (flags & IsSignalHandlerExpression || flags & IsSignalHandlerObject) { - Q_ASSERT(!isValueBinding()); - Q_ASSERT(!isAttachedProperty()); - Q_ASSERT(!isGroupProperty()); - return true; - } - return false; - } - - bool isAttachedProperty() const - { - if (type == Type_AttachedProperty) { - Q_ASSERT(!isValueBinding()); - Q_ASSERT(!isSignalHandler()); - Q_ASSERT(!isGroupProperty()); - return true; - } - return false; - } - - bool isGroupProperty() const - { - if (type == Type_GroupProperty) { - Q_ASSERT(!isValueBinding()); - Q_ASSERT(!isSignalHandler()); - Q_ASSERT(!isAttachedProperty()); - return true; - } - return false; - } - - bool isFunctionExpression() const { return (flags & IsFunctionExpression); } - - //reverse of Lexer::singleEscape() - static QString escapedString(const QString &string) - { - QString tmp = QLatin1String("\""); - for (int i = 0; i < string.length(); ++i) { - const QChar &c = string.at(i); - switch (c.unicode()) { - case 0x08: - tmp += QLatin1String("\\b"); - break; - case 0x09: - tmp += QLatin1String("\\t"); - break; - case 0x0A: - tmp += QLatin1String("\\n"); - break; - case 0x0B: - tmp += QLatin1String("\\v"); - break; - case 0x0C: - tmp += QLatin1String("\\f"); - break; - case 0x0D: - tmp += QLatin1String("\\r"); - break; - case 0x22: - tmp += QLatin1String("\\\""); - break; - case 0x27: - tmp += QLatin1String("\\\'"); - break; - case 0x5C: - tmp += QLatin1String("\\\\"); - break; - default: - tmp += c; - break; - } - } - tmp += QLatin1Char('\"'); - return tmp; - } - - bool isTranslationBinding() const { return type == Type_Translation || type == Type_TranslationById; } - bool evaluatesToString() const { return type == Type_String || isTranslationBinding(); } - - bool valueAsBoolean() const - { - 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"); - -struct EnumValue -{ - quint32_le nameIndex; - qint32_le value; - Location location; -}; -static_assert(sizeof(EnumValue) == 12, "EnumValue structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -struct Enum -{ - quint32_le nameIndex; - quint32_le nEnumValues; - Location location; - - const EnumValue *enumValueAt(int idx) const { - return reinterpret_cast<const EnumValue*>(this + 1) + idx; - } - - static int calculateSize(int nEnumValues) { - return (sizeof(Enum) - + nEnumValues * sizeof(EnumValue) - + 7) & ~0x7; - } - - // --- QQmlPropertyCacheCreatorInterface - const EnumValue *enumValuesBegin() const { return enumValueAt(0); } - const EnumValue *enumValuesEnd() const { return enumValueAt(nEnumValues); } - int enumValueCount() const { return nEnumValues; } - // --- -}; -static_assert(sizeof(Enum) == 12, "Enum structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -struct Signal -{ - quint32_le nameIndex; - quint32_le nParameters; - Location location; - // Parameter parameters[1]; - - const Parameter *parameterAt(int idx) const { - return reinterpret_cast<const Parameter*>(this + 1) + idx; - } - - static int calculateSize(int nParameters) { - return (sizeof(Signal) - + nParameters * sizeof(Parameter) - + 7) & ~0x7; - } - - // --- QQmlPropertyCacheCceatorInterface - const Parameter *parametersBegin() const { return parameterAt(0); } - const Parameter *parametersEnd() const { return parameterAt(nParameters); } - int parameterCount() const { return nParameters; } - // --- -}; -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"); - -struct Property -{ - quint32_le nameIndex; - union { - quint32_le_bitfield<0, 29> builtinTypeOrTypeNameIndex; - quint32_le_bitfield<29, 1> isBuiltinType; - quint32_le_bitfield<30, 1> isList; - quint32_le_bitfield<31, 1> isReadOnly; - }; - - Location location; - - void setBuiltinType(BuiltinType t) - { - builtinTypeOrTypeNameIndex = static_cast<quint32>(t); - isBuiltinType = true; - } - BuiltinType builtinType() const { - if (isBuiltinType) - return static_cast<BuiltinType>(quint32(builtinTypeOrTypeNameIndex)); - return BuiltinType::InvalidBuiltin; - } - void setCustomType(int nameIndex) - { - builtinTypeOrTypeNameIndex = nameIndex; - isBuiltinType = false; - } -}; -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"); - -struct Alias { - enum Flags : unsigned int { - IsReadOnly = 0x1, - Resolved = 0x2, - AliasPointsToPointerObject = 0x4 - }; - union { - quint32_le_bitfield<0, 29> nameIndex; - quint32_le_bitfield<29, 3> flags; - }; - union { - quint32_le idIndex; // string index - quint32_le_bitfield<0, 31> targetObjectId; // object id index (in QQmlContextData::idValues) - quint32_le_bitfield<31, 1> aliasToLocalAlias; - }; - union { - quint32_le propertyNameIndex; // string index - qint32_le encodedMetaPropertyIndex; - quint32_le localAliasIndex; // index in list of aliases local to the object (if targetObjectId == objectId) - }; - Location location; - Location referenceLocation; - - bool isObjectAlias() const { - Q_ASSERT(flags & Resolved); - return encodedMetaPropertyIndex == -1; - } -}; -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 { - NoFlag = 0x0, - IsComponent = 0x1, // object was identified to be an explicit or implicit component boundary - HasDeferredBindings = 0x2, // any of the bindings are deferred - HasCustomParserBindings = 0x4 - }; - - // 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; - }; - qint32_le indexOfDefaultPropertyOrAlias; // -1 means no default property declared in this object - quint16_le nFunctions; - quint16_le nProperties; - quint32_le offsetToFunctions; - quint32_le offsetToProperties; - quint32_le offsetToAliases; - quint16_le nAliases; - quint16_le nEnums; - quint32_le offsetToEnums; // which in turn will be a table with offsets to variable-sized Enum objects - quint32_le offsetToSignals; // which in turn will be a table with offsets to variable-sized Signal objects - quint16_le nSignals; - quint16_le nBindings; - quint32_le offsetToBindings; - quint32_le nNamedObjectsInComponent; - quint32_le offsetToNamedObjectsInComponent; - Location location; - Location locationOfIdProperty; -// Function[] -// Property[] -// Signal[] -// Binding[] - - static int calculateSizeExcludingSignalsAndEnums(int nFunctions, int nProperties, int nAliases, int nEnums, int nSignals, int nBindings, int nNamedObjectsInComponent) - { - return ( sizeof(Object) - + nFunctions * sizeof(quint32) - + nProperties * sizeof(Property) - + nAliases * sizeof(Alias) - + nEnums * sizeof(quint32) - + nSignals * sizeof(quint32) - + nBindings * sizeof(Binding) - + nNamedObjectsInComponent * sizeof(int) - + 0x7 - ) & ~0x7; - } - - const quint32_le *functionOffsetTable() const - { - return reinterpret_cast<const quint32_le*>(reinterpret_cast<const char *>(this) + offsetToFunctions); - } - - const Property *propertyTable() const - { - return reinterpret_cast<const Property*>(reinterpret_cast<const char *>(this) + offsetToProperties); - } - - const Alias *aliasTable() const - { - return reinterpret_cast<const Alias*>(reinterpret_cast<const char *>(this) + offsetToAliases); - } - - const Binding *bindingTable() const - { - return reinterpret_cast<const Binding*>(reinterpret_cast<const char *>(this) + offsetToBindings); - } - - const Enum *enumAt(int idx) const - { - const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToEnums); - const quint32_le offset = offsetTable[idx]; - return reinterpret_cast<const Enum*>(reinterpret_cast<const char*>(this) + offset); - } - - const Signal *signalAt(int idx) const - { - const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToSignals); - const quint32_le offset = offsetTable[idx]; - return reinterpret_cast<const Signal*>(reinterpret_cast<const char*>(this) + offset); - } - - const quint32_le *namedObjectsInComponentTable() const - { - return reinterpret_cast<const quint32_le*>(reinterpret_cast<const char *>(this) + offsetToNamedObjectsInComponent); - } - - // --- QQmlPropertyCacheCreator interface - int propertyCount() const { return nProperties; } - int aliasCount() const { return nAliases; } - int enumCount() const { return nEnums; } - int signalCount() const { return nSignals; } - int functionCount() const { return nFunctions; } - - const Binding *bindingsBegin() const { return bindingTable(); } - const Binding *bindingsEnd() const { return bindingTable() + nBindings; } - - const Property *propertiesBegin() const { return propertyTable(); } - const Property *propertiesEnd() const { return propertyTable() + nProperties; } - - const Alias *aliasesBegin() const { return aliasTable(); } - const Alias *aliasesEnd() const { return aliasTable() + nAliases; } - - typedef TableIterator<Enum, Object, &Object::enumAt> EnumIterator; - EnumIterator enumsBegin() const { return EnumIterator(this, 0); } - EnumIterator enumsEnd() const { return EnumIterator(this, nEnums); } - - typedef TableIterator<Signal, Object, &Object::signalAt> SignalIterator; - SignalIterator signalsBegin() const { return SignalIterator(this, 0); } - SignalIterator signalsEnd() const { return SignalIterator(this, nSignals); } - - int namedObjectsInComponentCount() const { return nNamedObjectsInComponent; } - // --- -}; -static_assert(sizeof(Object) == 68, "Object structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -struct Import -{ - enum ImportType : unsigned int { - ImportLibrary = 0x1, - ImportFile = 0x2, - ImportScript = 0x3 - }; - quint32_le type; - - quint32_le uriIndex; - quint32_le qualifierIndex; - - qint32_le majorVersion; - qint32_le minorVersion; - - Location location; - - Import() { type = 0; uriIndex = 0; qualifierIndex = 0; majorVersion = 0; minorVersion = 0; } -}; -static_assert(sizeof(Import) == 24, "Import structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -struct QmlUnit -{ - quint32_le nImports; - quint32_le offsetToImports; - quint32_le nObjects; - quint32_le offsetToObjects; - - const Import *importAt(int idx) const { - return reinterpret_cast<const Import*>((reinterpret_cast<const char *>(this)) + offsetToImports + idx * sizeof(Import)); - } - - const Object *objectAt(int idx) const { - const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToObjects); - const quint32_le offset = offsetTable[idx]; - return reinterpret_cast<const Object*>(reinterpret_cast<const char*>(this) + offset); - } -}; -static_assert(sizeof(QmlUnit) == 16, "QmlUnit structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target"); - -enum { QmlCompileHashSpace = 48 }; -static const char magic_str[] = "qv4cdata"; - -struct Unit -{ - // DO NOT CHANGE THESE FIELDS EVER - char magic[8]; - quint32_le version; - quint32_le qtVersion; - qint64_le sourceTimeStamp; - quint32_le unitSize; // Size of the Unit and any depending data. - // END DO NOT CHANGE THESE FIELDS EVER - - char libraryVersionHash[QmlCompileHashSpace]; - - char md5Checksum[16]; // checksum of all bytes following this field. - char dependencyMD5Checksum[16]; - - enum : unsigned int { - IsJavascript = 0x1, - StaticData = 0x2, // Unit data persistent in memory? - IsSingleton = 0x4, - IsSharedLibrary = 0x8, // .pragma shared? - IsESModule = 0x10, - PendingTypeCompilation = 0x20 // the QML data structures present are incomplete and require type compilation - }; - quint32_le flags; - quint32_le stringTableSize; - quint32_le offsetToStringTable; - quint32_le functionTableSize; - quint32_le offsetToFunctionTable; - quint32_le classTableSize; - quint32_le offsetToClassTable; - quint32_le templateObjectTableSize; - quint32_le offsetToTemplateObjectTable; - quint32_le blockTableSize; - quint32_le offsetToBlockTable; - quint32_le lookupTableSize; - quint32_le offsetToLookupTable; - quint32_le regexpTableSize; - quint32_le offsetToRegexpTable; - quint32_le constantTableSize; - quint32_le offsetToConstantTable; - quint32_le jsClassTableSize; - quint32_le offsetToJSClassTable; - quint32_le translationTableSize; - quint32_le offsetToTranslationTable; - quint32_le localExportEntryTableSize; - quint32_le offsetToLocalExportEntryTable; - quint32_le indirectExportEntryTableSize; - quint32_le offsetToIndirectExportEntryTable; - quint32_le starExportEntryTableSize; - quint32_le offsetToStarExportEntryTable; - quint32_le importEntryTableSize; - quint32_le offsetToImportEntryTable; - quint32_le moduleRequestTableSize; - quint32_le offsetToModuleRequestTable; - qint32_le indexOfRootFunction; - quint32_le sourceFileIndex; - quint32_le finalUrlIndex; - - quint32_le offsetToQmlUnit; - - /* QML specific fields */ - - const QmlUnit *qmlUnit() const { - return reinterpret_cast<const QmlUnit *>(reinterpret_cast<const char *>(this) + offsetToQmlUnit); - } - - QmlUnit *qmlUnit() { - return reinterpret_cast<QmlUnit *>(reinterpret_cast<char *>(this) + offsetToQmlUnit); - } - - bool isSingleton() const { - return flags & Unit::IsSingleton; - } - /* end QML specific fields*/ - - QString stringAtInternal(int idx) const { - Q_ASSERT(idx < int(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); - if (str->size == 0) - return QString(); -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - if (flags & StaticData) { - const QStringDataPtr holder = { const_cast<QStringData *>(reinterpret_cast<const QStringData*>(str)) }; - return QString(holder); - } - const QChar *characters = reinterpret_cast<const QChar *>(str + 1); - return QString(characters, str->size); -#else - const quint16_le *characters = reinterpret_cast<const quint16_le *>(str + 1); - QString qstr(str->size, Qt::Uninitialized); - QChar *ch = qstr.data(); - for (int i = 0; i < str->size; ++i) - ch[i] = QChar(characters[i]); - return qstr; -#endif - } - - const quint32_le *functionOffsetTable() const { return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToFunctionTable); } - const quint32_le *classOffsetTable() const { return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToClassTable); } - const quint32_le *templateObjectOffsetTable() const { return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToTemplateObjectTable); } - const quint32_le *blockOffsetTable() const { return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToBlockTable); } - - const Function *functionAt(int idx) const { - const quint32_le *offsetTable = functionOffsetTable(); - const quint32_le offset = offsetTable[idx]; - return reinterpret_cast<const Function*>(reinterpret_cast<const char *>(this) + offset); - } - - const Class *classAt(int idx) const { - const quint32_le *offsetTable = classOffsetTable(); - const quint32_le offset = offsetTable[idx]; - return reinterpret_cast<const Class *>(reinterpret_cast<const char *>(this) + offset); - } - - const TemplateObject *templateObjectAt(int idx) const { - const quint32_le *offsetTable = templateObjectOffsetTable(); - const quint32_le offset = offsetTable[idx]; - return reinterpret_cast<const TemplateObject *>(reinterpret_cast<const char *>(this) + offset); - } - - const Block *blockAt(int idx) const { - const quint32_le *offsetTable = blockOffsetTable(); - const quint32_le offset = offsetTable[idx]; - return reinterpret_cast<const Block *>(reinterpret_cast<const char *>(this) + offset); - } - - const Lookup *lookupTable() const { return reinterpret_cast<const Lookup*>(reinterpret_cast<const char *>(this) + offsetToLookupTable); } - const RegExp *regexpAt(int index) const { - return reinterpret_cast<const RegExp*>(reinterpret_cast<const char *>(this) + offsetToRegexpTable + index * sizeof(RegExp)); - } - const quint64_le *constants() const { - return reinterpret_cast<const quint64_le*>(reinterpret_cast<const char *>(this) + offsetToConstantTable); - } - - const JSClassMember *jsClassAt(int idx, int *nMembers) const { - const quint32_le *offsetTable = reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + offsetToJSClassTable); - const quint32_le offset = offsetTable[idx]; - const char *ptr = reinterpret_cast<const char *>(this) + offset; - const JSClass *klass = reinterpret_cast<const JSClass *>(ptr); - *nMembers = klass->nMembers; - return reinterpret_cast<const JSClassMember*>(ptr + sizeof(JSClass)); - } - - const TranslationData *translations() const { - return reinterpret_cast<const TranslationData *>(reinterpret_cast<const char *>(this) + offsetToTranslationTable); - } - - 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); } -}; - -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"); - -struct TypeReference -{ - TypeReference(const Location &loc) - : location(loc) - , needsCreation(false) - , errorWhenNotFound(false) - {} - Location location; // first use - bool needsCreation : 1; // whether the type needs to be creatable or not - bool errorWhenNotFound: 1; -}; - -// Map from name index to location of first use. -struct TypeReferenceMap : QHash<int, TypeReference> -{ - TypeReference &add(int nameIndex, const Location &loc) { - Iterator it = find(nameIndex); - if (it != end()) - return *it; - return *insert(nameIndex, loc); - } - - template <typename CompiledObject> - void collectFromObject(const CompiledObject *obj) - { - if (obj->inheritedTypeNameIndex != 0) { - TypeReference &r = this->add(obj->inheritedTypeNameIndex, obj->location); - r.needsCreation = true; - r.errorWhenNotFound = true; - } - - auto prop = obj->propertiesBegin(); - auto propEnd = obj->propertiesEnd(); - for ( ; prop != propEnd; ++prop) { - if (!prop->isBuiltinType) { - TypeReference &r = this->add(prop->builtinTypeOrTypeNameIndex, prop->location); - r.errorWhenNotFound = true; - } - } - - auto binding = obj->bindingsBegin(); - auto bindingEnd = obj->bindingsEnd(); - for ( ; binding != bindingEnd; ++binding) { - if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) - this->add(binding->propertyNameIndex, binding->location); - } - } - - template <typename Iterator> - void collectFromObjects(Iterator it, Iterator end) - { - for (; it != end; ++it) - collectFromObject(*it); - } -}; - -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; - } - - // pointers either to data->constants() or little-endian memory copy. - QV4::Heap::String **runtimeStrings = nullptr; // Array - const StaticValue* constants = nullptr; - QV4::StaticValue *runtimeRegularExpressions = nullptr; - QV4::Heap::InternalClass **runtimeClasses = nullptr; - const StaticValue** imports = nullptr; -}; - -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 -{ - Q_DISABLE_COPY(CompilationUnit) - - const Unit *data = nullptr; - const QmlUnit *qmlData = nullptr; - QStringList dynamicStrings; -public: - using CompiledObject = CompiledData::Object; - - CompilationUnit(const Unit *unitData = nullptr, const QString &fileName = QString(), - const QString &finalUrlString = QString()) - { - setUnitData(unitData, nullptr, fileName, finalUrlString); - } - - ~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); - } - - 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); - 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; - } - - const Unit *unitData() const { return data; } - - void setUnitData(const Unit *unitData, const QmlUnit *qmlUnit = nullptr, - const QString &fileName = QString(), const QString &finalUrlString = QString()) - { - data = unitData; - qmlData = nullptr; -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - delete [] constants; -#endif - constants = nullptr; - m_fileName.clear(); - m_finalUrlString.clear(); - if (!data) - return; - - qmlData = qmlUnit ? qmlUnit : data->qmlUnit(); - -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - StaticValue *bigEndianConstants = new StaticValue[data->constantTableSize]; - const quint64_le *littleEndianConstants = data->constants(); - for (uint i = 0; i < data->constantTableSize; ++i) - bigEndianConstants[i] = StaticValue::fromReturnedValue(littleEndianConstants[i]); - constants = bigEndianConstants; -#else - constants = reinterpret_cast<const StaticValue*>(data->constants()); -#endif - - m_fileName = !fileName.isEmpty() ? fileName : stringAt(data->sourceFileIndex); - m_finalUrlString = !finalUrlString.isEmpty() ? finalUrlString : stringAt(data->finalUrlIndex); - } - - QString stringAt(int index) const - { - if (uint(index) >= data->stringTableSize) - return dynamicStrings.at(index - data->stringTableSize); - return data->stringAtInternal(index); - } - - 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; } - -private: - QString m_fileName; // initialized from data->sourceFileIndex - QString m_finalUrlString; // initialized from data->finalUrlIndex - - Heap::Module *m_module = nullptr; -}; - -class SaveableUnitPointer -{ - Q_DISABLE_COPY_MOVE(SaveableUnitPointer) -public: - SaveableUnitPointer(const Unit *unit, quint32 temporaryFlags = Unit::StaticData) : - unit(unit), - temporaryFlags(temporaryFlags) - { - } - - ~SaveableUnitPointer() = default; - - template<typename Char> - bool saveToDisk(const std::function<bool(const Char *, quint32)> &writer) const - { - auto cleanup = qScopeGuard([this]() { mutableFlags() ^= temporaryFlags; }); - mutableFlags() |= temporaryFlags; - return writer(data<Char>(), size()); - } - - static bool writeDataToFile(const QString &outputFileName, const char *data, quint32 size, - QString *errorString) - { -#if QT_CONFIG(temporaryfile) - QSaveFile cacheFile(outputFileName); - if (!cacheFile.open(QIODevice::WriteOnly | QIODevice::Truncate) - || cacheFile.write(data, size) != size - || !cacheFile.commit()) { - *errorString = cacheFile.errorString(); - return false; - } - - errorString->clear(); - return true; -#else - Q_UNUSED(outputFileName) - *errorString = QStringLiteral("features.temporaryfile is disabled."); - return false; -#endif - } - -private: - const Unit *unit; - quint32 temporaryFlags; - - quint32_le &mutableFlags() const - { - return const_cast<Unit *>(unit)->flags; - } - - template<typename Char> - const Char *data() const - { - Q_STATIC_ASSERT(sizeof(Char) == 1); - const Char *dataPtr; - memcpy(&dataPtr, &unit, sizeof(dataPtr)); - return dataPtr; - } - - quint32 size() const - { - return unit->unitSize; - } -}; - - -} // CompiledData namespace -} // QV4 namespace - -Q_DECLARE_TYPEINFO(QV4::CompiledData::JSClassMember, Q_PRIMITIVE_TYPE); - -QT_END_NAMESPACE - -#endif |