/* -*- 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 jspubtd_h
#define jspubtd_h

/*
 * JS public API typedefs.
 */

#include "mozilla/Assertions.h"
#include "mozilla/LinkedList.h"
#include "mozilla/PodOperations.h"

#include "jsprototypes.h"
#include "jstypes.h"

#include "js/TypeDecls.h"

# define JSGC_HASH_TABLE_CHECKS

namespace JS {

template <typename T>
class AutoVectorRooter;
typedef AutoVectorRooter<jsid> AutoIdVector;
class CallArgs;

template <typename T>
class Rooted;

class JS_FRIEND_API(CompileOptions);
class JS_FRIEND_API(ReadOnlyCompileOptions);
class JS_FRIEND_API(OwningCompileOptions);
class JS_FRIEND_API(TransitiveCompileOptions);
class JS_PUBLIC_API(CompartmentOptions);

class Value;
struct Zone;

} /* namespace JS */

namespace js {
struct ContextFriendFields;
class RootLists;
} // namespace js

/*
 * Run-time version enumeration.  For compile-time version checking, please use
 * the JS_HAS_* macros in jsversion.h, or use MOZJS_MAJOR_VERSION,
 * MOZJS_MINOR_VERSION, MOZJS_PATCH_VERSION, and MOZJS_ALPHA definitions.
 */
enum JSVersion {
    JSVERSION_ECMA_3  = 148,
    JSVERSION_1_6     = 160,
    JSVERSION_1_7     = 170,
    JSVERSION_1_8     = 180,
    JSVERSION_ECMA_5  = 185,
    JSVERSION_DEFAULT = 0,
    JSVERSION_UNKNOWN = -1,
    JSVERSION_LATEST  = JSVERSION_ECMA_5
};

/* Result of typeof operator enumeration. */
enum JSType {
    JSTYPE_VOID,                /* undefined */
    JSTYPE_OBJECT,              /* object */
    JSTYPE_FUNCTION,            /* function */
    JSTYPE_STRING,              /* string */
    JSTYPE_NUMBER,              /* number */
    JSTYPE_BOOLEAN,             /* boolean */
    JSTYPE_NULL,                /* null */
    JSTYPE_SYMBOL,              /* symbol */
    JSTYPE_LIMIT
};

/* Dense index into cached prototypes and class atoms for standard objects. */
enum JSProtoKey {
#define PROTOKEY_AND_INITIALIZER(name,code,init,clasp) JSProto_##name = code,
    JS_FOR_EACH_PROTOTYPE(PROTOKEY_AND_INITIALIZER)
#undef PROTOKEY_AND_INITIALIZER
    JSProto_LIMIT
};

/* Struct forward declarations. */
struct JSClass;
struct JSCompartment;
struct JSCrossCompartmentCall;
class JSErrorReport;
struct JSExceptionState;
struct JSFunctionSpec;
struct JSLocaleCallbacks;
struct JSObjectMap;
struct JSPrincipals;
struct JSPropertyDescriptor;
struct JSPropertyName;
struct JSPropertySpec;
struct JSRuntime;
struct JSSecurityCallbacks;
struct JSStructuredCloneCallbacks;
struct JSStructuredCloneReader;
struct JSStructuredCloneWriter;
class JS_PUBLIC_API(JSTracer);

class JSFlatString;

typedef struct PRCallOnceType   JSCallOnceType;
typedef bool                    (*JSInitCallback)(void);

template<typename T> struct JSConstScalarSpec;
typedef JSConstScalarSpec<double> JSConstDoubleSpec;
typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec;

/*
 * Generic trace operation that calls JS_CallTracer on each traceable thing
 * stored in data.
 */
typedef void
(* JSTraceDataOp)(JSTracer* trc, void* data);

namespace js {

void FinishGC(JSRuntime* rt);

namespace gc {
class AutoTraceSession;
class StoreBuffer;
void MarkPersistentRootedChains(JSTracer*);
void MarkPersistentRootedChainsInLists(js::RootLists&, JSTracer*);
void FinishPersistentRootedChains(js::RootLists&);
} // namespace gc
} // namespace js

