/****************************************************************************
**
** 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 "qv4compilerscanfunctions_p.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include <QtCore/QSet>
#include <QtCore/QBuffer>
#include <QtCore/QBitArray>
#include <QtCore/QStack>
#include <private/qqmljsast_p.h>
#include <private/qv4compilercontext_p.h>
#include <private/qv4codegen_p.h>

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

static CompiledData::Location location(const QQmlJS::AST::SourceLocation &astLocation)
{
    CompiledData::Location target;
    target.line = astLocation.startLine;
    target.column = astLocation.startColumn;
    return target;
}


ScanFunctions::ScanFunctions(Codegen *cg, const QString &sourceCode, ContextType defaultProgramType)
    : QQmlJS::AST::Visitor(cg->recursionDepth())
    , _cg(cg)
    , _sourceCode(sourceCode)
    , _context(nullptr)
    , _allowFuncDecls(true)
    , defaultProgramType(defaultProgramType)
{
}

void ScanFunctions::operator()(Node *node)
{
    if (node)
        node->accept(this);

    calcEscapingVariables();
}

void ScanFunctions::enterGlobalEnvironment(ContextType compilationMode)
{
    enterEnvironment(astNodeForGlobalEnvironment, compilationMode, QStringLiteral("%GlobalCode"));
}

void ScanFunctions::enterEnvironment(Node *node, ContextType compilationMode, const QString &name)
{
    Context *c = _cg->_module->contextMap.value(node);
    if (!c)
        c = _cg->_module->newContext(node, _context, compilationMode);
    if (!c->isStrict)
        c->isStrict = _cg->_strictMode;
    c->name = name;
    _contextStack.append(c);
    _context = c;
}

void ScanFunctions::leaveEnvironment()
{
    _contextStack.pop();
    _context = _contextStack.isEmpty() ? nullptr : _contextStack.top();
}

void ScanFunctions::checkDirectivePrologue(StatementList *ast)
{
    for (StatementList *it = ast; it; it = it->next) {
        if (ExpressionStatement *expr = cast<ExpressionStatement *>(it->statement)) {
            if (StringLiteral *strLit = cast<StringLiteral *>(expr->expression)) {
                // Use the source code, because the StringLiteral's
                // value might have escape sequences in it, which is not
                // allowed.
                if (strLit->literalToken.length < 2)
                    continue;
                QStringRef str = _sourceCode.midRef(strLit->literalToken.offset + 1, strLit->literalToken.length - 2);
                if (str == QLatin1String("use strict")) {
                    _context->isStrict = true;
                } else {
                    // TODO: give a warning.
                }
                continue;
            }
        }

        break;
    }
}

void ScanFunctions::checkName(const QStringRef &name, const SourceLocation &loc)
{
    if (_context->isStrict) {
        if (name == QLatin1String("implements")
                || name == QLatin1String("interface")
                || name == QLatin1String("let")
                || name == QLatin1String("package")
                || name == QLatin1String("private")
                || name == QLatin1String("protected")
                || name == QLatin1String("public")
                || name == QLatin1String("static")
                || name == QLatin1String("yield")) {
            _cg->throwSyntaxError(loc, QStringLiteral("Unexpected strict mode reserved word"));
        }
    }
}

bool ScanFunctions::visit(Program *ast)
{
    enterEnvironment(ast, defaultProgramType, QStringLiteral("%ProgramCode"));
    checkDirectivePrologue(ast->statements);
    return true;
}

void ScanFunctions::endVisit(Program *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ESModule *ast)
{
    enterEnvironment(ast, defaultProgramType, QStringLiteral("%ModuleCode"));
    _context->isStrict = true;
    return true;
}

void ScanFunctions::endVisit(ESModule *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ExportDeclaration *declaration)
{
    QString module;
    if (declaration->fromClause) {
        module = declaration->fromClause->moduleSpecifier.toString();
        if (!module.isEmpty())
            _context->moduleRequests << module;
    }

    QString localNameForDefaultExport = QStringLiteral("*default*");

    if (declaration->exportAll) {
        Compiler::ExportEntry entry;
        entry.moduleRequest = declaration->fromClause->moduleSpecifier.toString();
        entry.importName = QStringLiteral("*");
        entry.location = location(declaration->firstSourceLocation());
        _context->exportEntries << entry;
    } else if (declaration->exportClause) {
        for (ExportsList *it = declaration->exportClause->exportsList; it; it = it->next) {
            ExportSpecifier *spec = it->exportSpecifier;
            Compiler::ExportEntry entry;
            if (module.isEmpty())
                entry.localName = spec->identifier.toString();
            else
                entry.importName = spec->identifier.toString();

            entry.moduleRequest = module;
            entry.exportName = spec->exportedIdentifier.toString();
            entry.location = location(it->firstSourceLocation());

            _context->exportEntries << entry;
        }
    } else if (auto *vstmt = AST::cast<AST::VariableStatement*>(declaration->variableStatementOrDeclaration)) {
        BoundNames boundNames;
        for (VariableDeclarationList *it = vstmt->declarations; it; it = it->next) {
            if (!it->declaration)
                continue;
            it->declaration->boundNames(&boundNames);
        }
        for (const auto &name: boundNames) {
            Compiler::ExportEntry entry;
            entry.localName = name.id;
            entry.exportName = name.id;
            entry.location = location(vstmt->firstSourceLocation());
            _context->exportEntries << entry;
        }
    } else if (auto *classDecl = AST::cast<AST::ClassDeclaration*>(declaration->variableStatementOrDeclaration)) {
        QString name = classDecl->name.toString();
        if (!name.isEmpty()) {
            Compiler::ExportEntry entry;
            entry.localName = name;
            entry.exportName = name;
            entry.location = location(classDecl->firstSourceLocation());
            _context->exportEntries << entry;
            if (declaration->exportDefault)
                localNameForDefaultExport = entry.localName;
        }
    } else if (auto *fdef = declaration->variableStatementOrDeclaration->asFunctionDefinition()) {
        QString functionName;

        // Only function definitions for which we enter their name into the local environment
        // can result in exports. Nested expressions such as (function foo() {}) are not accessible
        // as locals and can only be exported as default exports (further down).
        auto ast = declaration->variableStatementOrDeclaration;
        if (AST::cast<AST::ExpressionStatement*>(ast) || AST::cast<AST::FunctionDeclaration*>(ast))
            functionName = fdef->name.toString();

        if (!functionName.isEmpty()) {
            Compiler::ExportEntry entry;
            entry.localName = functionName;
            entry.exportName = functionName;
            entry.location = location(fdef->firstSourceLocation());
            _context->exportEntries << entry;
            if (declaration->exportDefault)
                localNameForDefaultExport = entry.localName;
        }
    }

    if (declaration->exportDefault) {
        Compiler::ExportEntry entry;
        entry.localName = localNameForDefaultExport;
        _context->localNameForDefaultExport = localNameForDefaultExport;
        entry.exportName = QStringLiteral("default");
        entry.location = location(declaration->firstSourceLocation());
        _context->exportEntries << entry;
    }

    return true; // scan through potential assignment expression code, etc.
}

bool ScanFunctions::visit(ImportDeclaration *declaration)
{
    QString module;
    if (declaration->fromClause) {
        module = declaration->fromClause->moduleSpecifier.toString();
        if (!module.isEmpty())
            _context->moduleRequests << module;
    }

    if (!declaration->moduleSpecifier.isEmpty())
        _context->moduleRequests << declaration->moduleSpecifier.toString();

    if (ImportClause *import = declaration->importClause) {
        if (!import->importedDefaultBinding.isEmpty()) {
            Compiler::ImportEntry entry;
            entry.moduleRequest = module;
            entry.importName = QStringLiteral("default");
            entry.localName = import->importedDefaultBinding.toString();
            entry.location = location(declaration->firstSourceLocation());
            _context->importEntries << entry;
        }

        if (import->nameSpaceImport) {
            Compiler::ImportEntry entry;
            entry.moduleRequest = module;
            entry.importName = QStringLiteral("*");
            entry.localName = import->nameSpaceImport->importedBinding.toString();
            entry.location = location(declaration->firstSourceLocation());
            _context->importEntries << entry;
        }

        if (import->namedImports) {
            for (ImportsList *it = import->namedImports->importsList; it; it = it->next) {
                Compiler::ImportEntry entry;
                entry.moduleRequest = module;
                entry.localName = it->importSpecifier->importedBinding.toString();
                if (!it->importSpecifier->identifier.isEmpty())
                    entry.importName = it->importSpecifier->identifier.toString();
                else
                    entry.importName = entry.localName;
                entry.location = location(declaration->firstSourceLocation());
                _context->importEntries << entry;
            }
        }
    }
    return false;
}

bool ScanFunctions::visit(CallExpression *ast)
{
    if (!_context->hasDirectEval) {
        if (IdentifierExpression *id = cast<IdentifierExpression *>(ast->base)) {
            if (id->name == QLatin1String("eval")) {
                if (_context->usesArgumentsObject == Context::ArgumentsObjectUnknown)
                    _context->usesArgumentsObject = Context::ArgumentsObjectUsed;
                _context->hasDirectEval = true;
            }
        }
    }
    return true;
}

bool ScanFunctions::visit(PatternElement *ast)
{
    if (!ast->isVariableDeclaration())
        return true;

    BoundNames names;
    ast->boundNames(&names);

    QQmlJS::AST::SourceLocation lastInitializerLocation = ast->lastSourceLocation();
    if (_context->lastBlockInitializerLocation.isValid())
        lastInitializerLocation = _context->lastBlockInitializerLocation;

    for (const auto &name : qAsConst(names)) {
        if (_context->isStrict && (name.id == QLatin1String("eval") || name.id == QLatin1String("arguments")))
            _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Variable name may not be eval or arguments in strict mode"));
        checkName(QStringRef(&name.id), ast->identifierToken);
        if (name.id == QLatin1String("arguments"))
            _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
        if (ast->scope == VariableScope::Const && !ast->initializer && !ast->isForDeclaration && !ast->destructuringPattern()) {
            _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Missing initializer in const declaration"));
            return false;
        }
        if (!_context->addLocalVar(name.id, ast->initializer ? Context::VariableDefinition : Context::VariableDeclaration, ast->scope,
                                   /*function*/nullptr, lastInitializerLocation)) {
            _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Identifier %1 has already been declared").arg(name.id));
            return false;
        }
    }
    return true;
}

