/****************************************************************************
**
** 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$
**
****************************************************************************/

#include <qv4compiler_p.h>
#include <qv4codegen_p.h>
#include <private/qv4compileddata_p.h>
#include <private/qv4staticvalue_p.h>
#include <private/qv4alloca_p.h>
#include <private/qqmljslexer_p.h>
#include <private/qqmljsast_p.h>
#include <private/qml_compile_hash_p.h>
#include <private/qqmlirbuilder_p.h>
#include <QCryptographicHash>

// Efficient implementation that takes advantage of powers of two.
static inline size_t roundUpToMultipleOf(size_t divisor, size_t x)
{
    Q_ASSERT(divisor && !(divisor & (divisor - 1)));
    const size_t remainderMask = divisor - 1;
    return (x + remainderMask) & ~remainderMask;
}

QV4::Compiler::StringTableGenerator::StringTableGenerator()
{
    clear();
}

int QV4::Compiler::StringTableGenerator::registerString(const QString &str)
{
    Q_ASSERT(!frozen);
    QHash<QString, int>::ConstIterator it = stringToId.constFind(str);
    if (it != stringToId.cend())
        return *it;
    stringToId.insert(str, strings.size());
    strings.append(str);
    stringDataSize += QV4::CompiledData::String::calculateSize(str);
    return strings.size() - 1;
}

int QV4::Compiler::StringTableGenerator::getStringId(const QString &string) const
{
    Q_ASSERT(stringToId.contains(string));
    return stringToId.value(string);
}

void QV4::Compiler::StringTableGenerator::clear()
{
    strings.clear();
    stringToId.clear();
    stringDataSize = 0;
    frozen = false;
}

void QV4::Compiler::StringTableGenerator::initializeFromBackingUnit(const QV4::CompiledData::Unit *unit)
{
    clear();
    for (uint i = 0; i < unit->stringTableSize; ++i)
        registerString(unit->stringAtInternal(i));
    backingUnitTableSize = unit->stringTableSize;
    stringDataSize = 0;
}

void QV4::Compiler::StringTableGenerator::serialize(CompiledData::Unit *unit)
{
    char *dataStart = reinterpret_cast<char *>(unit);
    quint32_le *stringTable = reinterpret_cast<quint32_le *>(dataStart + unit->offsetToStringTable);
    char *stringData = reinterpret_cast<char *>(stringTable) + roundUpToMultipleOf(8, unit->stringTableSize * sizeof(uint));
    for (int i = backingUnitTableSize ; i < strings.size(); ++i) {
        const int index = i - backingUnitTableSize;
        stringTable[index] = stringData - dataStart;
        const QString &qstr = strings.at(i);

        QV4::CompiledData::String *s = reinterpret_cast<QV4::CompiledData::String *>(stringData);
        Q_ASSERT(reinterpret_cast<uintptr_t>(s) % alignof(QV4::CompiledData::String) == 0);
        s->refcount = -1;
        s->size = qstr.length();
        s->allocAndCapacityReservedFlag = 0;
        s->offsetOn32Bit = sizeof(QV4::CompiledData::String);
        s->offsetOn64Bit = sizeof(QV4::CompiledData::String);

        ushort *uc = reinterpret_cast<ushort *>(reinterpret_cast<char *>(s) + sizeof(*s));
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
        memcpy(uc, qstr.constData(), s->size * sizeof(ushort));
#else
        for (int i = 0; i < s->size; ++i)
            uc[i] = qToLittleEndian<ushort>(qstr.at(i).unicode());
#endif
        uc[s->size] = 0;

        stringData += QV4::CompiledData::String::calculateSize(qstr);
    }
}

