/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef frontend_SharedContext_h
#define frontend_SharedContext_h

#include "jsatom.h"
#include "jsopcode.h"
#include "jspubtd.h"
#include "jsscript.h"
#include "jstypes.h"

#include "builtin/ModuleObject.h"
#include "frontend/ParseMaps.h"
#include "frontend/ParseNode.h"
#include "frontend/TokenStream.h"
#include "vm/ScopeObject.h"

namespace js {
namespace frontend {

// These flags apply to both global and function contexts.
class AnyContextFlags
{
    // This class's data is all private and so only visible to these friends.
    friend class SharedContext;

    // True if "use strict"; appears in the body instead of being inherited.
    bool            hasExplicitUseStrict:1;

    // The (static) bindings of this script need to support dynamic name
    // read/write access. Here, 'dynamic' means dynamic dictionary lookup on
    // the scope chain for a dynamic set of keys. The primary examples are:
    //  - direct eval
    //  - function::
    //  - with
    // since both effectively allow any name to be accessed. Non-examples are:
    //  - upvars of nested functions
    //  - function statement
    // since the set of assigned name is known dynamically. 'with' could be in
    // the non-example category, provided the set of all free variables within
    // the with block was noted. However, we do not optimize 'with' so, for
    // simplicity, 'with' is treated like eval.
    //
    // Note: access through the arguments object is not considered dynamic
    // binding access since it does not go through the normal name lookup
    // mechanism. This is debatable and could be changed (although care must be
    // taken not to turn off the whole 'arguments' optimization). To answer the
    // more general "is this argument aliased" question, script->needsArgsObj
    // should be tested (see JSScript::argIsAlised).
    //
    bool            bindingsAccessedDynamically:1;

    // Whether this script, or any of its inner scripts contains a debugger
    // statement which could potentially read or write anywhere along the
    // scope chain.
    bool            hasDebuggerStatement:1;

    // A direct eval occurs in the body of the script.
    bool            hasDirectEval:1;

  public:
    AnyContextFlags()
     :  hasExplicitUseStrict(false),
        bindingsAccessedDynamically(false),
        hasDebuggerStatement(false),
        hasDirectEval(false)
    { }
};

class FunctionContextFlags
{
    // This class's data is all private and so only visible to these friends.
    friend class FunctionBox;

    // The function or a function that encloses it may define new local names
    // at runtime through means other than calling eval.
    bool mightAliasLocals:1;

    // This function does something that can extend the set of bindings in its
    // call objects --- it does a direct eval in non-strict code, or includes a
    // function statement (as opposed to a function definition).
    //
    // This flag is *not* inherited by enclosed or enclosing functions; it
    // applies only to the function in whose flags it appears.
    //
    bool hasExtensibleScope:1;

    // This function refers directly to its name in a way which requires the
    // name to be a separate object on the scope chain.
    bool needsDeclEnvObject:1;

    // Technically, every function has a binding named 'arguments'. Internally,
    // this binding is only added when 'arguments' is mentioned by the function
    // body. This flag indicates whether 'arguments' has been bound either
    // through implicit use:
    //   function f() { return arguments }
    // or explicit redeclaration:
    //   function f() { var arguments; return arguments }
    //
    // Note 1: overwritten arguments (function() { arguments = 3 }) will cause
    // this flag to be set but otherwise require no special handling:
    // 'arguments' is just a local variable and uses of 'arguments' will just
    // read the local's current slot which may have been assigned. The only
    // special semantics is that the initial value of 'arguments' is the
    // arguments object (not undefined, like normal locals).
    //
    // Note 2: if 'arguments' is bound as a formal parameter, there will be an
    // 'arguments' in Bindings, but, as the "LOCAL" in the name indicates, this
    // flag will not be set. This is because, as a formal, 'arguments' will
    // have no special semantics: the initial value is unconditionally the
    // actual argument (or undefined if nactual < nformal).
    //
    bool argumentsHasLocalBinding:1;