bool ScanFunctions::visit(IdentifierExpression *ast)
{
    checkName(ast->name, ast->identifierToken);
    if (_context->usesArgumentsObject == Context::ArgumentsObjectUnknown && ast->name == QLatin1String("arguments"))
        _context->usesArgumentsObject = Context::ArgumentsObjectUsed;
    _context->addUsedVariable(ast->name.toString());
    return true;
}

bool ScanFunctions::visit(ExpressionStatement *ast)
{
    if (FunctionExpression* expr = AST::cast<AST::FunctionExpression*>(ast->expression)) {
        if (!_allowFuncDecls)
            _cg->throwSyntaxError(expr->functionToken, QStringLiteral("conditional function or closure declaration"));

        if (!enterFunction(expr, /*enterName*/ true))
            return false;
        Node::accept(expr->formals, this);
        Node::accept(expr->body, this);
        leaveEnvironment();
        return false;
    } else {
        SourceLocation firstToken = ast->firstSourceLocation();
        if (_sourceCode.midRef(firstToken.offset, firstToken.length) == QLatin1String("function")) {
            _cg->throwSyntaxError(firstToken, QStringLiteral("unexpected token"));
        }
    }
    return true;
}

bool ScanFunctions::visit(FunctionExpression *ast)
{
    return enterFunction(ast, /*enterName*/ false);
}

