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

/* JS script descriptor. */

#ifndef jsscript_h
#define jsscript_h

#include "mozilla/PodOperations.h"

#include "jsdbgapi.h"
#include "jsinfer.h"
#include "jsopcode.h"

#include "gc/Barrier.h"
#include "js/RootingAPI.h"
#include "vm/Shape.h"

#if defined(STARBOARD) && defined(JS_THREADSAFE)
#include "starboard/client_porting/pr_starboard/pr_starboard.h"
#endif  // defined(STARBOARD) && defined(JS_THREADSAFE)

namespace js {

namespace jit {
    struct IonScript;
    struct BaselineScript;
    struct IonScriptCounts;
}

# define ION_DISABLED_SCRIPT ((js::jit::IonScript *)0x1)
# define ION_COMPILING_SCRIPT ((js::jit::IonScript *)0x2)

# define BASELINE_DISABLED_SCRIPT ((js::jit::BaselineScript *)0x1)

class Shape;

class BindingIter;

namespace mjit {
    struct JITScript;
    class CallCompiler;
}

namespace analyze {
    class ScriptAnalysis;
}

}

/*
 * Type of try note associated with each catch or finally block, and also with
 * for-in and other kinds of loops. Non-for-in loops do not need these notes
 * for exception unwinding, but storing their boundaries here is helpful for
 * heuristics that need to know whether a given op is inside a loop.
 */
typedef enum JSTryNoteKind {
    JSTRY_CATCH,
    JSTRY_FINALLY,
    JSTRY_ITER,
    JSTRY_LOOP
} JSTryNoteKind;

/*
 * Exception handling record.
 */
struct JSTryNote {
    uint8_t         kind;       /* one of JSTryNoteKind */
    uint8_t         padding;    /* explicit padding on uint16_t boundary */
    uint16_t        stackDepth; /* stack depth upon exception handler entry */
    uint32_t        start;      /* start of the try statement or loop
                                   relative to script->main */
    uint32_t        length;     /* length of the try statement or loop */
};

namespace js {

struct ConstArray {
    js::HeapValue   *vector;    /* array of indexed constant values */
    uint32_t        length;
};

struct ObjectArray {
    js::HeapPtrObject *vector;  /* array of indexed objects */
    uint32_t        length;     /* count of indexed objects */
};

struct TryNoteArray {
    JSTryNote       *vector;    /* array of indexed try notes */
    uint32_t        length;     /* count of indexed try notes */
};

/*
 * A "binding" is a formal, 'var' or 'const' declaration. A function's lexical
 * scope is composed of these three kinds of bindings.
 */

enum BindingKind { ARGUMENT, VARIABLE, CONSTANT };

class Binding
{
    /*
     * One JSScript stores one Binding per formal/variable so we use a
     * packed-word representation.
     */
    uintptr_t bits_;

    static const uintptr_t KIND_MASK = 0x3;
    static const uintptr_t ALIASED_BIT = 0x4;
    static const uintptr_t NAME_MASK = ~(KIND_MASK | ALIASED_BIT);

  public:
    explicit Binding() : bits_(0) {}

    Binding(PropertyName *name, BindingKind kind, bool aliased) {
        JS_STATIC_ASSERT(CONSTANT <= KIND_MASK);
        JS_ASSERT((uintptr_t(name) & ~NAME_MASK) == 0);
        JS_ASSERT((uintptr_t(kind) & ~KIND_MASK) == 0);
        bits_ = uintptr_t(name) | uintptr_t(kind) | (aliased ? ALIASED_BIT : 0);
    }

    PropertyName *name() const {
        return (PropertyName *)(bits_ & NAME_MASK);
    }

    BindingKind kind() const {
        return BindingKind(bits_ & KIND_MASK);
    }

    bool aliased() const {
        return bool(bits_ & ALIASED_BIT);
    }
};

JS_STATIC_ASSERT(sizeof(Binding) == sizeof(uintptr_t));

class Bindings;
typedef InternalHandle<Bindings *> InternalBindingsHandle;

/*
 * Formal parameters and local variables are stored in a shape tree
 * path encapsulated within this class.  This class represents bindings for
 * both function and top-level scripts (the latter is needed to track names in
 * strict mode eval code, to give such code its own lexical environment).
 */
class Bindings
{
    friend class BindingIter;
    friend class AliasedFormalIter;

    HeapPtr<Shape> callObjShape_;
    uintptr_t bindingArrayAndFlag_;
    uint16_t numArgs_;
    uint16_t numVars_;

    /*
     * During parsing, bindings are allocated out of a temporary LifoAlloc.
     * After parsing, a JSScript object is created and the bindings are
     * permanently transferred to it. On error paths, the JSScript object may
     * end up with bindings that still point to the (new released) LifoAlloc
     * memory. To avoid tracing these bindings during GC, we keep track of
     * whether the bindings are temporary or permanent in the low bit of
     * bindingArrayAndFlag_.
     */
    static const uintptr_t TEMPORARY_STORAGE_BIT = 0x1;
    bool bindingArrayUsingTemporaryStorage() const {
        return bindingArrayAndFlag_ & TEMPORARY_STORAGE_BIT;
    }
    Binding *bindingArray() const {
        return reinterpret_cast<Binding *>(bindingArrayAndFlag_ & ~TEMPORARY_STORAGE_BIT);
    }

  public:
    inline Bindings();

    /*
     * Initialize a Bindings with a pointer into temporary storage.
     * bindingArray must have length numArgs+numVars. Before the temporary
     * storage is release, switchToScriptStorage must be called, providing a
     * pointer into the Binding array stored in script->data.
     */
    static bool initWithTemporaryStorage(JSContext *cx, InternalBindingsHandle self,
                                         unsigned numArgs, unsigned numVars,
                                         Binding *bindingArray);

    uint8_t *switchToScriptStorage(Binding *newStorage);

    /*
     * Clone srcScript's bindings (as part of js::CloneScript). dstScriptData
     * is the pointer to what will eventually be dstScript->data.
     */
    static bool clone(JSContext *cx, InternalBindingsHandle self, uint8_t *dstScriptData,
                      HandleScript srcScript);

    unsigned numArgs() const { return numArgs_; }
    unsigned numVars() const { return numVars_; }
    unsigned count() const { return numArgs() + numVars(); }