void QV4::Compiler::JSUnitGenerator::generateUnitChecksum(QV4::CompiledData::Unit *unit)
{
#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
    QCryptographicHash hash(QCryptographicHash::Md5);

    const int checksummableDataOffset
            = offsetof(QV4::CompiledData::Unit, md5Checksum) + sizeof(unit->md5Checksum);

    const char *dataPtr = reinterpret_cast<const char *>(unit) + checksummableDataOffset;
    hash.addData(dataPtr, unit->unitSize - checksummableDataOffset);

    QByteArray checksum = hash.result();
    Q_ASSERT(checksum.size() == sizeof(unit->md5Checksum));
    memcpy(unit->md5Checksum, checksum.constData(), sizeof(unit->md5Checksum));
#else
    memset(unit->md5Checksum, 0, sizeof(unit->md5Checksum));
#endif
}

QV4::Compiler::JSUnitGenerator::JSUnitGenerator(QV4::Compiler::Module *module)
    : module(module)
{
    // Make sure the empty string always gets index 0
    registerString(QString());
}

int QV4::Compiler::JSUnitGenerator::registerGetterLookup(const QString &name)
{
    return registerGetterLookup(registerString(name));
}

int QV4::Compiler::JSUnitGenerator::registerGetterLookup(int nameIndex)
{
    CompiledData::Lookup l;
    l.type_and_flags = CompiledData::Lookup::Type_Getter;
    l.nameIndex = nameIndex;
    lookups << l;
    return lookups.size() - 1;
}

int QV4::Compiler::JSUnitGenerator::registerSetterLookup(const QString &name)
{
    return registerSetterLookup(registerString(name));
}

int QV4::Compiler::JSUnitGenerator::registerSetterLookup(int nameIndex)
{
    CompiledData::Lookup l;
    l.type_and_flags = CompiledData::Lookup::Type_Setter;
    l.nameIndex = nameIndex;
    lookups << l;
    return lookups.size() - 1;
}

int QV4::Compiler::JSUnitGenerator::registerGlobalGetterLookup(int nameIndex)
{
    CompiledData::Lookup l;
    l.type_and_flags = CompiledData::Lookup::Type_GlobalGetter;
    l.nameIndex = nameIndex;
    lookups << l;
    return lookups.size() - 1;
}

int QV4::Compiler::JSUnitGenerator::registerQmlContextPropertyGetterLookup(int nameIndex)
{
    CompiledData::Lookup l;
    l.type_and_flags = CompiledData::Lookup::Type_QmlContextPropertyGetter;
    l.nameIndex = nameIndex;
    lookups << l;
    return lookups.size() - 1;
}

int QV4::Compiler::JSUnitGenerator::registerRegExp(QQmlJS::AST::RegExpLiteral *regexp)
{
    CompiledData::RegExp re;
    re.stringIndex = registerString(regexp->pattern.toString());

    re.flags = 0;
    if (regexp->flags & QQmlJS::Lexer::RegExp_Global)
        re.flags |= CompiledData::RegExp::RegExp_Global;
    if (regexp->flags &  QQmlJS::Lexer::RegExp_IgnoreCase)
        re.flags |= CompiledData::RegExp::RegExp_IgnoreCase;
    if (regexp->flags &  QQmlJS::Lexer::RegExp_Multiline)
        re.flags |= CompiledData::RegExp::RegExp_Multiline;
    if (regexp->flags &  QQmlJS::Lexer::RegExp_Unicode)
        re.flags |= CompiledData::RegExp::RegExp_Unicode;
    if (regexp->flags &  QQmlJS::Lexer::RegExp_Sticky)
        re.flags |= CompiledData::RegExp::RegExp_Sticky;

    regexps.append(re);
    return regexps.size() - 1;
}

int QV4::Compiler::JSUnitGenerator::registerConstant(QV4::ReturnedValue v)
{
    int idx = constants.indexOf(v);
    if (idx >= 0)
        return idx;
    constants.append(v);
    return constants.size() - 1;
}

QV4::ReturnedValue QV4::Compiler::JSUnitGenerator::constant(int idx)
{
    return constants.at(idx);
}