bool ScanFunctions::visit(ClassExpression *ast)
{
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%Class"));
    _context->isStrict = true;
    _context->hasNestedFunctions = true;
    if (!ast->name.isEmpty())
        _context->addLocalVar(ast->name.toString(), Context::VariableDefinition, AST::VariableScope::Const);
    return true;
}

void ScanFunctions::endVisit(ClassExpression *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ClassDeclaration *ast)
{
    if (!ast->name.isEmpty())
        _context->addLocalVar(ast->name.toString(), Context::VariableDeclaration, AST::VariableScope::Let);

    enterEnvironment(ast, ContextType::Block, QStringLiteral("%Class"));
    _context->isStrict = true;
    _context->hasNestedFunctions = true;
    if (!ast->name.isEmpty())
        _context->addLocalVar(ast->name.toString(), Context::VariableDefinition, AST::VariableScope::Const);
    return true;
}

void ScanFunctions::endVisit(ClassDeclaration *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(TemplateLiteral *ast)
{
    while (ast) {
        if (ast->expression)
            Node::accept(ast->expression, this);
        ast = ast->next;
    }
    return true;

}

bool ScanFunctions::visit(SuperLiteral *)
{
    Context *c = _context;
    bool needContext = false;
    while (c && (c->contextType == ContextType::Block || c->isArrowFunction)) {
        needContext |= c->isArrowFunction;
        c = c->parent;
    }

    c->requiresExecutionContext |= needContext;

    return false;
}

bool ScanFunctions::visit(FieldMemberExpression *ast)
{
    if (AST::IdentifierExpression *id = AST::cast<AST::IdentifierExpression *>(ast->base)) {
        if (id->name == QLatin1String("new")) {
            // new.target
            if (ast->name != QLatin1String("target")) {
                _cg->throwSyntaxError(ast->identifierToken, QLatin1String("Expected 'target' after 'new.'."));
                return false;
            }
            Context *c = _context;
            bool needContext = false;
            while (c->contextType == ContextType::Block || c->isArrowFunction) {
                needContext |= c->isArrowFunction;
                c = c->parent;
            }
            c->requiresExecutionContext |= needContext;
            c->innerFunctionAccessesNewTarget |= needContext;

            return false;
        }
    }

    return true;
}

bool ScanFunctions::visit(ArrayPattern *ast)
{
    for (PatternElementList *it = ast->elements; it; it = it->next)
        Node::accept(it->element, this);

    return false;
}

bool ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName)
{
    if (_context->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
        _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Function name may not be eval or arguments in strict mode"));
    return enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName);
}