    /* Return the initial shape of call objects created for this scope. */
    Shape *callObjShape() const { return callObjShape_; }

    /* Convenience method to get the var index of 'arguments'. */
    static unsigned argumentsVarIndex(JSContext *cx, InternalBindingsHandle);

    /* Return whether the binding at bindingIndex is aliased. */
    bool bindingIsAliased(unsigned bindingIndex);

    /* Return whether this scope has any aliased bindings. */
    bool hasAnyAliasedBindings() const { return callObjShape_ && !callObjShape_->isEmptyShape(); }

    void trace(JSTracer *trc);
};

template <>
struct GCMethods<Bindings> {
    static Bindings initial();
    static ThingRootKind kind() { return THING_ROOT_BINDINGS; }
    static bool poisoned(const Bindings &bindings) {
        return IsPoisonedPtr(static_cast<Shape *>(bindings.callObjShape()));
    }
};

class ScriptCounts
{
    friend class ::JSScript;
    friend struct ScriptAndCounts;

    /*
     * This points to a single block that holds an array of PCCounts followed
     * by an array of doubles.  Each element in the PCCounts array has a
     * pointer into the array of doubles.
     */
    PCCounts *pcCountsVector;

    /* Information about any Ion compilations for the script. */
    jit::IonScriptCounts *ionCounts;

 public:
    ScriptCounts() : pcCountsVector(NULL), ionCounts(NULL) { }

    inline void destroy(FreeOp *fop);

    void set(js::ScriptCounts counts) {
        pcCountsVector = counts.pcCountsVector;
        ionCounts = counts.ionCounts;
    }
};

typedef HashMap<JSScript *,
                ScriptCounts,
                DefaultHasher<JSScript *>,
                SystemAllocPolicy> ScriptCountsMap;

class DebugScript
{
    friend class ::JSScript;

    /*
     * When non-zero, compile script in single-step mode. The top bit is set and
     * cleared by setStepMode, as used by JSD. The lower bits are a count,
     * adjusted by changeStepModeCount, used by the Debugger object. Only
     * when the bit is clear and the count is zero may we compile the script
     * without single-step support.
     */
    uint32_t        stepMode;

    /* Number of breakpoint sites at opcodes in the script. */
    uint32_t        numSites;

    /*
     * Array with all breakpoints installed at opcodes in the script, indexed
     * by the offset of the opcode into the script.
     */
    BreakpointSite  *breakpoints[1];
};

typedef HashMap<JSScript *,
                DebugScript *,
                DefaultHasher<JSScript *>,
                SystemAllocPolicy> DebugScriptMap;

struct ScriptSource
{
    friend class SourceCompressorThread;
  private:
    union {
        // Before setSourceCopy or setSource are successfully called, this union
        // has a NULL pointer. When the script source is ready,
        // compressedLength_ != 0 implies compressed holds the compressed data;
        // otherwise, source holds the uncompressed source. There is a special
        // pointer |emptySource| for source code for length 0.
        //
        // The only function allowed to malloc, realloc, or free the pointers in
        // this union is adjustDataSize(). Don't do it elsewhere.
        jschar *source;
        unsigned char *compressed;
    } data;
    uint32_t refs;
    uint32_t length_;
    uint32_t compressedLength_;
    char *filename_;
    jschar *sourceMap_;

    // True if we can call JSRuntime::sourceHook to load the source on
    // demand. If sourceRetrievable_ and hasSourceData() are false, it is not
    // possible to get source at all.
    bool sourceRetrievable_:1;
    bool argumentsNotIncluded_:1;
    bool ready_:1;

  public:
    ScriptSource()
      : refs(0),
        length_(0),
        compressedLength_(0),
        filename_(NULL),
        sourceMap_(NULL),
        sourceRetrievable_(false),
        argumentsNotIncluded_(false),
        ready_(true)
    {
        data.source = NULL;
    }
    void incref() { refs++; }
    void decref() {
        JS_ASSERT(refs != 0);
        if (--refs == 0)
            destroy();
    }
    bool setSourceCopy(JSContext *cx,
                       const jschar *src,
                       uint32_t length,
                       bool argumentsNotIncluded,
                       SourceCompressionToken *tok);
    void setSource(const jschar *src, uint32_t length);
    bool ready() const { return ready_; }
    void setSourceRetrievable() { sourceRetrievable_ = true; }
    bool sourceRetrievable() const { return sourceRetrievable_; }
    bool hasSourceData() const { return !!data.source || !ready(); }
    uint32_t length() const {
        JS_ASSERT(hasSourceData());
        return length_;
    }
    bool argumentsNotIncluded() const {
        JS_ASSERT(hasSourceData());
        return argumentsNotIncluded_;
    }
    const jschar *chars(JSContext *cx);
    JSStableString *substring(JSContext *cx, uint32_t start, uint32_t stop);
    size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf);

    // XDR handling
    template <XDRMode mode>
    bool performXDR(XDRState<mode> *xdr);

    bool setFilename(JSContext *cx, const char *filename);
    const char *filename() const {
        return filename_;
    }

    // Source maps
    bool setSourceMap(JSContext *cx, jschar *sourceMapURL, const char *filename);
    const jschar *sourceMap();
    bool hasSourceMap() const { return sourceMap_ != NULL; }

  private:
    void destroy();
    bool compressed() const { return compressedLength_ != 0; }
    size_t computedSizeOfData() const {
        return compressed() ? compressedLength_ : sizeof(jschar) * length_;
    }
    bool adjustDataSize(size_t nbytes);
};

class ScriptSourceHolder
{
    ScriptSource *ss;
  public:
    explicit ScriptSourceHolder(ScriptSource *ss)
      : ss(ss)
    {
        ss->incref();
    }
    ~ScriptSourceHolder()
    {
        ss->decref();
    }
};

class ScriptSourceObject : public JSObject
{
  public:
    static Class class_;

    static void finalize(FreeOp *fop, JSObject *obj);
    static ScriptSourceObject *create(JSContext *cx, ScriptSource *source);

    ScriptSource *source() {
        return static_cast<ScriptSource *>(getReservedSlot(SOURCE_SLOT).toPrivate());
    }

    void setSource(ScriptSource *source);