int QV4::Compiler::JSUnitGenerator::registerJSClass(const QStringList &members)
{
    // ### re-use existing class definitions.

    const int size = CompiledData::JSClass::calculateSize(members.size());
    jsClassOffsets.append(jsClassData.size());
    const int oldSize = jsClassData.size();
    jsClassData.resize(jsClassData.size() + size);
    memset(jsClassData.data() + oldSize, 0, size);

    CompiledData::JSClass *jsClass = reinterpret_cast<CompiledData::JSClass*>(jsClassData.data() + oldSize);
    jsClass->nMembers = members.size();
    CompiledData::JSClassMember *member = reinterpret_cast<CompiledData::JSClassMember*>(jsClass + 1);

    for (const auto &name : members) {
        member->nameOffset = registerString(name);
        member->isAccessor = false;
        ++member;
    }

    return jsClassOffsets.size() - 1;
}

int QV4::Compiler::JSUnitGenerator::registerTranslation(const QV4::CompiledData::TranslationData &translation)
{
    translations.append(translation);
    return translations.size() - 1;
}

QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorOption option)
{
    registerString(module->fileName);
    registerString(module->finalUrl);
    for (Context *f : qAsConst(module->functions)) {
        registerString(f->name);
        registerString(f->returnType);
        for (int i = 0; i < f->arguments.size(); ++i) {
            registerString(f->arguments.at(i).id);
            registerString(f->arguments.at(i).typeName());
        }
        for (int i = 0; i < f->locals.size(); ++i)
            registerString(f->locals.at(i));
    }
    for (Context *c : qAsConst(module->blocks)) {
        for (int i = 0; i < c->locals.size(); ++i)
            registerString(c->locals.at(i));
    }
    {
        const auto registerExportEntry = [this](const Compiler::ExportEntry &entry) {
            registerString(entry.exportName);
            registerString(entry.moduleRequest);
            registerString(entry.importName);
            registerString(entry.localName);
        };
        std::for_each(module->localExportEntries.constBegin(), module->localExportEntries.constEnd(), registerExportEntry);
        std::for_each(module->indirectExportEntries.constBegin(), module->indirectExportEntries.constEnd(), registerExportEntry);
        std::for_each(module->starExportEntries.constBegin(), module->starExportEntries.constEnd(), registerExportEntry);
    }
    {
        for (const auto &entry: module->importEntries) {
            registerString(entry.moduleRequest);
            registerString(entry.importName);
            registerString(entry.localName);
        }

        for (const QString &request: module->moduleRequests)
            registerString(request);
    }

    Q_ALLOCA_VAR(quint32_le, blockClassAndFunctionOffsets, (module->functions.size() + module->classes.size() + module->templateObjects.size() + module->blocks.size()) * sizeof(quint32_le));
    uint jsClassDataOffset = 0;

    char *dataPtr;
    CompiledData::Unit *unit;
    {
        QV4::CompiledData::Unit tempHeader = generateHeader(option, blockClassAndFunctionOffsets, &jsClassDataOffset);
        dataPtr = reinterpret_cast<char *>(malloc(tempHeader.unitSize));
        memset(dataPtr, 0, tempHeader.unitSize);
        memcpy(&unit, &dataPtr, sizeof(CompiledData::Unit*));
        memcpy(unit, &tempHeader, sizeof(tempHeader));
    }

    memcpy(dataPtr + unit->offsetToFunctionTable, blockClassAndFunctionOffsets, unit->functionTableSize * sizeof(quint32_le));
    memcpy(dataPtr + unit->offsetToClassTable, blockClassAndFunctionOffsets + unit->functionTableSize, unit->classTableSize * sizeof(quint32_le));
    memcpy(dataPtr + unit->offsetToTemplateObjectTable, blockClassAndFunctionOffsets + unit->functionTableSize + unit->classTableSize, unit->templateObjectTableSize * sizeof(quint32_le));
    memcpy(dataPtr + unit->offsetToBlockTable, blockClassAndFunctionOffsets + unit->functionTableSize + unit->classTableSize + unit->templateObjectTableSize, unit->blockTableSize * sizeof(quint32_le));

    for (int i = 0; i < module->functions.size(); ++i) {
        Context *function = module->functions.at(i);
        if (function == module->rootContext)
            unit->indexOfRootFunction = i;

        writeFunction(dataPtr + blockClassAndFunctionOffsets[i], function);
    }

    for (int i = 0; i < module->classes.size(); ++i) {
        const Class &c = module->classes.at(i);

        writeClass(dataPtr + blockClassAndFunctionOffsets[i + module->functions.size()], c);
    }

    for (int i = 0; i < module->templateObjects.size(); ++i) {
        const TemplateObject &t = module->templateObjects.at(i);

        writeTemplateObject(dataPtr + blockClassAndFunctionOffsets[i + module->functions.size() + module->classes.size()], t);
    }

    for (int i = 0; i < module->blocks.size(); ++i) {
        Context *block = module->blocks.at(i);

        writeBlock(dataPtr + blockClassAndFunctionOffsets[i + module->classes.size() + module->templateObjects.size() + module->functions.size()], block);
    }

    CompiledData::Lookup *lookupsToWrite = reinterpret_cast<CompiledData::Lookup*>(dataPtr + unit->offsetToLookupTable);
    for (const CompiledData::Lookup &l : qAsConst(lookups))
        *lookupsToWrite++ = l;

    CompiledData::RegExp *regexpTable = reinterpret_cast<CompiledData::RegExp *>(dataPtr + unit->offsetToRegexpTable);
    memcpy(regexpTable, regexps.constData(), regexps.size() * sizeof(*regexpTable));

#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
    ReturnedValue *constantTable = reinterpret_cast<ReturnedValue *>(dataPtr + unit->offsetToConstantTable);
    memcpy(constantTable, constants.constData(), constants.size() * sizeof(ReturnedValue));
#else
    quint64_le *constantTable = reinterpret_cast<quint64_le *>(dataPtr + unit->offsetToConstantTable);
    for (int i = 0; i < constants.count(); ++i)
        constantTable[i] = constants.at(i);
#endif

    {
        memcpy(dataPtr + jsClassDataOffset, jsClassData.constData(), jsClassData.size());

        // write js classes and js class lookup table
        quint32_le *jsClassOffsetTable = reinterpret_cast<quint32_le *>(dataPtr + unit->offsetToJSClassTable);
        for (int i = 0; i < jsClassOffsets.count(); ++i)
            jsClassOffsetTable[i] = jsClassDataOffset + jsClassOffsets.at(i);
    }


    memcpy(dataPtr + unit->offsetToTranslationTable, translations.constData(), translations.count() * sizeof(CompiledData::TranslationData));

    {
        const auto populateExportEntryTable = [this, dataPtr](const QVector<Compiler::ExportEntry> &table, quint32_le offset) {
            CompiledData::ExportEntry *entryToWrite = reinterpret_cast<CompiledData::ExportEntry *>(dataPtr + offset);
            for (const Compiler::ExportEntry &entry: table) {
                entryToWrite->exportName = getStringId(entry.exportName);
                entryToWrite->moduleRequest = getStringId(entry.moduleRequest);
                entryToWrite->importName = getStringId(entry.importName);
                entryToWrite->localName = getStringId(entry.localName);
                entryToWrite->location = entry.location;
                entryToWrite++;
            }
        };
        populateExportEntryTable(module->localExportEntries, unit->offsetToLocalExportEntryTable);
        populateExportEntryTable(module->indirectExportEntries, unit->offsetToIndirectExportEntryTable);
        populateExportEntryTable(module->starExportEntries, unit->offsetToStarExportEntryTable);
    }

    {
        CompiledData::ImportEntry *entryToWrite = reinterpret_cast<CompiledData::ImportEntry *>(dataPtr + unit->offsetToImportEntryTable);
        for (const Compiler::ImportEntry &entry: module->importEntries) {
            entryToWrite->moduleRequest = getStringId(entry.moduleRequest);
            entryToWrite->importName = getStringId(entry.importName);
            entryToWrite->localName = getStringId(entry.localName);
            entryToWrite->location = entry.location;
            entryToWrite++;
        }
    }

    {
        quint32_le *moduleRequestEntryToWrite = reinterpret_cast<quint32_le *>(dataPtr + unit->offsetToModuleRequestTable);
        for (const QString &moduleRequest: module->moduleRequests) {
            *moduleRequestEntryToWrite = getStringId(moduleRequest);
            moduleRequestEntryToWrite++;
        }
    }

    // write strings and string table
    if (option == GenerateWithStringTable)
        stringTable.serialize(unit);

    generateUnitChecksum(unit);

    return unit;
}