void ScanFunctions::endVisit(FunctionExpression *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ObjectPattern *ast)
{
    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true);
    Node::accept(ast->properties, this);
    return false;
}

bool ScanFunctions::visit(PatternProperty *ast)
{
    Q_UNUSED(ast);
    // ### Shouldn't be required anymore
//    if (ast->type == PatternProperty::Getter || ast->type == PatternProperty::Setter) {
//        TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true);
//        return enterFunction(ast, QString(), ast->formals, ast->functionBody, /*enterName */ false);
//    }
    return true;
}

void ScanFunctions::endVisit(PatternProperty *)
{
    // ###
//    if (ast->type == PatternProperty::Getter || ast->type == PatternProperty::Setter)
//        leaveEnvironment();
}

bool ScanFunctions::visit(FunctionDeclaration *ast)
{
    return enterFunction(ast, /*enterName*/ true);
}

void ScanFunctions::endVisit(FunctionDeclaration *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(DoWhileStatement *ast) {
    {
        TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
        Node::accept(ast->statement, this);
    }
    Node::accept(ast->expression, this);
    return false;
}

bool ScanFunctions::visit(ForStatement *ast) {
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%For"));
    Node::accept(ast->initialiser, this);
    Node::accept(ast->declarations, this);
    Node::accept(ast->condition, this);
    Node::accept(ast->expression, this);

    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
    Node::accept(ast->statement, this);

    return false;
}

void ScanFunctions::endVisit(ForStatement *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ForEachStatement *ast) {
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%Foreach"));
    if (ast->expression)
        _context->lastBlockInitializerLocation = ast->expression->lastSourceLocation();
    Node::accept(ast->lhs, this);
    Node::accept(ast->expression, this);

    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
    Node::accept(ast->statement, this);

    return false;
}

void ScanFunctions::endVisit(ForEachStatement *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(ThisExpression *)
{
    _context->usesThis = true;
    return false;
}

bool ScanFunctions::visit(Block *ast)
{
    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, _context->isStrict ? false : _allowFuncDecls);
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%Block"));
    Node::accept(ast->statements, this);
    return false;
}

void ScanFunctions::endVisit(Block *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(CaseBlock *ast)
{
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%CaseBlock"));
    return true;
}

void ScanFunctions::endVisit(CaseBlock *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(Catch *ast)
{
    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, _context->isStrict ? false : _allowFuncDecls);
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%CatchBlock"));
    _context->isCatchBlock = true;
    QString caughtVar = ast->patternElement->bindingIdentifier.toString();
    if (caughtVar.isEmpty())
        caughtVar = QStringLiteral("@caught");
    _context->addLocalVar(caughtVar, Context::MemberType::VariableDefinition, VariableScope::Let);

    _context->caughtVariable = caughtVar;
    if (_context->isStrict &&
        (caughtVar == QLatin1String("eval") || caughtVar == QLatin1String("arguments"))) {
        _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Catch variable name may not be eval or arguments in strict mode"));
        return false;
    }
    Node::accept(ast->patternElement, this);
    // skip the block statement
    Node::accept(ast->statement->statements, this);
    return false;
}

void ScanFunctions::endVisit(Catch *)
{
    leaveEnvironment();
}

bool ScanFunctions::visit(WithStatement *ast)
{
    Node::accept(ast->expression, this);

    TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, _context->isStrict ? false : _allowFuncDecls);
    enterEnvironment(ast, ContextType::Block, QStringLiteral("%WithBlock"));
    _context->isWithBlock = true;

    if (_context->isStrict) {
        _cg->throwSyntaxError(ast->withToken, QStringLiteral("'with' statement is not allowed in strict mode"));
        return false;
    }
    Node::accept(ast->statement, this);

    return false;
}

void ScanFunctions::endVisit(WithStatement *)
{
    leaveEnvironment();
}

bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, StatementList *body, bool enterName)
{
    Context *outerContext = _context;
    enterEnvironment(ast, ContextType::Function, name);

    FunctionExpression *expr = AST::cast<FunctionExpression *>(ast);
    if (!expr)
        expr = AST::cast<FunctionDeclaration *>(ast);
    if (outerContext) {
        outerContext->hasNestedFunctions = true;
        // The identifier of a function expression cannot be referenced from the enclosing environment.
        if (enterName) {
            if (!outerContext->addLocalVar(name, Context::FunctionDefinition, VariableScope::Var, expr)) {
                _cg->throwSyntaxError(ast->firstSourceLocation(), QStringLiteral("Identifier %1 has already been declared").arg(name));
                return false;
            }
            outerContext->addLocalVar(name, Context::FunctionDefinition, VariableScope::Var, expr);
        }
        if (name == QLatin1String("arguments"))
            outerContext->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
    }

    _context->name = name;
    if (formals && formals->containsName(QStringLiteral("arguments")))
        _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
    if (expr) {
        if (expr->isArrowFunction)
            _context->isArrowFunction = true;
        else if (expr->isGenerator)
            _context->isGenerator = true;

        if (expr->typeAnnotation)
            _context->returnType = expr->typeAnnotation->type->toString();
    }


    if (!enterName && (!name.isEmpty() && (!formals || !formals->containsName(name))))
        _context->addLocalVar(name, Context::ThisFunctionName, VariableScope::Var);
    _context->formals = formals;

    if (body && !_context->isStrict)
        checkDirectivePrologue(body);

    bool isSimpleParameterList = formals && formals->isSimpleParameterList();

    _context->arguments = formals ? formals->formals() : BoundNames();

    const BoundNames boundNames = formals ? formals->boundNames() : BoundNames();
    for (int i = 0; i < boundNames.size(); ++i) {
        const QString &arg = boundNames.at(i).id;
        if (_context->isStrict || !isSimpleParameterList) {
            bool duplicate = (boundNames.indexOf(arg, i + 1) != -1);
            if (duplicate) {
                _cg->throwSyntaxError(formals->firstSourceLocation(), QStringLiteral("Duplicate parameter name '%1' is not allowed.").arg(arg));
                return false;
            }
        }
        if (_context->isStrict) {
            if (arg == QLatin1String("eval") || arg == QLatin1String("arguments")) {
                _cg->throwSyntaxError(formals->firstSourceLocation(), QStringLiteral("'%1' cannot be used as parameter name in strict mode").arg(arg));
                return false;
            }
        }
        if (!_context->arguments.contains(arg))
            _context->addLocalVar(arg, Context::VariableDefinition, VariableScope::Var);
    }

    return true;
}