  private:
    static const uint32_t SOURCE_SLOT = 0;
};

} /* namespace js */

class JSScript : public js::gc::Cell
{
    static const uint32_t stepFlagMask = 0x80000000U;
    static const uint32_t stepCountMask = 0x7fffffffU;

  public:
    //
    // We order fields according to their size in order to avoid wasting space
    // for alignment.
    //

    // Larger-than-word-sized fields.

  public:
    js::Bindings    bindings;   /* names of top-level variables in this script
                                   (and arguments if this is a function script) */

    // Word-sized fields.

  public:
    jsbytecode      *code;      /* bytecodes and their immediate operands */
    uint8_t         *data;      /* pointer to variable-length data array (see
                                   comment above Create() for details) */

    js::HeapPtrAtom *atoms;     /* maps immediate index to literal struct */

    JSCompartment   *compartment_;
    JSPrincipals    *originPrincipals; /* see jsapi.h 'originPrincipals' comment */

    /* Persistent type information retained across GCs. */
    js::types::TypeScript *types;

  private:
    js::HeapPtrObject sourceObject_; /* source code object */
    js::HeapPtrFunction function_;

    // For callsite clones, which cannot have enclosing scopes, the original
    // function; otherwise the enclosing scope
    js::HeapPtrObject   enclosingScopeOrOriginalFunction_;

    // 32-bit fields.

  public:
    uint32_t        length;     /* length of code vector */

    uint32_t        dataSize;   /* size of the used part of the data array */

    uint32_t        lineno;     /* base line number of script */
    uint32_t        column;     /* base column of script, optionally set */

    uint32_t        mainOffset; /* offset of main entry point from code, after
                                   predef'ing prolog */

    uint32_t        natoms;     /* length of atoms array */

    /* Range of characters in scriptSource which contains this script's source. */
    uint32_t        sourceStart;
    uint32_t        sourceEnd;

  private:
    uint32_t        useCount;   /* Number of times the script has been called
                                 * or has had backedges taken. Reset if the
                                 * script's JIT code is forcibly discarded. */

#ifdef DEBUG
    // Unique identifier within the compartment for this script, used for
    // printing analysis information.
    uint32_t        id_;
  private:
    uint32_t        idpad;
#endif

    // 16-bit fields.

  private:
    uint16_t        PADDING16;
    uint16_t        version;    /* JS version under which script was compiled */

  public:
    uint16_t        ndefaults;  /* number of defaults the function has */

    uint16_t        nfixed;     /* number of slots besides stack operands in
                                   slot array */

    uint16_t        nTypeSets;  /* number of type sets used in this script for
                                   dynamic type monitoring */

    uint16_t        nslots;     /* vars plus maximum stack depth */
    uint16_t        staticLevel;/* static level for display maintenance */

    // 8-bit fields.

  public:
    // The kinds of the optional arrays.
    enum ArrayKind {
        CONSTS,
        OBJECTS,
        REGEXPS,
        TRYNOTES,
        LIMIT
    };

    typedef uint8_t ArrayBitsT;

  private:
    // The bits in this field indicate the presence/non-presence of several
    // optional arrays in |data|.  See the comments above Create() for details.
    ArrayBitsT      hasArrayBits;

    // 1-bit fields.

  public:
    bool            noScriptRval:1; /* no need for result value of last
                                       expression statement */
    bool            savedCallerFun:1; /* can call getCallerFunction() */
    bool            strict:1; /* code is in strict mode */
    bool            explicitUseStrict:1; /* code has "use strict"; explicitly */
    bool            compileAndGo:1;   /* see Parser::compileAndGo */
    bool            selfHosted:1;     /* see Parser::selfHostingMode */
    bool            bindingsAccessedDynamically:1; /* see FunctionContextFlags */
    bool            funHasExtensibleScope:1;       /* see FunctionContextFlags */
    bool            funNeedsDeclEnvObject:1;       /* see FunctionContextFlags */
    bool            funHasAnyAliasedFormal:1;      /* true if any formalIsAliased(i) */
    bool            warnedAboutTwoArgumentEval:1; /* have warned about use of
                                                     obsolete eval(s, o) in
                                                     this script */
    bool            warnedAboutUndefinedProp:1; /* have warned about uses of
                                                   undefined properties in this
                                                   script */
    bool            hasSingletons:1;  /* script has singleton objects */
    bool            treatAsRunOnce:1; /* script is a lambda to treat as running once. */
    bool            hasRunOnce:1;     /* if treatAsRunOnce, whether script has executed. */
    bool            hasBeenCloned:1;  /* script has been reused for a clone. */
    bool            isActiveEval:1;   /* script came from eval(), and is still active */
    bool            isCachedEval:1;   /* script came from eval(), and is in eval cache */

    // Set for functions defined at the top level within an 'eval' script.
    bool directlyInsideEval:1;

    // Both 'arguments' and f.apply() are used. This is likely to be a wrapper.
    bool usesArgumentsAndApply:1;

    /* script is attempted to be cloned anew at each callsite. This is
       temporarily needed for ParallelArray selfhosted code until type
       information can be made context sensitive. See discussion in
       bug 826148. */
    bool            shouldCloneAtCallsite:1;

    bool            isCallsiteClone:1; /* is a callsite clone; has a link to the original function */
#ifdef JS_ION
    bool            failedBoundsCheck:1; /* script has had hoisted bounds checks fail */
    bool            failedShapeGuard:1; /* script has had hoisted shape guard fail */
    bool            hadFrequentBailouts:1;
#else
    bool            failedBoundsCheckPad:1;
    bool            failedShapeGuardPad:1;
    bool            hadFrequentBailoutsPad:1;
#endif
    bool            invalidatedIdempotentCache:1; /* idempotent cache has triggered invalidation */
    bool            isGenerator:1;    /* is a generator */
    bool            isGeneratorExp:1; /* is a generator expression */
    bool            hasScriptCounts:1;/* script has an entry in
                                         JSCompartment::scriptCountsMap */
    bool            hasDebugScript:1; /* script has an entry in
                                         JSCompartment::debugScriptMap */
    bool            hasFreezeConstraints:1; /* freeze constraints for stack
                                             * type sets have been generated */