    // In many cases where 'arguments' has a local binding (as described above)
    // we do not need to actually create an arguments object in the function
    // prologue: instead we can analyze how 'arguments' is used (using the
    // simple dataflow analysis in analyzeSSA) to determine that uses of
    // 'arguments' can just read from the stack frame directly. However, the
    // dataflow analysis only looks at how JSOP_ARGUMENTS is used, so it will
    // be unsound in several cases. The frontend filters out such cases by
    // setting this flag which eagerly sets script->needsArgsObj to true.
    //
    bool definitelyNeedsArgsObj:1;

    bool needsHomeObject:1;
    bool isDerivedClassConstructor:1;

    // Whether this function has a .this binding. If true, we need to emit
    // JSOP_FUNCTIONTHIS in the prologue to initialize it.
    bool hasThisBinding:1;

  public:
    FunctionContextFlags()
     :  mightAliasLocals(false),
        hasExtensibleScope(false),
        needsDeclEnvObject(false),
        argumentsHasLocalBinding(false),
        definitelyNeedsArgsObj(false),
        needsHomeObject(false),
        isDerivedClassConstructor(false),
        hasThisBinding(false)
    { }
};

// List of directives that may be encountered in a Directive Prologue (ES5 15.1).
class Directives
{
    bool strict_;
    bool asmJS_;

  public:
    explicit Directives(bool strict) : strict_(strict), asmJS_(false) {}
    template <typename ParseHandler> explicit Directives(ParseContext<ParseHandler>* parent);

    void setStrict() { strict_ = true; }
    bool strict() const { return strict_; }

    void setAsmJS() { asmJS_ = true; }
    bool asmJS() const { return asmJS_; }

    Directives& operator=(Directives rhs) {
        strict_ = rhs.strict_;
        asmJS_ = rhs.asmJS_;
        return *this;
    }
    bool operator==(const Directives& rhs) const {
        return strict_ == rhs.strict_ && asmJS_ == rhs.asmJS_;
    }
    bool operator!=(const Directives& rhs) const {
        return !(*this == rhs);
    }
};

// The kind of this-binding for the current scope. Note that arrow functions
// (and generator expression lambdas) have a lexical this-binding so their
// ThisBinding is the same as the ThisBinding of their enclosing scope and can
// be any value.
enum class ThisBinding { Global, Function, Module };

/*
 * The struct SharedContext is part of the current parser context (see
 * ParseContext). It stores information that is reused between the parser and
 * the bytecode emitter. Note however, that this information is not shared
 * between the two; they simply reuse the same data structure.
 */
class SharedContext
{
  public:
    ExclusiveContext* const context;
    AnyContextFlags anyCxFlags;
    bool strictScript;
    bool localStrict;
    bool extraWarnings;

  private:
    ThisBinding thisBinding_;

    bool allowNewTarget_;
    bool allowSuperProperty_;
    bool allowSuperCall_;
    bool inWith_;
    bool needsThisTDZChecks_;
    bool superScopeAlreadyNeedsHomeObject_;

  public:
    SharedContext(ExclusiveContext* cx, Directives directives,
                  bool extraWarnings)
      : context(cx),
        anyCxFlags(),
        strictScript(directives.strict()),
        localStrict(false),
        extraWarnings(extraWarnings),
        thisBinding_(ThisBinding::Global),
        allowNewTarget_(false),
        allowSuperProperty_(false),
        allowSuperCall_(false),
        inWith_(false),
        needsThisTDZChecks_(false),
        superScopeAlreadyNeedsHomeObject_(false)
    { }

    // The unfortunate reason that staticScope() is a virtual is because
    // GlobalSharedContext and FunctionBox have different lifetimes.
    // GlobalSharedContexts are stack allocated and thus may use RootedObject
    // for the static scope. FunctionBoxes are LifoAlloc'd and need to
    // manually trace their static scope.
    virtual JSObject* staticScope() const = 0;
    void computeAllowSyntax(JSObject* staticScope);
    void computeInWith(JSObject* staticScope);
    void computeThisBinding(JSObject* staticScope);