namespace JS {

typedef void (*OffThreadCompileCallback)(void* token, void* callbackData);

enum class HeapState {
    Idle,             // doing nothing with the GC heap
    Tracing,          // tracing the GC heap without collecting, e.g. IterateCompartments()
    MajorCollecting,  // doing a GC of the major heap
    MinorCollecting   // doing a GC of the minor heap (nursery)
};

namespace shadow {

struct Runtime
{
  protected:
    // Allow inlining of heapState checks.
    friend class js::gc::AutoTraceSession;
    JS::HeapState heapState_;

    js::gc::StoreBuffer* gcStoreBufferPtr_;

  public:
    Runtime()
      : heapState_(JS::HeapState::Idle)
      , gcStoreBufferPtr_(nullptr)
    {}

    bool isHeapBusy() const { return heapState_ != JS::HeapState::Idle; }
    bool isHeapMajorCollecting() const { return heapState_ == JS::HeapState::MajorCollecting; }
    bool isHeapMinorCollecting() const { return heapState_ == JS::HeapState::MinorCollecting; }
    bool isHeapCollecting() const { return isHeapMinorCollecting() || isHeapMajorCollecting(); }

    js::gc::StoreBuffer* gcStoreBufferPtr() { return gcStoreBufferPtr_; }

    static JS::shadow::Runtime* asShadowRuntime(JSRuntime* rt) {
        return reinterpret_cast<JS::shadow::Runtime*>(rt);
    }

  protected:
    void setGCStoreBufferPtr(js::gc::StoreBuffer* storeBuffer) {
        gcStoreBufferPtr_ = storeBuffer;
    }
};

} /* namespace shadow */

class JS_PUBLIC_API(AutoGCRooter)
{
  public:
    AutoGCRooter(JSContext* cx, ptrdiff_t tag);
    AutoGCRooter(js::ContextFriendFields* cx, ptrdiff_t tag);

    ~AutoGCRooter() {
        MOZ_ASSERT(this == *stackTop);
        *stackTop = down;
    }

    /* Implemented in gc/RootMarking.cpp. */
    inline void trace(JSTracer* trc);
    static void traceAll(JSTracer* trc);
    static void traceAllWrappers(JSTracer* trc);

    /* T must be a context type */
    template<typename T>
    static void traceAllInContext(T* cx, JSTracer* trc) {
        for (AutoGCRooter* gcr = cx->roots.autoGCRooters_; gcr; gcr = gcr->down)
            gcr->trace(trc);
    }

  protected:
    AutoGCRooter * const down;

    /*
     * Discriminates actual subclass of this being used.  If non-negative, the
     * subclass roots an array of values of the length stored in this field.
     * If negative, meaning is indicated by the corresponding value in the enum
     * below.  Any other negative value indicates some deeper problem such as
     * memory corruption.
     */
    ptrdiff_t tag_;

    enum {
        VALARRAY =     -2, /* js::AutoValueArray */
        PARSER =       -3, /* js::frontend::Parser */
        VALVECTOR =   -10, /* js::AutoValueVector */
        IDVECTOR =    -11, /* js::AutoIdVector */
        OBJVECTOR =   -14, /* js::AutoObjectVector */
        IONMASM =     -19, /* js::jit::MacroAssembler */
        WRAPVECTOR =  -20, /* js::AutoWrapperVector */
        WRAPPER =     -21, /* js::AutoWrapperRooter */
        CUSTOM =      -26  /* js::CustomAutoRooter */
    };

    static ptrdiff_t GetTag(const Value& value) { return VALVECTOR; }
    static ptrdiff_t GetTag(const jsid& id) { return IDVECTOR; }
    static ptrdiff_t GetTag(JSObject* obj) { return OBJVECTOR; }

  private:
    AutoGCRooter ** const stackTop;

    /* No copy or assignment semantics. */
    AutoGCRooter(AutoGCRooter& ida) = delete;
    void operator=(AutoGCRooter& ida) = delete;
};

} /* namespace JS */