  private:
    /* See comments below. */
    bool            argsHasVarBinding_:1;
    bool            needsArgsAnalysis_:1;
    bool            needsArgsObj_:1;

    //
    // End of fields.  Start methods.
    //

  public:
    static JSScript *Create(JSContext *cx, js::HandleObject enclosingScope, bool savedCallerFun,
                            const JS::CompileOptions &options, unsigned staticLevel,
                            JS::HandleScriptSource sourceObject, uint32_t sourceStart,
                            uint32_t sourceEnd);

    // Three ways ways to initialize a JSScript. Callers of partiallyInit()
    // and fullyInitTrivial() are responsible for notifying the debugger after
    // successfully creating any kind (function or other) of new JSScript.
    // However, callers of fullyInitFromEmitter() do not need to do this.
    static bool partiallyInit(JSContext *cx, JS::Handle<JSScript*> script,
                              uint32_t nobjects, uint32_t nregexps,
                              uint32_t ntrynotes, uint32_t nconsts, uint32_t nTypeSets);
    static bool fullyInitTrivial(JSContext *cx, JS::Handle<JSScript*> script);  // inits a JSOP_STOP-only script
    static bool fullyInitFromEmitter(JSContext *cx, JS::Handle<JSScript*> script,
                                     js::frontend::BytecodeEmitter *bce);

    inline JSPrincipals *principals();

    JSCompartment *compartment() const { return compartment_; }

    void setVersion(JSVersion v) { version = v; }

    /* See ContextFlags::funArgumentsHasLocalBinding comment. */
    bool argumentsHasVarBinding() const { return argsHasVarBinding_; }
    jsbytecode *argumentsBytecode() const { JS_ASSERT(code[0] == JSOP_ARGUMENTS); return code; }
    void setArgumentsHasVarBinding();

    /*
     * As an optimization, even when argsHasLocalBinding, the function prologue
     * may not need to create an arguments object. This is determined by
     * needsArgsObj which is set by ScriptAnalysis::analyzeSSA before running
     * the script the first time. When !needsArgsObj, the prologue may simply
     * write MagicValue(JS_OPTIMIZED_ARGUMENTS) to 'arguments's slot and any
     * uses of 'arguments' will be guaranteed to handle this magic value.
     * So avoid spurious arguments object creation, we maintain the invariant
     * that needsArgsObj is only called after the script has been analyzed.
     */
    bool analyzedArgsUsage() const { return !needsArgsAnalysis_; }
    bool needsArgsObj() const { JS_ASSERT(analyzedArgsUsage()); return needsArgsObj_; }
    void setNeedsArgsObj(bool needsArgsObj);
    static bool argumentsOptimizationFailed(JSContext *cx, js::HandleScript script);

    /*
     * Arguments access (via JSOP_*ARG* opcodes) must access the canonical
     * location for the argument. If an arguments object exists AND this is a
     * non-strict function (where 'arguments' aliases formals), then all access
     * must go through the arguments object. Otherwise, the local slot is the
     * canonical location for the arguments. Note: if a formal is aliased
     * through the scope chain, then script->formalIsAliased and JSOP_*ARG*
     * opcodes won't be emitted at all.
     */
    bool argsObjAliasesFormals() const {
        return needsArgsObj() && !strict;
    }

    bool hasAnyIonScript() const {
        return hasIonScript() || hasParallelIonScript();
    }

  private:
    /* Information attached by Baseline/Ion for sequential mode execution. */
    js::jit::IonScript *ion;
    js::jit::BaselineScript *baseline;

    /* Information attached by Ion for parallel mode execution */
    js::jit::IonScript *parallelIon;

#if JS_BITS_PER_WORD == 32
    uint32_t padding0;
#endif

    /*
     * Pointer to either baseline->method()->raw() or ion->method()->raw(), or NULL
     * if there's no Baseline or Ion script.
     */
    uint8_t *baselineOrIonRaw;
    uint8_t *baselineOrIonSkipArgCheck;

  public:
    bool hasIonScript() const {
        return ion && ion != ION_DISABLED_SCRIPT && ion != ION_COMPILING_SCRIPT;
    }
    bool canIonCompile() const {
        return ion != ION_DISABLED_SCRIPT;
    }

    bool isIonCompilingOffThread() const {
        return ion == ION_COMPILING_SCRIPT;
    }

    js::jit::IonScript *ionScript() const {
        JS_ASSERT(hasIonScript());
        return ion;
    }
    js::jit::IonScript *maybeIonScript() const {
        return ion;
    }
    js::jit::IonScript *const *addressOfIonScript() const {
        return &ion;
    }
    inline void setIonScript(js::jit::IonScript *ionScript);

    bool hasBaselineScript() const {
        return baseline && baseline != BASELINE_DISABLED_SCRIPT;
    }
    bool canBaselineCompile() const {
        return baseline != BASELINE_DISABLED_SCRIPT;
    }
    js::jit::BaselineScript *baselineScript() const {
        JS_ASSERT(hasBaselineScript());
        return baseline;
    }
    inline void setBaselineScript(js::jit::BaselineScript *baselineScript);

    void updateBaselineOrIonRaw();

    bool hasParallelIonScript() const {
        return parallelIon && parallelIon != ION_DISABLED_SCRIPT && parallelIon != ION_COMPILING_SCRIPT;
    }

    bool canParallelIonCompile() const {
        return parallelIon != ION_DISABLED_SCRIPT;
    }

    bool isParallelIonCompilingOffThread() const {
        return parallelIon == ION_COMPILING_SCRIPT;
    }

    js::jit::IonScript *parallelIonScript() const {
        JS_ASSERT(hasParallelIonScript());
        return parallelIon;
    }
    js::jit::IonScript *maybeParallelIonScript() const {
        return parallelIon;
    }
    inline void setParallelIonScript(js::jit::IonScript *ionScript);

    static size_t offsetOfBaselineScript() {
        return offsetof(JSScript, baseline);
    }
    static size_t offsetOfIonScript() {
        return offsetof(JSScript, ion);
    }
    static size_t offsetOfParallelIonScript() {
        return offsetof(JSScript, parallelIon);
    }
    static size_t offsetOfBaselineOrIonRaw() {
        return offsetof(JSScript, baselineOrIonRaw);
    }
    static size_t offsetOfBaselineOrIonSkipArgCheck() {
        return offsetof(JSScript, baselineOrIonSkipArgCheck);
    }