    virtual ObjectBox* toObjectBox() { return nullptr; }
    bool isObjectBox() { return toObjectBox() != nullptr; }
    bool isFunctionBox() { return isObjectBox() && toObjectBox()->isFunctionBox(); }
    inline FunctionBox* asFunctionBox();
    bool isModuleBox() { return isObjectBox() && toObjectBox()->isModuleBox(); }
    inline ModuleBox* asModuleBox();
    bool isGlobalContext() { return !toObjectBox(); }

    ThisBinding thisBinding()          const { return thisBinding_; }

    bool allowNewTarget()              const { return allowNewTarget_; }
    bool allowSuperProperty()          const { return allowSuperProperty_; }
    bool allowSuperCall()              const { return allowSuperCall_; }
    bool inWith()                      const { return inWith_; }
    bool needsThisTDZChecks()          const { return needsThisTDZChecks_; }

    void markSuperScopeNeedsHomeObject();

    bool hasExplicitUseStrict()        const { return anyCxFlags.hasExplicitUseStrict; }
    bool bindingsAccessedDynamically() const { return anyCxFlags.bindingsAccessedDynamically; }
    bool hasDebuggerStatement()        const { return anyCxFlags.hasDebuggerStatement; }
    bool hasDirectEval()               const { return anyCxFlags.hasDirectEval; }

    void setExplicitUseStrict()           { anyCxFlags.hasExplicitUseStrict        = true; }
    void setBindingsAccessedDynamically() { anyCxFlags.bindingsAccessedDynamically = true; }
    void setHasDebuggerStatement()        { anyCxFlags.hasDebuggerStatement        = true; }
    void setHasDirectEval()               { anyCxFlags.hasDirectEval               = true; }

    inline bool allLocalsAliased();

    bool strict() const {
        return strictScript || localStrict;
    }
    bool setLocalStrictMode(bool strict) {
        bool retVal = localStrict;
        localStrict = strict;
        return retVal;
    }

    // JSOPTION_EXTRA_WARNINGS warnings or strict mode errors.
    bool needStrictChecks() const {
        return strict() || extraWarnings;
    }

    bool isDotVariable(JSAtom* atom) const {
        return atom == context->names().dotGenerator || atom == context->names().dotThis;
    }
};

class MOZ_STACK_CLASS GlobalSharedContext : public SharedContext
{
    Rooted<ScopeObject*> staticScope_;

  public:
    GlobalSharedContext(ExclusiveContext* cx, ScopeObject* staticScope, Directives directives,
                        bool extraWarnings, JSFunction* maybeEvalCaller = nullptr)
      : SharedContext(cx, directives, extraWarnings),
        staticScope_(cx, staticScope)
    {
        computeAllowSyntax(staticScope);
        computeInWith(staticScope);

        // If we're executing a Debugger eval-in-frame, staticScope is always a
        // non-function scope, so we have to compute our ThisBinding based on
        // the actual callee.
        if (maybeEvalCaller)
            computeThisBinding(maybeEvalCaller);
        else
            computeThisBinding(staticScope);
    }

    JSObject* staticScope() const override { return staticScope_; }
};

class FunctionBox : public ObjectBox, public SharedContext
{
  public:
    Bindings        bindings;               /* bindings for this function */
    JSObject*       enclosingStaticScope_;
    uint32_t        bufStart;
    uint32_t        bufEnd;
    uint32_t        startLine;
    uint32_t        startColumn;
    uint16_t        length;

    uint8_t         generatorKindBits_;     /* The GeneratorKind of this function. */
    bool            inGenexpLambda:1;       /* lambda from generator expression */
    bool            hasDestructuringArgs:1; /* arguments list contains destructuring expression */
    bool            useAsm:1;               /* see useAsmOrInsideUseAsm */
    bool            insideUseAsm:1;         /* see useAsmOrInsideUseAsm */
    bool            wasEmitted:1;           /* Bytecode has been emitted for this function. */

    // Fields for use in heuristics.
    bool            usesArguments:1;  /* contains a free use of 'arguments' */
    bool            usesApply:1;      /* contains an f.apply() call */
    bool            usesThis:1;       /* contains 'this' */
    bool            usesReturn:1;     /* contains a 'return' statement */