namespace js {

class ExclusiveContext;

/*
 * This list enumerates the different types of conceptual stacks we have in
 * SpiderMonkey. In reality, they all share the C stack, but we allow different
 * stack limits depending on the type of code running.
 */
enum StackKind
{
    StackForSystemCode,      // C++, such as the GC, running on behalf of the VM.
    StackForTrustedScript,   // Script running with trusted principals.
    StackForUntrustedScript, // Script running with untrusted principals.
    StackKindCount
};

enum ThingRootKind
{
    THING_ROOT_OBJECT,
    THING_ROOT_SHAPE,
    THING_ROOT_BASE_SHAPE,
    THING_ROOT_OBJECT_GROUP,
    THING_ROOT_STRING,
    THING_ROOT_SYMBOL,
    THING_ROOT_JIT_CODE,
    THING_ROOT_SCRIPT,
    THING_ROOT_LAZY_SCRIPT,
    THING_ROOT_ID,
    THING_ROOT_VALUE,
    THING_ROOT_TRACEABLE,
    THING_ROOT_LIMIT
};

template <typename T>
struct RootKind;

/*
 * Specifically mark the ThingRootKind of externally visible types, so that
 * JSAPI users may use JSRooted... types without having the class definition
 * available.
 */
template<typename T, ThingRootKind Kind>
struct SpecificRootKind
{
    static ThingRootKind rootKind() { return Kind; }
};

template <> struct RootKind<JSObject*> : SpecificRootKind<JSObject*, THING_ROOT_OBJECT> {};
template <> struct RootKind<JSFlatString*> : SpecificRootKind<JSFlatString*, THING_ROOT_STRING> {};
template <> struct RootKind<JSFunction*> : SpecificRootKind<JSFunction*, THING_ROOT_OBJECT> {};
template <> struct RootKind<JSString*> : SpecificRootKind<JSString*, THING_ROOT_STRING> {};
template <> struct RootKind<JS::Symbol*> : SpecificRootKind<JS::Symbol*, THING_ROOT_SYMBOL> {};
template <> struct RootKind<JSScript*> : SpecificRootKind<JSScript*, THING_ROOT_SCRIPT> {};
template <> struct RootKind<jsid> : SpecificRootKind<jsid, THING_ROOT_ID> {};
template <> struct RootKind<JS::Value> : SpecificRootKind<JS::Value, THING_ROOT_VALUE> {};

// Abstracts JS rooting mechanisms so they can be shared between the JSContext
// and JSRuntime.
class RootLists
{
    // Stack GC roots for stack-allocated GC heap pointers.
    JS::Rooted<void*>* stackRoots_[THING_ROOT_LIMIT];
    template <typename T> friend class JS::Rooted;

    // Stack GC roots for stack-allocated AutoFooRooter classes.
    JS::AutoGCRooter* autoGCRooters_;
    friend class JS::AutoGCRooter;

  public:
    RootLists() : autoGCRooters_(nullptr) {
        mozilla::PodArrayZero(stackRoots_);
    }

    template <class T>
    inline JS::Rooted<T>* gcRooters() {
        js::ThingRootKind kind = RootKind<T>::rootKind();
        return reinterpret_cast<JS::Rooted<T>*>(stackRoots_[kind]);
    }

    void checkNoGCRooters();

    /* Allow inlining of PersistentRooted constructors and destructors. */
  private:
    template <typename Referent> friend class JS::PersistentRooted;
    friend void js::gc::MarkPersistentRootedChains(JSTracer*);
    friend void js::gc::MarkPersistentRootedChainsInLists(RootLists&, JSTracer*);
    friend void js::gc::FinishPersistentRootedChains(RootLists&);

    mozilla::LinkedList<JS::PersistentRooted<void*>> heapRoots_[THING_ROOT_LIMIT];

    /* Specializations of this return references to the appropriate list. */
    template<typename Referent>
    inline mozilla::LinkedList<JS::PersistentRooted<Referent>>& getPersistentRootedList();
};

template<>
inline mozilla::LinkedList<JS::PersistentRootedFunction>&
RootLists::getPersistentRootedList<JSFunction*>() {
    return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<JSFunction*>>&>(
        heapRoots_[THING_ROOT_OBJECT]);
}

template<>
inline mozilla::LinkedList<JS::PersistentRootedObject>&
RootLists::getPersistentRootedList<JSObject*>() {
    return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<JSObject*>>&>(
        heapRoots_[THING_ROOT_OBJECT]);
}

template<>
inline mozilla::LinkedList<JS::PersistentRootedId>&
RootLists::getPersistentRootedList<jsid>() {
    return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<jsid>>&>(
        heapRoots_[THING_ROOT_ID]);
}

template<>
inline mozilla::LinkedList<JS::PersistentRootedScript>&
RootLists::getPersistentRootedList<JSScript*>() {
    return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<JSScript*>>&>(
        heapRoots_[THING_ROOT_SCRIPT]);
}

template<>
inline mozilla::LinkedList<JS::PersistentRootedString>&
RootLists::getPersistentRootedList<JSString*>() {
    return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<JSString*>>&>(
        heapRoots_[THING_ROOT_STRING]);
}

template<>
inline mozilla::LinkedList<JS::PersistentRootedValue>&
RootLists::getPersistentRootedList<JS::Value>() {
    return reinterpret_cast<mozilla::LinkedList<JS::PersistentRooted<JS::Value>>&>(
        heapRoots_[THING_ROOT_VALUE]);
}

struct ContextFriendFields
{
  protected:
    JSRuntime* const     runtime_;