    /*
     * Original compiled function for the script, if it has a function.
     * NULL for global and eval scripts.
     */
    JSFunction *function() const { return function_; }
    inline void setFunction(JSFunction *fun);

    JSFunction *originalFunction() const;
    void setOriginalFunctionObject(JSObject *fun);

    JSFlatString *sourceData(JSContext *cx);

    static bool loadSource(JSContext *cx, js::HandleScript scr, bool *worked);

    void setSourceObject(js::ScriptSourceObject *object);
    js::ScriptSourceObject *sourceObject() const;
    js::ScriptSource *scriptSource() const { return sourceObject()->source(); }
    const char *filename() const { return scriptSource()->filename(); }

  public:

    /* Return whether this script was compiled for 'eval' */
    bool isForEval() { return isCachedEval || isActiveEval; }

#ifdef DEBUG
    unsigned id();
#else
    unsigned id() { return 0; }
#endif

    /* Ensure the script has a TypeScript. */
    inline bool ensureHasTypes(JSContext *cx);

    /* Ensure the script has a TypeScript and map for computing BytecodeTypes. */
    inline bool ensureHasBytecodeTypeMap(JSContext *cx);

    /*
     * Ensure the script has bytecode analysis information. Performed when the
     * script first runs, or first runs after a TypeScript GC purge.
     */
    inline bool ensureRanAnalysis(JSContext *cx);

    /* Ensure the script has type inference analysis information. */
    inline bool ensureRanInference(JSContext *cx);

    inline bool hasAnalysis();
    inline void clearAnalysis();
    inline js::analyze::ScriptAnalysis *analysis();

    /* Heuristic to check if the function is expected to be "short running". */
    bool isShortRunning();

    inline void clearPropertyReadTypes();

    inline js::GlobalObject &global() const;

    /* See StaticScopeIter comment. */
    JSObject *enclosingStaticScope() const {
        if (isCallsiteClone)
            return NULL;
        return enclosingScopeOrOriginalFunction_;
    }

    /*
     * If a compile error occurs in an enclosing function after parsing a
     * nested function, the enclosing function's JSFunction, which appears on
     * the nested function's enclosingScope chain, will be invalid. Normal VM
     * operation only sees scripts where all enclosing scripts have been
     * successfully compiled. Any path that may look at scripts left over from
     * unsuccessful compilation (e.g., by iterating over all scripts in the
     * compartment) should check this predicate before doing any operation that
     * uses enclosingScope (e.g., ScopeCoordinateName).
     */
    bool enclosingScriptsCompiledSuccessfully() const;

  private:
    bool makeTypes(JSContext *cx);
    bool makeBytecodeTypeMap(JSContext *cx);
    bool makeAnalysis(JSContext *cx);

  public:
    uint32_t getUseCount() const  { return useCount; }
    uint32_t incUseCount(uint32_t amount = 1) { return useCount += amount; }
    uint32_t *addressOfUseCount() { return &useCount; }
    static size_t offsetOfUseCount() { return offsetof(JSScript, useCount); }
    void resetUseCount() { useCount = 0; }

  public:
    bool initScriptCounts(JSContext *cx);
    js::PCCounts getPCCounts(jsbytecode *pc);
    void addIonCounts(js::jit::IonScriptCounts *ionCounts);
    js::jit::IonScriptCounts *getIonCounts();
    js::ScriptCounts releaseScriptCounts();
    void destroyScriptCounts(js::FreeOp *fop);

    jsbytecode *main() {
        return code + mainOffset;
    }

    /*
     * computedSizeOfData() is the in-use size of all the data sections.
     * sizeOfData() is the size of the block allocated to hold all the data sections
     * (which can be larger than the in-use size).
     */
    size_t computedSizeOfData();
    size_t sizeOfData(JSMallocSizeOfFun mallocSizeOf);

    uint32_t numNotes();  /* Number of srcnote slots in the srcnotes section */

    /* Script notes are allocated right after the code. */
    jssrcnote *notes() { return (jssrcnote *)(code + length); }

    bool hasArray(ArrayKind kind)           { return (hasArrayBits & (1 << kind)); }
    void setHasArray(ArrayKind kind)        { hasArrayBits |= (1 << kind); }
    void cloneHasArray(JSScript *script) { hasArrayBits = script->hasArrayBits; }

    bool hasConsts()        { return hasArray(CONSTS);      }
    bool hasObjects()       { return hasArray(OBJECTS);     }
    bool hasRegexps()       { return hasArray(REGEXPS);     }
    bool hasTrynotes()      { return hasArray(TRYNOTES);    }

    #define OFF(fooOff, hasFoo, t)   (fooOff() + (hasFoo() ? sizeof(t) : 0))

    size_t constsOffset()     { return 0; }
    size_t objectsOffset()    { return OFF(constsOffset,     hasConsts,     js::ConstArray);      }
    size_t regexpsOffset()    { return OFF(objectsOffset,    hasObjects,    js::ObjectArray);     }
    size_t trynotesOffset()   { return OFF(regexpsOffset,    hasRegexps,    js::ObjectArray);     }

    js::ConstArray *consts() {
        JS_ASSERT(hasConsts());
        return reinterpret_cast<js::ConstArray *>(data + constsOffset());
    }

    js::ObjectArray *objects() {
        JS_ASSERT(hasObjects());
        return reinterpret_cast<js::ObjectArray *>(data + objectsOffset());
    }

    js::ObjectArray *regexps() {
        JS_ASSERT(hasRegexps());
        return reinterpret_cast<js::ObjectArray *>(data + regexpsOffset());
    }

    js::TryNoteArray *trynotes() {
        JS_ASSERT(hasTrynotes());
        return reinterpret_cast<js::TryNoteArray *>(data + trynotesOffset());
    }

    js::HeapPtrAtom &getAtom(size_t index) const {
        JS_ASSERT(index < natoms);
        return atoms[index];
    }

    js::HeapPtrAtom &getAtom(jsbytecode *pc) const {
        JS_ASSERT(pc >= code && pc + sizeof(uint32_t) < code + length);
        return getAtom(GET_UINT32_INDEX(pc));
    }