    FunctionContextFlags funCxFlags;

    template <typename ParseHandler>
    FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
                JSObject* enclosingStaticScope, ParseContext<ParseHandler>* pc,
                Directives directives, bool extraWarnings, GeneratorKind generatorKind);

    ObjectBox* toObjectBox() override { return this; }
    JSFunction* function() const { return &object->as<JSFunction>(); }
    JSObject* staticScope() const override { return function(); }
    JSObject* enclosingStaticScope() const { return enclosingStaticScope_; }

    bool isLikelyConstructorWrapper() const {
        return usesArguments && usesApply && usesThis && !usesReturn;
    }

    GeneratorKind generatorKind() const { return GeneratorKindFromBits(generatorKindBits_); }
    bool isGenerator() const { return generatorKind() != NotGenerator; }
    bool isLegacyGenerator() const { return generatorKind() == LegacyGenerator; }
    bool isStarGenerator() const { return generatorKind() == StarGenerator; }
    bool isArrow() const { return function()->isArrow(); }

    void setGeneratorKind(GeneratorKind kind) {
        // A generator kind can be set at initialization, or when "yield" is
        // first seen.  In both cases the transition can only happen from
        // NotGenerator.
        MOZ_ASSERT(!isGenerator());
        generatorKindBits_ = GeneratorKindAsBits(kind);
    }

    bool mightAliasLocals()         const { return funCxFlags.mightAliasLocals; }
    bool hasExtensibleScope()       const { return funCxFlags.hasExtensibleScope; }
    bool needsDeclEnvObject()       const { return funCxFlags.needsDeclEnvObject; }
    bool hasThisBinding()           const { return funCxFlags.hasThisBinding; }
    bool argumentsHasLocalBinding() const { return funCxFlags.argumentsHasLocalBinding; }
    bool definitelyNeedsArgsObj()   const { return funCxFlags.definitelyNeedsArgsObj; }
    bool needsHomeObject()          const { return funCxFlags.needsHomeObject; }
    bool isDerivedClassConstructor() const { return funCxFlags.isDerivedClassConstructor; }

    void setMightAliasLocals()             { funCxFlags.mightAliasLocals         = true; }
    void setHasExtensibleScope()           { funCxFlags.hasExtensibleScope       = true; }
    void setNeedsDeclEnvObject()           { funCxFlags.needsDeclEnvObject       = true; }
    void setHasThisBinding()               { funCxFlags.hasThisBinding           = true; }
    void setArgumentsHasLocalBinding()     { funCxFlags.argumentsHasLocalBinding = true; }
    void setDefinitelyNeedsArgsObj()       { MOZ_ASSERT(funCxFlags.argumentsHasLocalBinding);
                                             funCxFlags.definitelyNeedsArgsObj   = true; }
    void setNeedsHomeObject()              { MOZ_ASSERT(function()->allowSuperProperty());
                                             funCxFlags.needsHomeObject          = true; }
    void setDerivedClassConstructor()      { MOZ_ASSERT(function()->isClassConstructor());
                                             funCxFlags.isDerivedClassConstructor = true; }

    bool hasDefaults() const {
        return length != function()->nargs() - function()->hasRest();
    }

    bool hasMappedArgsObj() const {
        return !strict() && !function()->hasRest() && !hasDefaults() && !hasDestructuringArgs;
    }

    // Return whether this or an enclosing function is being parsed and
    // validated as asm.js. Note: if asm.js validation fails, this will be false
    // while the function is being reparsed. This flag can be used to disable
    // certain parsing features that are necessary in general, but unnecessary
    // for validated asm.js.
    bool useAsmOrInsideUseAsm() const {
        return useAsm || insideUseAsm;
    }

    void setStart(const TokenStream& tokenStream) {
        bufStart = tokenStream.currentToken().pos.begin;
        startLine = tokenStream.getLineno();
        startColumn = tokenStream.getColumn();
    }