void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Context *irFunction) const
{
    QV4::CompiledData::Function *function = (QV4::CompiledData::Function *)f;

    quint32 currentOffset = static_cast<quint32>(roundUpToMultipleOf(8, sizeof(*function)));

    function->nameIndex = getStringId(irFunction->name);
    function->flags = 0;
    if (irFunction->isStrict)
        function->flags |= CompiledData::Function::IsStrict;
    if (irFunction->isArrowFunction)
        function->flags |= CompiledData::Function::IsArrowFunction;
    if (irFunction->isGenerator)
        function->flags |= CompiledData::Function::IsGenerator;
    function->nestedFunctionIndex =
            irFunction->returnsClosure ? quint32(module->functions.indexOf(irFunction->nestedContexts.first()))
                                       : std::numeric_limits<uint32_t>::max();
    function->length = irFunction->formals ? irFunction->formals->length() : 0;
    function->nFormals = irFunction->arguments.size();
    function->formalsOffset = currentOffset;
    currentOffset += function->nFormals * sizeof(CompiledData::Parameter);

    QmlIR::Parameter::initType(&function->returnType, this, getStringId(irFunction->returnType));

    function->sizeOfLocalTemporalDeadZone = irFunction->sizeOfLocalTemporalDeadZone;
    function->sizeOfRegisterTemporalDeadZone = irFunction->sizeOfRegisterTemporalDeadZone;
    function->firstTemporalDeadZoneRegister = irFunction->firstTemporalDeadZoneRegister;

    function->nLocals = irFunction->locals.size();
    function->localsOffset = currentOffset;
    currentOffset += function->nLocals * sizeof(quint32);

    function->nLineNumbers = irFunction->lineNumberMapping.size();
    Q_ASSERT(function->lineNumberOffset() == currentOffset);
    currentOffset += function->nLineNumbers * sizeof(CompiledData::CodeOffsetToLine);

    function->nRegisters = irFunction->registerCountInFunction;

    if (!irFunction->labelInfo.empty()) {
        function->nLabelInfos = quint32(irFunction->labelInfo.size());
        Q_ASSERT(function->labelInfosOffset() == currentOffset);
        currentOffset += function->nLabelInfos * sizeof(quint32);
    }

    function->location.line = irFunction->line;
    function->location.column = irFunction->column;

    function->codeOffset = currentOffset;
    function->codeSize = irFunction->code.size();

    // write formals
    CompiledData::Parameter *formals = (CompiledData::Parameter *)(f + function->formalsOffset);
    for (int i = 0; i < irFunction->arguments.size(); ++i) {
        QmlIR::Parameter::init(&formals[i], this, getStringId(irFunction->arguments.at(i).id),
                               getStringId(irFunction->arguments.at(i).typeName()));
    }

    // write locals
    quint32_le *locals = (quint32_le *)(f + function->localsOffset);
    for (int i = 0; i < irFunction->locals.size(); ++i)
        locals[i] = getStringId(irFunction->locals.at(i));

    // write line numbers
    memcpy(f + function->lineNumberOffset(), irFunction->lineNumberMapping.constData(), irFunction->lineNumberMapping.size()*sizeof(CompiledData::CodeOffsetToLine));

    quint32_le *labels = (quint32_le *)(f + function->labelInfosOffset());
    for (unsigned u : irFunction->labelInfo) {
        *labels++ = u;
    }

    // write byte code
    memcpy(f + function->codeOffset, irFunction->code.constData(), irFunction->code.size());
}