    js::PropertyName *getName(size_t index) {
        return getAtom(index)->asPropertyName();
    }

    js::PropertyName *getName(jsbytecode *pc) const {
        JS_ASSERT(pc >= code && pc + sizeof(uint32_t) < code + length);
        return getAtom(GET_UINT32_INDEX(pc))->asPropertyName();
    }

    JSObject *getObject(size_t index) {
        js::ObjectArray *arr = objects();
        JS_ASSERT(index < arr->length);
        return arr->vector[index];
    }

    size_t innerObjectsStart() {
        // The first object contains the caller if savedCallerFun is used.
        return savedCallerFun ? 1 : 0;
    }

    JSObject *getObject(jsbytecode *pc) {
        JS_ASSERT(pc >= code && pc + sizeof(uint32_t) < code + length);
        return getObject(GET_UINT32_INDEX(pc));
    }

    JSVersion getVersion() const {
        return JSVersion(version);
    }

    inline JSFunction *getFunction(size_t index);
    inline JSFunction *getCallerFunction();
    inline JSFunction *functionOrCallerFunction();

    inline js::RegExpObject *getRegExp(size_t index);

    const js::Value &getConst(size_t index) {
        js::ConstArray *arr = consts();
        JS_ASSERT(index < arr->length);
        return arr->vector[index];
    }

    /*
     * The isEmpty method tells whether this script has code that computes any
     * result (not return value, result AKA normal completion value) other than
     * JSVAL_VOID, or any other effects.
     */
    inline bool isEmpty() const;

    bool varIsAliased(unsigned varSlot);
    bool formalIsAliased(unsigned argSlot);
    bool formalLivesInArgumentsObject(unsigned argSlot);

  private:
    /*
     * Recompile with or without single-stepping support, as directed
     * by stepModeEnabled().
     */
    void recompileForStepMode(js::FreeOp *fop);

    /* Attempt to change this->stepMode to |newValue|. */
    bool tryNewStepMode(JSContext *cx, uint32_t newValue);

    bool ensureHasDebugScript(JSContext *cx);
    js::DebugScript *debugScript();
    js::DebugScript *releaseDebugScript();
    void destroyDebugScript(js::FreeOp *fop);

  public:
    bool hasBreakpointsAt(jsbytecode *pc);
    bool hasAnyBreakpointsOrStepMode() { return hasDebugScript; }

    js::BreakpointSite *getBreakpointSite(jsbytecode *pc)
    {
        JS_ASSERT(size_t(pc - code) < length);
        return hasDebugScript ? debugScript()->breakpoints[pc - code] : NULL;
    }

    js::BreakpointSite *getOrCreateBreakpointSite(JSContext *cx, jsbytecode *pc);

    void destroyBreakpointSite(js::FreeOp *fop, jsbytecode *pc);

    void clearBreakpointsIn(js::FreeOp *fop, js::Debugger *dbg, JSObject *handler);
    void clearTraps(js::FreeOp *fop);

    void markTrapClosures(JSTracer *trc);

    /*
     * Set or clear the single-step flag. If the flag is set or the count
     * (adjusted by changeStepModeCount) is non-zero, then the script is in
     * single-step mode. (JSD uses an on/off-style interface; Debugger uses a
     * count-style interface.)
     */
    bool setStepModeFlag(JSContext *cx, bool step);

    /*
     * Increment or decrement the single-step count. If the count is non-zero or
     * the flag (set by setStepModeFlag) is set, then the script is in
     * single-step mode. (JSD uses an on/off-style interface; Debugger uses a
     * count-style interface.)
     */
    bool changeStepModeCount(JSContext *cx, int delta);

    bool stepModeEnabled() { return hasDebugScript && !!debugScript()->stepMode; }

#ifdef DEBUG
    uint32_t stepModeCount() { return hasDebugScript ? (debugScript()->stepMode & stepCountMask) : 0; }
#endif

    void finalize(js::FreeOp *fop);

    JS::Zone *zone() const { return tenuredZone(); }

    static inline void writeBarrierPre(JSScript *script);
    static inline void writeBarrierPost(JSScript *script, void *addr);

    static inline js::ThingRootKind rootKind() { return js::THING_ROOT_SCRIPT; }

    static JSPrincipals *normalizeOriginPrincipals(JSPrincipals *principals,
                                                   JSPrincipals *originPrincipals) {
        return originPrincipals ? originPrincipals : principals;
    }

    void markChildren(JSTracer *trc);
};

JS_STATIC_ASSERT(sizeof(JSScript::ArrayBitsT) * 8 >= JSScript::LIMIT);

/* If this fails, add/remove padding within JSScript. */
JS_STATIC_ASSERT(sizeof(JSScript) % js::gc::CellSize == 0);

namespace js {

/*
 * Iterator over a script's bindings (formals and variables).
 * The order of iteration is:
 *  - first, formal arguments, from index 0 to numArgs
 *  - next, variables, from index 0 to numVars
 */
class BindingIter
{
    const InternalBindingsHandle bindings_;
    unsigned i_;

    friend class Bindings;

  public:
    explicit BindingIter(const InternalBindingsHandle &bindings) : bindings_(bindings), i_(0) {}
    explicit BindingIter(const HandleScript &script) : bindings_(script, &script->bindings), i_(0) {}

    bool done() const { return i_ == bindings_->count(); }
    operator bool() const { return !done(); }
    void operator++(int) { JS_ASSERT(!done()); i_++; }
    BindingIter &operator++() { (*this)++; return *this; }

    unsigned frameIndex() const {
        JS_ASSERT(!done());
        return i_ < bindings_->numArgs() ? i_ : i_ - bindings_->numArgs();
    }

    const Binding &operator*() const { JS_ASSERT(!done()); return bindings_->bindingArray()[i_]; }
    const Binding *operator->() const { JS_ASSERT(!done()); return &bindings_->bindingArray()[i_]; }
};

/*
 * This helper function fills the given BindingVector with the sequential
 * values of BindingIter.
 */

typedef Vector<Binding, 32> BindingVector;

extern bool
FillBindingVector(HandleScript fromScript, BindingVector *vec);

/*
 * Iterator over the aliased formal bindings in ascending index order. This can
 * be veiwed as a filtering of BindingIter with predicate
 *   bi->aliased() && bi->kind() == ARGUMENT
 */
class AliasedFormalIter
{
    const Binding *begin_, *p_, *end_;
    unsigned slot_;

