/****************************************************************************
**
** Copyright (C) 2017 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 "qv4compilercontext_p.h"
#include "qv4compilercontrolflow_p.h"
#include "qv4bytecodegenerator_p.h"

QT_USE_NAMESPACE
using namespace QV4;
using namespace QV4::Compiler;
using namespace QQmlJS::AST;
using namespace QQmlJS;

QT_BEGIN_NAMESPACE

Context *Module::newContext(Node *node, Context *parent, ContextType contextType)
{
    Q_ASSERT(!contextMap.contains(node));

    Context *c = new Context(parent, contextType);
    if (node) {
        SourceLocation loc = node->firstSourceLocation();
        c->line = loc.startLine;
        c->column = loc.startColumn;
    }

    contextMap.insert(node, c);

    if (!parent)
        rootContext = c;
    else {
        parent->nestedContexts.append(c);
        c->isStrict = parent->isStrict;
    }

    return c;
}

bool Context::Member::requiresTDZCheck(const SourceLocation &accessLocation, bool accessAcrossContextBoundaries) const
{
    if (!isLexicallyScoped())
        return false;

    if (accessAcrossContextBoundaries)
        return true;

    if (!accessLocation.isValid() || !endOfInitializerLocation.isValid())
        return true;

    return accessLocation.begin() < endOfInitializerLocation.end();
}

bool Context::addLocalVar(const QString &name, Context::MemberType type, VariableScope scope, FunctionExpression *function,
                          const QQmlJS::SourceLocation &endOfInitializer)
{
    // ### can this happen?
    if (name.isEmpty())
        return true;

    if (type != FunctionDefinition) {
        if (formals && formals->containsName(name))
            return (scope == VariableScope::Var);
    }
    if (!isCatchBlock || name != caughtVariable) {
        MemberMap::iterator it = members.find(name);
        if (it != members.end()) {
            if (scope != VariableScope::Var || (*it).scope != VariableScope::Var)
                return false;
            if ((*it).type <= type) {
                (*it).type = type;
                (*it).function = function;
            }
            return true;
        }
    }

    // hoist var declarations to the function level
    if (contextType == ContextType::Block && (scope == VariableScope::Var && type != MemberType::FunctionDefinition))
        return parent->addLocalVar(name, type, scope, function, endOfInitializer);

    Member m;
    m.type = type;
    m.function = function;
    m.scope = scope;
    m.endOfInitializerLocation = endOfInitializer;
    members.insert(name, m);
    return true;
}

Context::ResolvedName Context::resolveName(const QString &name, const QQmlJS::SourceLocation &accessLocation)
{
    int scope = 0;
    Context *c = this;

    ResolvedName result;

    while (c) {
        if (c->isWithBlock)
            return result;

        Context::Member m = c->findMember(name);
        if (!c->parent && m.index < 0)
            break;

        if (m.type != Context::UndefinedMember) {
            result.type = m.canEscape ? ResolvedName::Local : ResolvedName::Stack;
            result.scope = scope;
            result.index = m.index;
            result.isConst = (m.scope == VariableScope::Const);
            result.requiresTDZCheck = m.requiresTDZCheck(accessLocation, c != this);
            if (c->isStrict && (name == QLatin1String("arguments") || name == QLatin1String("eval")))
                result.isArgOrEval = true;
            return result;
        }
        const int argIdx = c->findArgument(name);
        if (argIdx != -1) {
            if (c->argumentsCanEscape) {
                result.index = argIdx + c->locals.size();
                result.scope = scope;
                result.type = ResolvedName::Local;
                result.isConst = false;
                return result;
            } else {
                result.index = argIdx + sizeof(CallData) / sizeof(StaticValue) - 1;
                result.scope = 0;
                result.type = ResolvedName::Stack;
                result.isConst = false;
                return result;
            }
        }
        if (c->hasDirectEval) {
            Q_ASSERT(!c->isStrict && c->contextType != ContextType::Block);
            return result;
        }

        if (c->requiresExecutionContext)
            ++scope;
        c = c->parent;
    }

    if (c && c->contextType == ContextType::ESModule) {
        for (int i = 0; i < c->importEntries.count(); ++i) {
            if (c->importEntries.at(i).localName == name) {
                result.index = i;
                result.type = ResolvedName::Import;
                result.isConst = true;
                // We don't know at compile time whether the imported value is let/const or not.
                result.requiresTDZCheck = true;
                return result;
            }
        }
    }

    // ### can we relax the restrictions here?
    if (c->contextType == ContextType::Eval)
        return result;

    if (c->contextType == ContextType::Binding || c->contextType == ContextType::ScriptImportedByQML)
        result.type = ResolvedName::QmlGlobal;
    else
        result.type = ResolvedName::Global;
    return result;
}

void Context::emitBlockHeader(Codegen *codegen)
{
    using Instruction = Moth::Instruction;
    Moth::BytecodeGenerator *bytecodeGenerator = codegen->generator();

    setupFunctionIndices(bytecodeGenerator);

    if (requiresExecutionContext) {
        if (blockIndex < 0) {
            codegen->module()->blocks.append(this);
            blockIndex = codegen->module()->blocks.count() - 1;
        }

        if (contextType == ContextType::Global) {
            Instruction::PushScriptContext scriptContext;
            scriptContext.index = blockIndex;
            bytecodeGenerator->addInstruction(scriptContext);
        } else if (contextType == ContextType::Block || (contextType == ContextType::Eval && !isStrict)) {
            if (isCatchBlock) {
                Instruction::PushCatchContext catchContext;
                catchContext.index = blockIndex;
                catchContext.name = codegen->registerString(caughtVariable);
                bytecodeGenerator->addInstruction(catchContext);
            } else {
                Instruction::PushBlockContext blockContext;
                blockContext.index = blockIndex;
                bytecodeGenerator->addInstruction(blockContext);
            }
        } else if (contextType != ContextType::ESModule && contextType != ContextType::ScriptImportedByQML) {
            Instruction::CreateCallContext createContext;
            bytecodeGenerator->addInstruction(createContext);
        }
    }

    if (contextType == ContextType::Block && sizeOfRegisterTemporalDeadZone > 0) {
        Instruction::InitializeBlockDeadTemporalZone tdzInit;
        tdzInit.firstReg = registerOffset + nRegisters - sizeOfRegisterTemporalDeadZone;
        tdzInit.count = sizeOfRegisterTemporalDeadZone;
        bytecodeGenerator->addInstruction(tdzInit);
    }

    if (usesThis) {
        Q_ASSERT(!isStrict);
        // make sure we convert this to an object
        Instruction::ConvertThisToObject convert;
        bytecodeGenerator->addInstruction(convert);
    }
    if (innerFunctionAccessesThis) {
        Instruction::LoadReg load;
        load.reg = CallData::This;
        bytecodeGenerator->addInstruction(load);
        Codegen::Reference r = codegen->referenceForName(QStringLiteral("this"), true);
        r.storeConsumeAccumulator();
    }
    if (innerFunctionAccessesNewTarget) {
        Instruction::LoadReg load;
        load.reg = CallData::NewTarget;
        bytecodeGenerator->addInstruction(load);
        Codegen::Reference r = codegen->referenceForName(QStringLiteral("new.target"), true);
        r.storeConsumeAccumulator();
    }

    if (contextType == ContextType::Global || contextType == ContextType::ScriptImportedByQML || (contextType == ContextType::Eval && !isStrict)) {
        // variables in global code are properties of the global context object, not locals as with other functions.
        for (Context::MemberMap::const_iterator it = members.constBegin(), cend = members.constEnd(); it != cend; ++it) {
            if (it->isLexicallyScoped())
                continue;
            const QString &local = it.key();

            Instruction::DeclareVar declareVar;
            declareVar.isDeletable = (contextType == ContextType::Eval);
            declareVar.varName = codegen->registerString(local);
            bytecodeGenerator->addInstruction(declareVar);
        }
    }

    if (contextType == ContextType::Function || contextType == ContextType::Binding || contextType == ContextType::ESModule) {
        for (Context::MemberMap::iterator it = members.begin(), end = members.end(); it != end; ++it) {
            if (it->canEscape && it->type == Context::ThisFunctionName) {
                // move the function from the stack to the call context
                Instruction::LoadReg load;
                load.reg = CallData::Function;
                bytecodeGenerator->addInstruction(load);
                Instruction::StoreLocal store;
                store.index = it->index;
                bytecodeGenerator->addInstruction(store);
            }
        }
    }

    if (usesArgumentsObject == Context::ArgumentsObjectUsed) {
        Q_ASSERT(contextType != ContextType::Block);
        if (isStrict || (formals && !formals->isSimpleParameterList())) {
            Instruction::CreateUnmappedArgumentsObject setup;
            bytecodeGenerator->addInstruction(setup);
        } else {
            Instruction::CreateMappedArgumentsObject setup;
            bytecodeGenerator->addInstruction(setup);
        }
        codegen->referenceForName(QStringLiteral("arguments"), false).storeConsumeAccumulator();
    }

    for (const Context::Member &member : qAsConst(members)) {
        if (member.function) {
            const int function = codegen->defineFunction(member.function->name.toString(), member.function, member.function->formals, member.function->body);
            codegen->loadClosure(function);
            Codegen::Reference r = codegen->referenceForName(member.function->name.toString(), true);
            r.storeConsumeAccumulator();
        }
    }
}

void Context::emitBlockFooter(Codegen *codegen)
{
    using Instruction = Moth::Instruction;
    Moth::BytecodeGenerator *bytecodeGenerator = codegen->generator();

    if (!requiresExecutionContext)
        return;

QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // the loads below are empty structs.
    if (contextType == ContextType::Global)
        bytecodeGenerator->addInstruction(Instruction::PopScriptContext());
    else if (contextType != ContextType::ESModule && contextType != ContextType::ScriptImportedByQML)
        bytecodeGenerator->addInstruction(Instruction::PopContext());
QT_WARNING_POP
}

void Context::setupFunctionIndices(Moth::BytecodeGenerator *bytecodeGenerator)
{
    if (registerOffset != -1) {
        // already computed, check for consistency
        Q_ASSERT(registerOffset == bytecodeGenerator->currentRegister());
        bytecodeGenerator->newRegisterArray(nRegisters);
        return;
    }
    Q_ASSERT(locals.size() == 0);
    Q_ASSERT(nRegisters == 0);
    registerOffset = bytecodeGenerator->currentRegister();

    QVector<Context::MemberMap::Iterator> localsInTDZ;
    const auto registerLocal = [this, &localsInTDZ](Context::MemberMap::iterator member) {
        if (member->isLexicallyScoped()) {
            localsInTDZ << member;
        } else {
            member->index = locals.size();
            locals.append(member.key());
        }
    };

    QVector<Context::MemberMap::Iterator> registersInTDZ;
    const auto allocateRegister = [bytecodeGenerator, &registersInTDZ](Context::MemberMap::iterator member) {
        if (member->isLexicallyScoped())
            registersInTDZ << member;
        else
            member->index = bytecodeGenerator->newRegister();
    };

    switch (contextType) {
    case ContextType::ESModule:
    case ContextType::Block:
    case ContextType::Function:
    case ContextType::Binding: {
        for (Context::MemberMap::iterator it = members.begin(), end = members.end(); it != end; ++it) {
            if (it->canEscape) {
                registerLocal(it);
            } else {
                if (it->type == Context::ThisFunctionName)
                    it->index = CallData::Function;
                else
                    allocateRegister(it);
            }
        }
        break;
    }
    case ContextType::Global:
    case ContextType::ScriptImportedByQML:
    case ContextType::Eval:
        for (Context::MemberMap::iterator it = members.begin(), end = members.end(); it != end; ++it) {
            if (!it->isLexicallyScoped() && (contextType == ContextType::Global || contextType == ContextType::ScriptImportedByQML || !isStrict))
                continue;
            if (it->canEscape)
                registerLocal(it);
            else
                allocateRegister(it);
        }
        break;
    }

    sizeOfLocalTemporalDeadZone = localsInTDZ.count();
    for (auto &member: qAsConst(localsInTDZ)) {
        member->index = locals.size();
        locals.append(member.key());
    }

    if (contextType == ContextType::ESModule && !localNameForDefaultExport.isEmpty()) {
        if (!members.contains(localNameForDefaultExport)) {
            // allocate a local slot for the default export, to be used in
            // CodeGen::visit(ExportDeclaration*).
            locals.append(localNameForDefaultExport);
            ++sizeOfLocalTemporalDeadZone;
        }
    }

    sizeOfRegisterTemporalDeadZone = registersInTDZ.count();
    firstTemporalDeadZoneRegister = bytecodeGenerator->currentRegister();
    for (auto &member: qAsConst(registersInTDZ))
        member->index = bytecodeGenerator->newRegister();

    nRegisters = bytecodeGenerator->currentRegister() - registerOffset;
}

QT_END_NAMESPACE