    bool needsCallObject()
    {
        // Note: this should be kept in sync with JSFunction::needsCallObject().
        return bindings.hasAnyAliasedBindings() ||
               hasExtensibleScope() ||
               needsDeclEnvObject() ||
               needsHomeObject()    ||
               isDerivedClassConstructor() ||
               isGenerator();
    }

    void trace(JSTracer* trc) override;
};

class ModuleBox : public ObjectBox, public SharedContext
{
  public:
    Bindings bindings;
    TraceableVector<JSAtom*> exportNames;

    template <typename ParseHandler>
    ModuleBox(ExclusiveContext* cx, ObjectBox* traceListHead, ModuleObject* module,
              ParseContext<ParseHandler>* pc);

    ObjectBox* toObjectBox() override { return this; }
    ModuleObject* module() const { return &object->as<ModuleObject>(); }
    JSObject* staticScope() const override { return module(); }

    void trace(JSTracer* trc) override;
};

inline FunctionBox*
SharedContext::asFunctionBox()
{
    MOZ_ASSERT(isFunctionBox());
    return static_cast<FunctionBox*>(this);
}

inline ModuleBox*
SharedContext::asModuleBox()
{
    MOZ_ASSERT(isModuleBox());
    return static_cast<ModuleBox*>(this);
}


// In generators, we treat all locals as aliased so that they get stored on the
// heap.  This way there is less information to copy off the stack when
// suspending, and back on when resuming.  It also avoids the need to create and
// invalidate DebugScope proxies for unaliased locals in a generator frame, as
// the generator frame will be copied out to the heap and released only by GC.
inline bool
SharedContext::allLocalsAliased()
{
    return bindingsAccessedDynamically() || (isFunctionBox() && asFunctionBox()->isGenerator());
}


/*
 * NB: If you add a new type of statement that is a scope, add it between
 * STMT_WITH and STMT_CATCH, or you will break StmtInfoBase::linksScope. If you
 * add a non-looping statement type, add it before STMT_DO_LOOP or you will
 * break StmtInfoBase::isLoop().
 *
 * Also remember to keep the statementName array in BytecodeEmitter.cpp in
 * sync.
 */
enum class StmtType : uint16_t {
    LABEL,                 /* labeled statement:  L: s */
    IF,                    /* if (then) statement */
    ELSE,                  /* else clause of if statement */
    SEQ,                   /* synthetic sequence of statements */
    BLOCK,                 /* compound statement: { s1[;... sN] } */
    SWITCH,                /* switch statement */
    WITH,                  /* with statement */
    CATCH,                 /* catch block */
    TRY,                   /* try block */
    FINALLY,               /* finally block */
    SUBROUTINE,            /* gosub-target subroutine body */
    DO_LOOP,               /* do/while loop statement */
    FOR_LOOP,              /* for loop statement */
    FOR_IN_LOOP,           /* for/in loop statement */
    FOR_OF_LOOP,           /* for/of loop statement */
    WHILE_LOOP,            /* while loop statement */
    SPREAD,                /* spread operator (pseudo for/of) */
    LIMIT
};

/*
 * A comment on the encoding of the js::StmtType enum and StmtInfoBase
 * type-testing methods:
 *
 * StmtInfoBase::maybeScope() tells whether a statement type is always, or may
 * become, a lexical scope. It therefore includes block and switch (the two
 * low-numbered "maybe" scope types) and excludes with (with has dynamic scope
 * pending the "reformed with" in ES4/JS2). It includes all try-catch-finally
 * types, which are high-numbered maybe-scope types.
 *
 * StmtInfoBase::linksScope() tells whether a js::StmtInfo{PC,BCE} of the given
 * type eagerly links to other scoping statement info records. It excludes the
 * two early "maybe" types, block and switch, as well as the try and both
 * finally types, since try and the other trailing maybe-scope types don't need
 * block scope unless they contain let declarations.
 *
 * We treat WITH as a static scope because it prevents lexical binding from
 * continuing further up the static scope chain. With the lost "reformed with"
 * proposal for ES4, we would be able to model it statically, too.
 */

// StmtInfoPC is used by the Parser.  StmtInfoBCE is used by the
// BytecodeEmitter.  The two types have some overlap, encapsulated by
// StmtInfoBase.

struct StmtInfoBase
{
    // Statement type (StmtType).
    StmtType type;