    void settle() {
        while (p_ != end_ && !p_->aliased())
            p_++;
    }

  public:
    explicit inline AliasedFormalIter(JSScript *script);

    bool done() const { return p_ == end_; }
    operator bool() const { return !done(); }
    void operator++(int) { JS_ASSERT(!done()); p_++; slot_++; settle(); }

    const Binding &operator*() const { JS_ASSERT(!done()); return *p_; }
    const Binding *operator->() const { JS_ASSERT(!done()); return p_; }
    unsigned frameIndex() const { JS_ASSERT(!done()); return p_ - begin_; }
    unsigned scopeSlot() const { JS_ASSERT(!done()); return slot_; }
};

struct SourceCompressionToken;

// Information about a script which may be (or has been) lazily compiled to
// bytecode from its source.
class LazyScript : public js::gc::Cell
{
    // If non-NULL, the script has been compiled and this is a forwarding
    // pointer to the result.
    HeapPtrScript script_;

    // Original function with which the lazy script is associated.
    HeapPtrFunction function_;

    // Function or block chain in which the script is nested, or NULL.
    HeapPtrObject enclosingScope_;

    // Source code object, or NULL if the script in which this is nested has
    // not been compiled yet.
    HeapPtrObject sourceObject_;

    // Heap allocated table with any free variables or inner functions.
    void *table_;

    // Assorted bits that should really be in ScriptSourceObject.
    JSPrincipals *originPrincipals_;
    uint32_t version_ : 8;

    uint32_t numFreeVariables_ : 24;
    uint32_t numInnerFunctions_ : 26;

    // N.B. These are booleans but need to be uint32_t to pack correctly on MSVC.
    uint32_t strict_ : 1;
    uint32_t bindingsAccessedDynamically_ : 1;
    uint32_t hasDebuggerStatement_ : 1;
    uint32_t directlyInsideEval_:1;
    uint32_t usesArgumentsAndApply_:1;
    uint32_t hasBeenCloned_:1;

    // Source location for the script.
    uint32_t begin_;
    uint32_t end_;
    uint32_t lineno_;
    uint32_t column_;

    LazyScript(JSFunction *fun, void *table,
               uint32_t numFreeVariables, uint32_t numInnerFunctions, JSVersion version,
               uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column);

  public:
    static LazyScript *Create(JSContext *cx, HandleFunction fun,
                              uint32_t numFreeVariables, uint32_t numInnerFunctions,
                              JSVersion version, uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column);

    JSFunction *function() const {
        return function_;
    }

    void initScript(JSScript *script);
    JSScript *maybeScript() {
        return script_;
    }

    JSObject *enclosingScope() const {
        return enclosingScope_;
    }
    ScriptSourceObject *sourceObject() const;
    JSPrincipals *originPrincipals() const {
        return originPrincipals_;
    }
    JSVersion version() const {
        JS_STATIC_ASSERT(JSVERSION_UNKNOWN == -1);
        return (version_ == JS_BIT(8) - 1) ? JSVERSION_UNKNOWN : JSVersion(version_);
    }

    void setParent(JSObject *enclosingScope, ScriptSourceObject *sourceObject,
                   JSPrincipals *originPrincipals);

    uint32_t numFreeVariables() const {
        return numFreeVariables_;
    }
    HeapPtrAtom *freeVariables() {
        return (HeapPtrAtom *)table_;
    }

    uint32_t numInnerFunctions() const {
        return numInnerFunctions_;
    }
    HeapPtrFunction *innerFunctions() {
        return (HeapPtrFunction *)&freeVariables()[numFreeVariables()];
    }

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

    bool bindingsAccessedDynamically() const {
        return bindingsAccessedDynamically_;
    }
    void setBindingsAccessedDynamically() {
        bindingsAccessedDynamically_ = true;
    }

    bool hasDebuggerStatement() const {
        return hasDebuggerStatement_;
    }
    void setHasDebuggerStatement() {
        hasDebuggerStatement_ = true;
    }

    bool directlyInsideEval() const {
        return directlyInsideEval_;
    }
    void setDirectlyInsideEval() {
        directlyInsideEval_ = true;
    }

    bool usesArgumentsAndApply() const {
        return usesArgumentsAndApply_;
    }
    void setUsesArgumentsAndApply() {
        usesArgumentsAndApply_ = true;
    }

    bool hasBeenCloned() const {
        return hasBeenCloned_;
    }
    void setHasBeenCloned() {
        hasBeenCloned_ = true;
    }

    ScriptSource *source() const {
        return sourceObject()->source();
    }
    uint32_t begin() const {
        return begin_;
    }
    uint32_t end() const {
        return end_;
    }
    uint32_t lineno() const {
        return lineno_;
    }
    uint32_t column() const {
        return column_;
    }

    uint32_t staticLevel(JSContext *cx) const;

    Zone *zone() const {
        return Cell::tenuredZone();
    }

    void markChildren(JSTracer *trc);
    void finalize(js::FreeOp *fop);

    size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf)
    {
        return mallocSizeOf(table_);
    }

    static inline void writeBarrierPre(LazyScript *lazy);
};

#ifdef JS_THREADSAFE
/*
 * Background thread to compress JS source code. This happens only while parsing
 * and bytecode generation is happening in the main thread. If needed, the
 * compiler waits for compression to complete before returning.
 *
 * To use it, you have to have a SourceCompressionToken, tok, with tok.ss and
 * tok.chars set to the proper values. When the SourceCompressionToken is
 * destroyed, it makes sure the compression is complete. If you are about to
 * successfully exit the scope of tok, you should call and check the return
 * value of SourceCompressionToken::complete(). It returns false if allocation
 * errors occurred in the thread.
 */
class SourceCompressorThread
{
  private:
    enum {
        // The compression thread is in the process of compression some source.
        COMPRESSING,
        // The compression thread is not doing anything and available to
        // compress source.
        IDLE,
        // Set by finish() to tell the compression thread to exit.
        SHUTDOWN
    } state;
    SourceCompressionToken *tok;
    PRThread *thread;
    // Protects |state| and |tok| when it's non-NULL.
    PRLock *lock;
    // When it's idling, the compression thread blocks on this. The main thread
    // uses it to notify the compression thread when it has source to be
    // compressed.
    PRCondVar *wakeup;
    // The main thread can block on this to wait for compression to finish.
    PRCondVar *done;
    // Flag which can be set by the main thread to ask compression to abort.
    volatile bool stop;

