/****************************************************************************
**
** 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>
#include <functional>

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 0x25 // Extend size of "register" count (nRegisters)

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

    quint32_le nRegisters;
    Location location;
    quint32_le nLabelInfos;

    quint16_le sizeOfLocalTemporalDeadZone;
    quint16_le firstTemporalDeadZoneRegister;
    quint16_le sizeOfRegisterTemporalDeadZone;

    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.
    Heap::String **runtimeStrings = nullptr; // Array
    const StaticValue* constants = nullptr;
    QV4::StaticValue *runtimeRegularExpressions = nullptr;
    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