void ScanFunctions::calcEscapingVariables()
{
    Module *m = _cg->_module;

    for (Context *inner : qAsConst(m->contextMap)) {
        if (inner->usesArgumentsObject != Context::ArgumentsObjectUsed)
            continue;
        if (inner->contextType != ContextType::Block && !inner->isArrowFunction)
            continue;
        Context *c = inner->parent;
        while (c && (c->contextType == ContextType::Block || c->isArrowFunction))
            c = c->parent;
        if (c)
            c->usesArgumentsObject = Context::ArgumentsObjectUsed;
        inner->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
    }
    for (Context *inner : qAsConst(m->contextMap)) {
        if (!inner->parent || inner->usesArgumentsObject == Context::ArgumentsObjectUnknown)
            inner->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
        if (inner->usesArgumentsObject == Context::ArgumentsObjectUsed) {
            QString arguments = QStringLiteral("arguments");
            inner->addLocalVar(arguments, Context::VariableDeclaration, AST::VariableScope::Var);
            if (!inner->isStrict) {
                inner->argumentsCanEscape = true;
                inner->requiresExecutionContext = true;
            }
        }
    }

    for (Context *c : qAsConst(m->contextMap)) {
        if (c->contextType != ContextType::ESModule)
            continue;
        for (const auto &entry: c->exportEntries) {
            auto mIt = c->members.constFind(entry.localName);
            if (mIt != c->members.constEnd())
                mIt->canEscape = true;
        }
        break;
    }

    for (Context *inner : qAsConst(m->contextMap)) {
        for (const QString &var : qAsConst(inner->usedVariables)) {
            Context *c = inner;
            while (c) {
                Context *current = c;
                c = c->parent;
                if (current->isWithBlock || current->contextType != ContextType::Block)
                    break;
            }
            Q_ASSERT(c != inner);
            while (c) {
                Context::MemberMap::const_iterator it = c->members.constFind(var);
                if (it != c->members.constEnd()) {
                    if (c->parent || it->isLexicallyScoped()) {
                        it->canEscape = true;
                        c->requiresExecutionContext = true;
                    } else if (c->contextType == ContextType::ESModule) {
                        // Module instantiation provides a context, but vars used from inner
                        // scopes need to be stored in its locals[].
                        it->canEscape = true;
                    }
                    break;
                }
                if (c->findArgument(var) != -1) {
                    c->argumentsCanEscape = true;
                    c->requiresExecutionContext = true;
                    break;
                }
                c = c->parent;
            }
        }
        if (inner->hasDirectEval) {
            inner->hasDirectEval = false;
            inner->innerFunctionAccessesNewTarget = true;
            if (!inner->isStrict) {
                Context *c = inner;
                while (c->contextType == ContextType::Block) {
                    c = c->parent;
                }
                Q_ASSERT(c);
                c->hasDirectEval = true;
                c->innerFunctionAccessesThis = true;
            }
            Context *c = inner;
            while (c) {
                c->allVarsEscape = true;
                c = c->parent;
            }
        }
        if (inner->usesThis) {
            inner->usesThis = false;
            bool innerFunctionAccessesThis = false;
            Context *c = inner;
            while (c->contextType == ContextType::Block || c->isArrowFunction) {
                innerFunctionAccessesThis |= c->isArrowFunction;
                c = c->parent;
            }
            Q_ASSERT(c);
            if (!inner->isStrict)
                c->usesThis = true;
            c->innerFunctionAccessesThis |= innerFunctionAccessesThis;
        }
    }
    for (Context *c : qAsConst(m->contextMap)) {
        if (c->innerFunctionAccessesThis) {
            // add an escaping 'this' variable
            c->addLocalVar(QStringLiteral("this"), Context::VariableDefinition, VariableScope::Let);
            c->requiresExecutionContext = true;
            auto mIt = c->members.constFind(QStringLiteral("this"));
            Q_ASSERT(mIt != c->members.constEnd());
            mIt->canEscape = true;
        }
        if (c->innerFunctionAccessesNewTarget) {
            // add an escaping 'new.target' variable
            c->addLocalVar(QStringLiteral("new.target"), Context::VariableDefinition, VariableScope::Let);
            c->requiresExecutionContext = true;
            auto mIt = c->members.constFind(QStringLiteral("new.target"));
            Q_ASSERT(mIt != c->members.constEnd());
            mIt->canEscape = true;
        }
        if (c->allVarsEscape && c->contextType == ContextType::Block && c->members.isEmpty())
            c->allVarsEscape = false;
        if (c->contextType == ContextType::Global || c->contextType == ContextType::ScriptImportedByQML || (!c->isStrict && c->contextType == ContextType::Eval) || m->debugMode)
            c->allVarsEscape = true;
        if (c->allVarsEscape) {
            if (c->parent) {
                c->requiresExecutionContext = true;
                c->argumentsCanEscape = true;
            } else {
                for (const auto &m : qAsConst(c->members)) {
                    if (m.isLexicallyScoped()) {
                        c->requiresExecutionContext = true;
                        break;
                    }
                }
            }
        }
        if (c->contextType == ContextType::Block && c->isCatchBlock) {
            c->requiresExecutionContext = true;
            auto mIt = c->members.constFind(c->caughtVariable);
            Q_ASSERT(mIt != c->members.constEnd());
            mIt->canEscape = true;
        }
        const QLatin1String exprForOn("expression for on");
        if (c->contextType == ContextType::Binding && c->name.length() > exprForOn.size() &&
            c->name.startsWith(exprForOn) && c->name.at(exprForOn.size()).isUpper())
            // we don't really need this for bindings, but we do for signal handlers, and in this case,
            // we don't know if the code is a signal handler or not.
            c->requiresExecutionContext = true;
        if (c->allVarsEscape) {
            for (const auto &m : qAsConst(c->members))
                m.canEscape = true;
        }
    }

    static const bool showEscapingVars = qEnvironmentVariableIsSet("QV4_SHOW_ESCAPING_VARS");
    if (showEscapingVars) {
        qDebug() << "==== escaping variables ====";
        for (Context *c : qAsConst(m->contextMap)) {
            qDebug() << "Context" << c << c->name << "requiresExecutionContext" << c->requiresExecutionContext << "isStrict" << c->isStrict;
            qDebug() << "    isArrowFunction" << c->isArrowFunction << "innerFunctionAccessesThis" << c->innerFunctionAccessesThis;
            qDebug() << "    parent:" << c->parent;
            if (c->argumentsCanEscape)
                qDebug() << "    Arguments escape";
            for (auto it = c->members.constBegin(); it != c->members.constEnd(); ++it) {
                qDebug() << "    " << it.key() << it.value().index << it.value().canEscape << "isLexicallyScoped:" << it.value().isLexicallyScoped();
            }
        }
    }
}

void ScanFunctions::throwRecursionDepthError()
{
    _cg->throwRecursionDepthError();
}