    bool internalCompress();
    void threadLoop();
    static void compressorThread(void *arg);

  public:
    explicit SourceCompressorThread()
    : state(IDLE),
      tok(NULL),
      thread(NULL),
      lock(NULL),
      wakeup(NULL),
      done(NULL) {}
    void finish();
    bool init();
    void compress(SourceCompressionToken *tok);
    void waitOnCompression(SourceCompressionToken *userTok);
    void abort(SourceCompressionToken *userTok);
    const jschar *currentChars() const;
};
#endif

struct SourceCompressionToken
{
    friend struct ScriptSource;
    friend class SourceCompressorThread;
  private:
    JSContext *cx;
    ScriptSource *ss;
    const jschar *chars;
    bool oom;
  public:
    explicit SourceCompressionToken(JSContext *cx)
       : cx(cx), ss(NULL), chars(NULL), oom(false) {}
    ~SourceCompressionToken()
    {
        complete();
    }

    bool complete();
    void abort();
    bool active() const { return !!ss; }
};

/*
 * New-script-hook calling is factored from JSScript::fullyInitFromEmitter() so
 * that it and callers of XDRScript() can share this code.  In the case of
 * callers of XDRScript(), the hook should be invoked only after successful
 * decode of any owning function (the fun parameter) or script object (null
 * fun).
 */
extern void
CallNewScriptHook(JSContext *cx, JS::HandleScript script, JS::HandleFunction fun);

extern void
CallDestroyScriptHook(FreeOp *fop, JSScript *script);

struct SharedScriptData
{
    bool marked;
    uint32_t length;
    jsbytecode data[1];

    static SharedScriptData *new_(JSContext *cx, uint32_t codeLength,
                                             uint32_t srcnotesLength, uint32_t natoms);

    HeapPtrAtom *atoms(uint32_t codeLength, uint32_t srcnotesLength) {
        uint32_t length = codeLength + srcnotesLength;
        return reinterpret_cast<HeapPtrAtom *>(data + length + sizeof(JSAtom *) -
                                               length % sizeof(JSAtom *));
    }

    static SharedScriptData *fromBytecode(const jsbytecode *bytecode) {
        return (SharedScriptData *)(bytecode - offsetof(SharedScriptData, data));
    }
};

/*
 * Takes ownership of its *ssd parameter and either adds it into the runtime's
 * ScriptBytecodeTable or frees it if a matching entry already exists.
 *
 * Sets the |code| and |atoms| fields on the given JSScript.
 */
extern bool
SaveSharedScriptData(JSContext *cx, Handle<JSScript *> script, SharedScriptData *ssd);

struct ScriptBytecodeHasher
{
    struct Lookup
    {
        jsbytecode          *code;
        uint32_t            length;

        Lookup(SharedScriptData *ssd) : code(ssd->data), length(ssd->length) {}
    };
    static HashNumber hash(const Lookup &l) { return mozilla::HashBytes(l.code, l.length); }
    static bool match(SharedScriptData *entry, const Lookup &lookup) {
        if (entry->length != lookup.length)
            return false;
        return mozilla::PodEqual<jsbytecode>(entry->data, lookup.code, lookup.length);
    }
};

typedef HashSet<SharedScriptData*,
                ScriptBytecodeHasher,
                SystemAllocPolicy> ScriptDataTable;

inline void
MarkScriptBytecode(JSRuntime *rt, const jsbytecode *bytecode);

extern void
SweepScriptData(JSRuntime *rt);

extern void
FreeScriptData(JSRuntime *rt);

struct ScriptAndCounts
{
    /* This structure is stored and marked from the JSRuntime. */
    JSScript *script;
    ScriptCounts scriptCounts;

    PCCounts &getPCCounts(jsbytecode *pc) const {
        JS_ASSERT(unsigned(pc - script->code) < script->length);
        return scriptCounts.pcCountsVector[pc - script->code];
    }

    jit::IonScriptCounts *getIonCounts() const {
        return scriptCounts.ionCounts;
    }
};

} /* namespace js */

extern jssrcnote *
js_GetSrcNote(JSContext *cx, JSScript *script, jsbytecode *pc);

extern jsbytecode *
js_LineNumberToPC(JSScript *script, unsigned lineno);

extern JS_FRIEND_API(unsigned)
js_GetScriptLineExtent(JSScript *script);

namespace js {

extern unsigned
PCToLineNumber(JSScript *script, jsbytecode *pc, unsigned *columnp = NULL);

extern unsigned
PCToLineNumber(unsigned startLine, jssrcnote *notes, jsbytecode *code, jsbytecode *pc,
               unsigned *columnp = NULL);

/*
 * This function returns the file and line number of the script currently
 * executing on cx. If there is no current script executing on cx (e.g., a
 * native called directly through JSAPI (e.g., by setTimeout)), NULL and 0 are
 * returned as the file and line. Additionally, this function avoids the full
 * linear scan to compute line number when the caller guarnatees that the
 * script compilation occurs at a JSOP_EVAL.
 */

enum LineOption {
    CALLED_FROM_JSOP_EVAL,
    NOT_CALLED_FROM_JSOP_EVAL
};

inline void
CurrentScriptFileLineOrigin(JSContext *cx, unsigned *linenop, LineOption = NOT_CALLED_FROM_JSOP_EVAL);

extern JSScript *
CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, HandleScript script,
            NewObjectKind newKind = GenericObject);

bool
CloneFunctionScript(JSContext *cx, HandleFunction original, HandleFunction clone,
                    NewObjectKind newKind = GenericObject);

/*
 * NB: after a successful XDR_DECODE, XDRScript callers must do any required
 * subsequent set-up of owning function or script object and then call
 * js_CallNewScriptHook.
 */
template<XDRMode mode>
bool
XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enclosingScript,
          HandleFunction fun, MutableHandleScript scriptp);

} /* namespace js */

#endif /* jsscript_h */