    // True if type is StmtType::BLOCK, StmtType::TRY, StmtType::SWITCH, or
    // StmtType::FINALLY and the block contains at least one let-declaration,
    // or if type is StmtType::CATCH.
    bool isBlockScope:1;

    // for (let ...) induced block scope
    bool isForLetBlock:1;

    // Block label.
    RootedAtom      label;

    // Compile-time scope chain node for this scope.
    Rooted<NestedScopeObject*> staticScope;

    explicit StmtInfoBase(ExclusiveContext* cx)
        : isBlockScope(false), isForLetBlock(false),
          label(cx), staticScope(cx)
    {}

    bool maybeScope() const {
        return StmtType::BLOCK <= type && type <= StmtType::SUBROUTINE &&
               type != StmtType::WITH;
    }

    bool linksScope() const {
        return !!staticScope;
    }

    bool canBeBlockScope() {
        return type == StmtType::BLOCK ||
               type == StmtType::SWITCH ||
               type == StmtType::TRY ||
               type == StmtType::FINALLY ||
               type == StmtType::CATCH;
    }

    StaticBlockObject& staticBlock() const {
        MOZ_ASSERT(staticScope);
        MOZ_ASSERT(isBlockScope);
        return staticScope->as<StaticBlockObject>();
    }

    bool isLoop() const {
        return type >= StmtType::DO_LOOP;
    }

    bool isTrying() const {
        return StmtType::TRY <= type && type <= StmtType::SUBROUTINE;
    }
};

template <class StmtInfo>
class MOZ_STACK_CLASS StmtInfoStack
{
    // Top of the stack.
    StmtInfo* innermostStmt_;

    // Top scope statement with a nested scope.
    StmtInfo* innermostScopeStmt_;

  public:
    explicit StmtInfoStack(ExclusiveContext* cx)
      : innermostStmt_(nullptr),
        innermostScopeStmt_(nullptr)
    { }

    StmtInfo* innermost() const { return innermostStmt_; }
    StmtInfo* innermostScopeStmt() const { return innermostScopeStmt_; }

    void push(StmtInfo* stmt, StmtType type) {
        stmt->type = type;
        stmt->isBlockScope = false;
        stmt->isForLetBlock = false;
        stmt->label = nullptr;
        stmt->staticScope = nullptr;
        stmt->enclosing = innermostStmt_;
        stmt->enclosingScope = nullptr;
        innermostStmt_ = stmt;
    }

    void pushNestedScope(StmtInfo* stmt, StmtType type, NestedScopeObject& staticScope) {
        push(stmt, type);
        linkAsInnermostScopeStmt(stmt, staticScope);
    }

    void pop() {
        StmtInfo* stmt = innermostStmt_;
        innermostStmt_ = stmt->enclosing;
        if (stmt->linksScope())
            innermostScopeStmt_ = stmt->enclosingScope;
    }

    void linkAsInnermostScopeStmt(StmtInfo* stmt, NestedScopeObject& staticScope) {
        MOZ_ASSERT(stmt != innermostScopeStmt_);
        MOZ_ASSERT(!stmt->enclosingScope);
        stmt->enclosingScope = innermostScopeStmt_;
        innermostScopeStmt_ = stmt;
        stmt->staticScope = &staticScope;
    }

    void makeInnermostLexicalScope(StaticBlockObject& blockObj) {
        MOZ_ASSERT(!innermostStmt_->isBlockScope);
        MOZ_ASSERT(innermostStmt_->canBeBlockScope());
        innermostStmt_->isBlockScope = true;
        linkAsInnermostScopeStmt(innermostStmt_, blockObj);
    }
};

} // namespace frontend

} // namespace js

#endif /* frontend_SharedContext_h */