static_assert(int(QV4::Compiler::Class::Method::Regular) == int(QV4::CompiledData::Method::Regular), "Incompatible layout");
static_assert(int(QV4::Compiler::Class::Method::Getter) == int(QV4::CompiledData::Method::Getter), "Incompatible layout");
static_assert(int(QV4::Compiler::Class::Method::Setter) == int(QV4::CompiledData::Method::Setter), "Incompatible layout");

void QV4::Compiler::JSUnitGenerator::writeClass(char *b, const QV4::Compiler::Class &c)
{
    QV4::CompiledData::Class *cls = reinterpret_cast<QV4::CompiledData::Class *>(b);

    quint32 currentOffset = sizeof(QV4::CompiledData::Class);

    QVector<Class::Method> allMethods = c.staticMethods;
    allMethods += c.methods;

    cls->constructorFunction = c.constructorIndex;
    cls->nameIndex = c.nameIndex;
    cls->nMethods = c.methods.size();
    cls->nStaticMethods = c.staticMethods.size();
    cls->methodTableOffset = currentOffset;
    CompiledData::Method *method = reinterpret_cast<CompiledData::Method *>(b + currentOffset);

    // write methods
    for (int i = 0; i < allMethods.size(); ++i) {
        method->name = allMethods.at(i).nameIndex;
        method->type = allMethods.at(i).type;
        method->function = allMethods.at(i).functionIndex;
        ++method;
    }

    static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE");
    if (showCode) {
        qDebug() << "=== Class" << stringForIndex(cls->nameIndex) << "static methods"
                 << cls->nStaticMethods << "methods" << cls->nMethods;
        qDebug() << "    constructor:" << cls->constructorFunction;
        for (uint i = 0; i < cls->nStaticMethods + cls->nMethods; ++i) {
            QDebug output = qDebug().nospace();
            output << "    " << i << ": ";
            if (i < cls->nStaticMethods)
                output << "static ";
            switch (cls->methodTable()[i].type) {
            case CompiledData::Method::Getter:
                output << "get "; break;
            case CompiledData::Method::Setter:
                output << "set "; break;
            default:
                break;
            }
            output << stringForIndex(cls->methodTable()[i].name) << " "
                   << cls->methodTable()[i].function;
        }
        qDebug().space();
    }
}