    /* The current compartment. */
    JSCompartment*      compartment_;

    /* The current zone. */
    JS::Zone*           zone_;

  public:
    /* Rooting structures. */
    RootLists           roots;

    explicit ContextFriendFields(JSRuntime* rt)
      : runtime_(rt), compartment_(nullptr), zone_(nullptr)
    {}

    static const ContextFriendFields* get(const JSContext* cx) {
        return reinterpret_cast<const ContextFriendFields*>(cx);
    }

    static ContextFriendFields* get(JSContext* cx) {
        return reinterpret_cast<ContextFriendFields*>(cx);
    }

    friend JSRuntime* GetRuntime(const JSContext* cx);
    friend JSCompartment* GetContextCompartment(const JSContext* cx);
    friend JS::Zone* GetContextZone(const JSContext* cx);
    template <typename T> friend class JS::Rooted;
};

/*
 * Inlinable accessors for JSContext.
 *
 * - These must not be available on the more restricted superclasses of
 *   JSContext, so we can't simply define them on ContextFriendFields.
 *
 * - They're perfectly ordinary JSContext functionality, so ought to be
 *   usable without resorting to jsfriendapi.h, and when JSContext is an
 *   incomplete type.
 */
inline JSRuntime*
GetRuntime(const JSContext* cx)
{
    return ContextFriendFields::get(cx)->runtime_;
}

inline JSCompartment*
GetContextCompartment(const JSContext* cx)
{
    return ContextFriendFields::get(cx)->compartment_;
}

inline JS::Zone*
GetContextZone(const JSContext* cx)
{
    return ContextFriendFields::get(cx)->zone_;
}

class PerThreadData;

struct PerThreadDataFriendFields
{
  private:
    // Note: this type only exists to permit us to derive the offset of
    // the perThread data within the real JSRuntime* type in a portable
    // way.
    struct RuntimeDummy : JS::shadow::Runtime
    {
        struct PerThreadDummy {
            void* field1;
            uintptr_t field2;
#ifdef JS_DEBUG
            uint64_t field3;
#endif
        } mainThread;
    };

  public:
    /* Rooting structures. */
    RootLists roots;

    PerThreadDataFriendFields();

    /* Limit pointer for checking native stack consumption. */
    uintptr_t nativeStackLimit[js::StackKindCount];

    static const size_t RuntimeMainThreadOffset = offsetof(RuntimeDummy, mainThread);

    static inline PerThreadDataFriendFields* get(js::PerThreadData* pt) {
        return reinterpret_cast<PerThreadDataFriendFields*>(pt);
    }

    static inline PerThreadDataFriendFields* getMainThread(JSRuntime* rt) {
        // mainThread must always appear directly after |JS::shadow::Runtime|.
        // Tested by a JS_STATIC_ASSERT in |jsfriendapi.cpp|
        return reinterpret_cast<PerThreadDataFriendFields*>(
            reinterpret_cast<char*>(rt) + RuntimeMainThreadOffset);
    }

    static inline const PerThreadDataFriendFields* getMainThread(const JSRuntime* rt) {
        // mainThread must always appear directly after |JS::shadow::Runtime|.
        // Tested by a JS_STATIC_ASSERT in |jsfriendapi.cpp|
        return reinterpret_cast<const PerThreadDataFriendFields*>(
            reinterpret_cast<const char*>(rt) + RuntimeMainThreadOffset);
    }

    template <typename T> friend class JS::Rooted;
};

} /* namespace js */

#endif /* jspubtd_h */