void QV4::Compiler::JSUnitGenerator::writeTemplateObject(char *b, const QV4::Compiler::TemplateObject &t)
{
    QV4::CompiledData::TemplateObject *tmpl = reinterpret_cast<QV4::CompiledData::TemplateObject *>(b);
    tmpl->size = t.strings.size();

    quint32 currentOffset = sizeof(QV4::CompiledData::TemplateObject);

    quint32_le *strings = reinterpret_cast<quint32_le *>(b + currentOffset);

    // write methods
    for (int i = 0; i < t.strings.size(); ++i)
        strings[i] = t.strings.at(i);
    strings += t.strings.size();

    for (int i = 0; i < t.rawStrings.size(); ++i)
        strings[i] = t.rawStrings.at(i);

    static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE");
    if (showCode) {
        qDebug() << "=== TemplateObject size" << tmpl->size;
        for (uint i = 0; i < tmpl->size; ++i) {
            qDebug() << "    " << i << stringForIndex(tmpl->stringIndexAt(i));
            qDebug() << "        raw: " << stringForIndex(tmpl->rawStringIndexAt(i));
        }
        qDebug();
    }
}

void QV4::Compiler::JSUnitGenerator::writeBlock(char *b, QV4::Compiler::Context *irBlock) const
{
    QV4::CompiledData::Block *block = reinterpret_cast<QV4::CompiledData::Block *>(b);

    quint32 currentOffset = static_cast<quint32>(roundUpToMultipleOf(8, sizeof(*block)));

    block->sizeOfLocalTemporalDeadZone = irBlock->sizeOfLocalTemporalDeadZone;
    block->nLocals = irBlock->locals.size();
    block->localsOffset = currentOffset;
    currentOffset += block->nLocals * sizeof(quint32);

    // write locals
    quint32_le *locals = (quint32_le *)(b + block->localsOffset);
    for (int i = 0; i < irBlock->locals.size(); ++i)
        locals[i] = getStringId(irBlock->locals.at(i));

    static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE");
    if (showCode) {
        qDebug() << "=== Variables for block" << irBlock->blockIndex;
        for (int i = 0; i < irBlock->locals.size(); ++i)
            qDebug() << "    " << i << ":" << locals[i];
        qDebug();
    }
}

QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Compiler::JSUnitGenerator::GeneratorOption option, quint32_le *blockAndFunctionOffsets, uint *jsClassDataOffset)
{
    CompiledData::Unit unit;
    memset(&unit, 0, sizeof(unit));
    memcpy(unit.magic, CompiledData::magic_str, sizeof(unit.magic));
    unit.flags = QV4::CompiledData::Unit::IsJavascript;
    unit.flags |= module->unitFlags;
    unit.version = QV4_DATA_STRUCTURE_VERSION;
    unit.qtVersion = QT_VERSION;
    qstrcpy(unit.libraryVersionHash, QML_COMPILE_HASH);
    memset(unit.md5Checksum, 0, sizeof(unit.md5Checksum));
    memset(unit.dependencyMD5Checksum, 0, sizeof(unit.dependencyMD5Checksum));

    quint32 nextOffset = sizeof(CompiledData::Unit);

    unit.functionTableSize = module->functions.size();
    unit.offsetToFunctionTable = nextOffset;
    nextOffset += unit.functionTableSize * sizeof(uint);

    unit.classTableSize = module->classes.size();
    unit.offsetToClassTable = nextOffset;
    nextOffset += unit.classTableSize * sizeof(uint);

    unit.templateObjectTableSize = module->templateObjects.size();
    unit.offsetToTemplateObjectTable = nextOffset;
    nextOffset += unit.templateObjectTableSize * sizeof(uint);

    unit.blockTableSize = module->blocks.size();
    unit.offsetToBlockTable = nextOffset;
    nextOffset += unit.blockTableSize * sizeof(uint);

    unit.lookupTableSize = lookups.count();
    unit.offsetToLookupTable = nextOffset;
    nextOffset += unit.lookupTableSize * sizeof(CompiledData::Lookup);

    unit.regexpTableSize = regexps.size();
    unit.offsetToRegexpTable = nextOffset;
    nextOffset += unit.regexpTableSize * sizeof(CompiledData::RegExp);

    unit.constantTableSize = constants.size();

    // Ensure we load constants from well-aligned addresses into for example SSE registers.
    nextOffset = static_cast<quint32>(roundUpToMultipleOf(16, nextOffset));
    unit.offsetToConstantTable = nextOffset;
    nextOffset += unit.constantTableSize * sizeof(ReturnedValue);

    unit.jsClassTableSize = jsClassOffsets.count();
    unit.offsetToJSClassTable = nextOffset;
    nextOffset += unit.jsClassTableSize * sizeof(uint);

    *jsClassDataOffset = nextOffset;
    nextOffset += jsClassData.size();

    nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));

    unit.translationTableSize = translations.count();
    unit.offsetToTranslationTable = nextOffset;
    nextOffset += unit.translationTableSize * sizeof(CompiledData::TranslationData);

    nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));

    const auto reserveExportTable = [&nextOffset](int count, quint32_le *tableSizePtr, quint32_le *offsetPtr) {
        *tableSizePtr = count;
        *offsetPtr = nextOffset;
        nextOffset += count * sizeof(CompiledData::ExportEntry);
        nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));
    };

    reserveExportTable(module->localExportEntries.count(), &unit.localExportEntryTableSize, &unit.offsetToLocalExportEntryTable);
    reserveExportTable(module->indirectExportEntries.count(), &unit.indirectExportEntryTableSize, &unit.offsetToIndirectExportEntryTable);
    reserveExportTable(module->starExportEntries.count(), &unit.starExportEntryTableSize, &unit.offsetToStarExportEntryTable);

    unit.importEntryTableSize = module->importEntries.count();
    unit.offsetToImportEntryTable = nextOffset;
    nextOffset += unit.importEntryTableSize * sizeof(CompiledData::ImportEntry);
    nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));

    unit.moduleRequestTableSize = module->moduleRequests.count();
    unit.offsetToModuleRequestTable = nextOffset;
    nextOffset += unit.moduleRequestTableSize * sizeof(uint);
    nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));

    quint32 functionSize = 0;
    for (int i = 0; i < module->functions.size(); ++i) {
        Context *f = module->functions.at(i);
        blockAndFunctionOffsets[i] = nextOffset;

        quint32 size = QV4::CompiledData::Function::calculateSize(f->arguments.size(), f->locals.size(), f->lineNumberMapping.size(), f->nestedContexts.size(),
                                                                  int(f->labelInfo.size()), f->code.size());
        functionSize += size - f->code.size();
        nextOffset += size;
    }

    blockAndFunctionOffsets += module->functions.size();

    for (int i = 0; i < module->classes.size(); ++i) {
        const Class &c = module->classes.at(i);
        blockAndFunctionOffsets[i] = nextOffset;

        nextOffset += QV4::CompiledData::Class::calculateSize(c.staticMethods.size(), c.methods.size());
    }
    blockAndFunctionOffsets += module->classes.size();

    for (int i = 0; i < module->templateObjects.size(); ++i) {
        const TemplateObject &t = module->templateObjects.at(i);
        blockAndFunctionOffsets[i] = nextOffset;

        nextOffset += QV4::CompiledData::TemplateObject::calculateSize(t.strings.size());
    }
    blockAndFunctionOffsets += module->templateObjects.size();

    for (int i = 0; i < module->blocks.size(); ++i) {
        Context *c = module->blocks.at(i);
        blockAndFunctionOffsets[i] = nextOffset;

        nextOffset += QV4::CompiledData::Block::calculateSize(c->locals.size());
    }

    if (option == GenerateWithStringTable) {
        unit.stringTableSize = stringTable.stringCount();
        nextOffset = static_cast<quint32>(roundUpToMultipleOf(8, nextOffset));
        unit.offsetToStringTable = nextOffset;
        nextOffset += stringTable.sizeOfTableAndData();
    } else {
        unit.stringTableSize = 0;
        unit.offsetToStringTable = 0;
    }
    unit.indexOfRootFunction = -1;
    unit.sourceFileIndex = getStringId(module->fileName);
    unit.finalUrlIndex = getStringId(module->finalUrl);
    unit.sourceTimeStamp = module->sourceTimeStamp.isValid() ? module->sourceTimeStamp.toMSecsSinceEpoch() : 0;
    unit.offsetToQmlUnit = 0;

    unit.unitSize = nextOffset;

    static const bool showStats = qEnvironmentVariableIsSet("QML_SHOW_UNIT_STATS");
    if (showStats) {
        qDebug() << "Generated JS unit that is" << unit.unitSize << "bytes contains:";
        qDebug() << "    " << functionSize << "bytes for non-code function data for" << unit.functionTableSize << "functions";
        qDebug() << "    " << translations.count() * sizeof(CompiledData::TranslationData) << "bytes for" << translations.count() << "translations";
    }

    return unit;
}
