michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef jspubtd_h michael@0: #define jspubtd_h michael@0: michael@0: /* michael@0: * JS public API typedefs. michael@0: */ michael@0: michael@0: #include "mozilla/LinkedList.h" michael@0: #include "mozilla/NullPtr.h" michael@0: #include "mozilla/PodOperations.h" michael@0: michael@0: #include "jsprototypes.h" michael@0: #include "jstypes.h" michael@0: michael@0: #include "js/TypeDecls.h" michael@0: michael@0: #if defined(JSGC_USE_EXACT_ROOTING) || defined(JS_DEBUG) michael@0: # define JSGC_TRACK_EXACT_ROOTS michael@0: #endif michael@0: michael@0: namespace JS { michael@0: michael@0: class AutoIdVector; michael@0: class CallArgs; michael@0: michael@0: template michael@0: class Rooted; michael@0: michael@0: class JS_PUBLIC_API(AutoGCRooter); michael@0: michael@0: class JS_FRIEND_API(CompileOptions); michael@0: class JS_FRIEND_API(ReadOnlyCompileOptions); michael@0: class JS_FRIEND_API(OwningCompileOptions); michael@0: class JS_PUBLIC_API(CompartmentOptions); michael@0: michael@0: struct Zone; michael@0: michael@0: } /* namespace JS */ michael@0: michael@0: /* michael@0: * Run-time version enumeration. For compile-time version checking, please use michael@0: * the JS_HAS_* macros in jsversion.h, or use MOZJS_MAJOR_VERSION, michael@0: * MOZJS_MINOR_VERSION, MOZJS_PATCH_VERSION, and MOZJS_ALPHA definitions. michael@0: */ michael@0: enum JSVersion { michael@0: JSVERSION_ECMA_3 = 148, michael@0: JSVERSION_1_6 = 160, michael@0: JSVERSION_1_7 = 170, michael@0: JSVERSION_1_8 = 180, michael@0: JSVERSION_ECMA_5 = 185, michael@0: JSVERSION_DEFAULT = 0, michael@0: JSVERSION_UNKNOWN = -1, michael@0: JSVERSION_LATEST = JSVERSION_ECMA_5 michael@0: }; michael@0: michael@0: /* Result of typeof operator enumeration. */ michael@0: enum JSType { michael@0: JSTYPE_VOID, /* undefined */ michael@0: JSTYPE_OBJECT, /* object */ michael@0: JSTYPE_FUNCTION, /* function */ michael@0: JSTYPE_STRING, /* string */ michael@0: JSTYPE_NUMBER, /* number */ michael@0: JSTYPE_BOOLEAN, /* boolean */ michael@0: JSTYPE_NULL, /* null */ michael@0: JSTYPE_LIMIT michael@0: }; michael@0: michael@0: /* Dense index into cached prototypes and class atoms for standard objects. */ michael@0: enum JSProtoKey { michael@0: #define PROTOKEY_AND_INITIALIZER(name,code,init,clasp) JSProto_##name = code, michael@0: JS_FOR_EACH_PROTOTYPE(PROTOKEY_AND_INITIALIZER) michael@0: #undef PROTOKEY_AND_INITIALIZER michael@0: JSProto_LIMIT michael@0: }; michael@0: michael@0: /* michael@0: * This enum type is used to control the behavior of a JSObject property michael@0: * iterator function that has type JSNewEnumerate. michael@0: */ michael@0: enum JSIterateOp { michael@0: /* Create new iterator state over enumerable properties. */ michael@0: JSENUMERATE_INIT, michael@0: michael@0: /* Create new iterator state over all properties. */ michael@0: JSENUMERATE_INIT_ALL, michael@0: michael@0: /* Iterate once. */ michael@0: JSENUMERATE_NEXT, michael@0: michael@0: /* Destroy iterator state. */ michael@0: JSENUMERATE_DESTROY michael@0: }; michael@0: michael@0: /* See Value::gcKind() and JSTraceCallback in Tracer.h. */ michael@0: enum JSGCTraceKind { michael@0: JSTRACE_OBJECT, michael@0: JSTRACE_STRING, michael@0: JSTRACE_SCRIPT, michael@0: michael@0: /* michael@0: * Trace kinds internal to the engine. The embedding can only see them if michael@0: * it implements JSTraceCallback. michael@0: */ michael@0: JSTRACE_LAZY_SCRIPT, michael@0: JSTRACE_JITCODE, michael@0: JSTRACE_SHAPE, michael@0: JSTRACE_BASE_SHAPE, michael@0: JSTRACE_TYPE_OBJECT, michael@0: JSTRACE_LAST = JSTRACE_TYPE_OBJECT michael@0: }; michael@0: michael@0: /* Struct forward declarations. */ michael@0: struct JSClass; michael@0: struct JSCompartment; michael@0: struct JSConstDoubleSpec; michael@0: struct JSCrossCompartmentCall; michael@0: struct JSErrorReport; michael@0: struct JSExceptionState; michael@0: struct JSFunctionSpec; michael@0: struct JSIdArray; michael@0: struct JSLocaleCallbacks; michael@0: struct JSObjectMap; michael@0: struct JSPrincipals; michael@0: struct JSPropertyDescriptor; michael@0: struct JSPropertyName; michael@0: struct JSPropertySpec; michael@0: struct JSRuntime; michael@0: struct JSSecurityCallbacks; michael@0: struct JSStructuredCloneCallbacks; michael@0: struct JSStructuredCloneReader; michael@0: struct JSStructuredCloneWriter; michael@0: class JS_PUBLIC_API(JSTracer); michael@0: michael@0: class JSFlatString; michael@0: michael@0: #ifdef JS_THREADSAFE michael@0: typedef struct PRCallOnceType JSCallOnceType; michael@0: #else michael@0: typedef bool JSCallOnceType; michael@0: #endif michael@0: typedef bool (*JSInitCallback)(void); michael@0: michael@0: /* michael@0: * Generic trace operation that calls JS_CallTracer on each traceable thing michael@0: * stored in data. michael@0: */ michael@0: typedef void michael@0: (* JSTraceDataOp)(JSTracer *trc, void *data); michael@0: michael@0: void js_FinishGC(JSRuntime *rt); michael@0: michael@0: namespace js { michael@0: namespace gc { michael@0: class StoreBuffer; michael@0: void MarkPersistentRootedChains(JSTracer *); michael@0: } michael@0: } michael@0: michael@0: namespace JS { michael@0: michael@0: typedef void (*OffThreadCompileCallback)(void *token, void *callbackData); michael@0: michael@0: namespace shadow { michael@0: michael@0: struct Runtime michael@0: { michael@0: /* Restrict zone access during Minor GC. */ michael@0: bool needsBarrier_; michael@0: michael@0: #ifdef JSGC_GENERATIONAL michael@0: /* Allow inlining of Nursery::isInside. */ michael@0: uintptr_t gcNurseryStart_; michael@0: uintptr_t gcNurseryEnd_; michael@0: michael@0: private: michael@0: js::gc::StoreBuffer *gcStoreBufferPtr_; michael@0: #endif michael@0: michael@0: public: michael@0: Runtime( michael@0: #ifdef JSGC_GENERATIONAL michael@0: js::gc::StoreBuffer *storeBuffer michael@0: #endif michael@0: ) michael@0: : needsBarrier_(false) michael@0: #ifdef JSGC_GENERATIONAL michael@0: , gcNurseryStart_(0) michael@0: , gcNurseryEnd_(0) michael@0: , gcStoreBufferPtr_(storeBuffer) michael@0: #endif michael@0: {} michael@0: michael@0: bool needsBarrier() const { michael@0: return needsBarrier_; michael@0: } michael@0: michael@0: #ifdef JSGC_GENERATIONAL michael@0: js::gc::StoreBuffer *gcStoreBufferPtr() { return gcStoreBufferPtr_; } michael@0: #endif michael@0: michael@0: static JS::shadow::Runtime *asShadowRuntime(JSRuntime *rt) { michael@0: return reinterpret_cast(rt); michael@0: } michael@0: michael@0: /* Allow inlining of PersistentRooted constructors and destructors. */ michael@0: private: michael@0: template friend class JS::PersistentRooted; michael@0: friend void js::gc::MarkPersistentRootedChains(JSTracer *); michael@0: friend void ::js_FinishGC(JSRuntime *rt); michael@0: michael@0: mozilla::LinkedList functionPersistentRooteds; michael@0: mozilla::LinkedList idPersistentRooteds; michael@0: mozilla::LinkedList objectPersistentRooteds; michael@0: mozilla::LinkedList scriptPersistentRooteds; michael@0: mozilla::LinkedList stringPersistentRooteds; michael@0: mozilla::LinkedList valuePersistentRooteds; michael@0: michael@0: /* Specializations of this return references to the appropriate list. */ michael@0: template michael@0: inline mozilla::LinkedList > &getPersistentRootedList(); michael@0: }; michael@0: michael@0: template<> michael@0: inline mozilla::LinkedList michael@0: &Runtime::getPersistentRootedList() { return functionPersistentRooteds; } michael@0: michael@0: template<> michael@0: inline mozilla::LinkedList michael@0: &Runtime::getPersistentRootedList() { return idPersistentRooteds; } michael@0: michael@0: template<> michael@0: inline mozilla::LinkedList michael@0: &Runtime::getPersistentRootedList() { return objectPersistentRooteds; } michael@0: michael@0: template<> michael@0: inline mozilla::LinkedList michael@0: &Runtime::getPersistentRootedList() { return scriptPersistentRooteds; } michael@0: michael@0: template<> michael@0: inline mozilla::LinkedList michael@0: &Runtime::getPersistentRootedList() { return stringPersistentRooteds; } michael@0: michael@0: template<> michael@0: inline mozilla::LinkedList michael@0: &Runtime::getPersistentRootedList() { return valuePersistentRooteds; } michael@0: michael@0: } /* namespace shadow */ michael@0: } /* namespace JS */ michael@0: michael@0: namespace js { michael@0: michael@0: /* michael@0: * Parallel operations in general can have one of three states. They may michael@0: * succeed, fail, or "bail", where bail indicates that the code encountered an michael@0: * unexpected condition and should be re-run sequentially. Different michael@0: * subcategories of the "bail" state are encoded as variants of TP_RETRY_*. michael@0: */ michael@0: enum ParallelResult { TP_SUCCESS, TP_RETRY_SEQUENTIALLY, TP_RETRY_AFTER_GC, TP_FATAL }; michael@0: michael@0: struct ThreadSafeContext; michael@0: struct ForkJoinContext; michael@0: class ExclusiveContext; michael@0: michael@0: class Allocator; michael@0: michael@0: enum ThingRootKind michael@0: { michael@0: THING_ROOT_OBJECT, michael@0: THING_ROOT_SHAPE, michael@0: THING_ROOT_BASE_SHAPE, michael@0: THING_ROOT_TYPE_OBJECT, michael@0: THING_ROOT_STRING, michael@0: THING_ROOT_JIT_CODE, michael@0: THING_ROOT_SCRIPT, michael@0: THING_ROOT_LAZY_SCRIPT, michael@0: THING_ROOT_ID, michael@0: THING_ROOT_VALUE, michael@0: THING_ROOT_TYPE, michael@0: THING_ROOT_BINDINGS, michael@0: THING_ROOT_PROPERTY_DESCRIPTOR, michael@0: THING_ROOT_CUSTOM, michael@0: THING_ROOT_LIMIT michael@0: }; michael@0: michael@0: /* michael@0: * This list enumerates the different types of conceptual stacks we have in michael@0: * SpiderMonkey. In reality, they all share the C stack, but we allow different michael@0: * stack limits depending on the type of code running. michael@0: */ michael@0: enum StackKind michael@0: { michael@0: StackForSystemCode, // C++, such as the GC, running on behalf of the VM. michael@0: StackForTrustedScript, // Script running with trusted principals. michael@0: StackForUntrustedScript, // Script running with untrusted principals. michael@0: StackKindCount michael@0: }; michael@0: michael@0: template michael@0: struct RootKind; michael@0: michael@0: /* michael@0: * Specifically mark the ThingRootKind of externally visible types, so that michael@0: * JSAPI users may use JSRooted... types without having the class definition michael@0: * available. michael@0: */ michael@0: template michael@0: struct SpecificRootKind michael@0: { michael@0: static ThingRootKind rootKind() { return Kind; } michael@0: }; michael@0: michael@0: template <> struct RootKind : SpecificRootKind {}; michael@0: template <> struct RootKind : SpecificRootKind {}; michael@0: template <> struct RootKind : SpecificRootKind {}; michael@0: template <> struct RootKind : SpecificRootKind {}; michael@0: template <> struct RootKind : SpecificRootKind {}; michael@0: template <> struct RootKind : SpecificRootKind {}; michael@0: template <> struct RootKind : SpecificRootKind {}; michael@0: michael@0: struct ContextFriendFields michael@0: { michael@0: protected: michael@0: JSRuntime *const runtime_; michael@0: michael@0: /* The current compartment. */ michael@0: JSCompartment *compartment_; michael@0: michael@0: /* The current zone. */ michael@0: JS::Zone *zone_; michael@0: michael@0: public: michael@0: explicit ContextFriendFields(JSRuntime *rt) michael@0: : runtime_(rt), compartment_(nullptr), zone_(nullptr), autoGCRooters(nullptr) michael@0: { michael@0: #ifdef JSGC_TRACK_EXACT_ROOTS michael@0: mozilla::PodArrayZero(thingGCRooters); michael@0: #endif michael@0: } michael@0: michael@0: static const ContextFriendFields *get(const JSContext *cx) { michael@0: return reinterpret_cast(cx); michael@0: } michael@0: michael@0: static ContextFriendFields *get(JSContext *cx) { michael@0: return reinterpret_cast(cx); michael@0: } michael@0: michael@0: #ifdef JSGC_TRACK_EXACT_ROOTS michael@0: /* michael@0: * Stack allocated GC roots for stack GC heap pointers, which may be michael@0: * overwritten if moved during a GC. michael@0: */ michael@0: JS::Rooted *thingGCRooters[THING_ROOT_LIMIT]; michael@0: #endif michael@0: michael@0: /* Stack of thread-stack-allocated GC roots. */ michael@0: JS::AutoGCRooter *autoGCRooters; michael@0: michael@0: friend JSRuntime *GetRuntime(const JSContext *cx); michael@0: friend JSCompartment *GetContextCompartment(const JSContext *cx); michael@0: friend JS::Zone *GetContextZone(const JSContext *cx); michael@0: }; michael@0: michael@0: /* michael@0: * Inlinable accessors for JSContext. michael@0: * michael@0: * - These must not be available on the more restricted superclasses of michael@0: * JSContext, so we can't simply define them on ContextFriendFields. michael@0: * michael@0: * - They're perfectly ordinary JSContext functionality, so ought to be michael@0: * usable without resorting to jsfriendapi.h, and when JSContext is an michael@0: * incomplete type. michael@0: */ michael@0: inline JSRuntime * michael@0: GetRuntime(const JSContext *cx) michael@0: { michael@0: return ContextFriendFields::get(cx)->runtime_; michael@0: } michael@0: michael@0: inline JSCompartment * michael@0: GetContextCompartment(const JSContext *cx) michael@0: { michael@0: return ContextFriendFields::get(cx)->compartment_; michael@0: } michael@0: michael@0: inline JS::Zone * michael@0: GetContextZone(const JSContext *cx) michael@0: { michael@0: return ContextFriendFields::get(cx)->zone_; michael@0: } michael@0: michael@0: class PerThreadData; michael@0: michael@0: struct PerThreadDataFriendFields michael@0: { michael@0: private: michael@0: // Note: this type only exists to permit us to derive the offset of michael@0: // the perThread data within the real JSRuntime* type in a portable michael@0: // way. michael@0: struct RuntimeDummy : JS::shadow::Runtime michael@0: { michael@0: struct PerThreadDummy { michael@0: void *field1; michael@0: uintptr_t field2; michael@0: #ifdef JS_DEBUG michael@0: uint64_t field3; michael@0: #endif michael@0: } mainThread; michael@0: }; michael@0: michael@0: public: michael@0: michael@0: PerThreadDataFriendFields(); michael@0: michael@0: #ifdef JSGC_TRACK_EXACT_ROOTS michael@0: /* michael@0: * Stack allocated GC roots for stack GC heap pointers, which may be michael@0: * overwritten if moved during a GC. michael@0: */ michael@0: JS::Rooted *thingGCRooters[THING_ROOT_LIMIT]; michael@0: #endif michael@0: michael@0: /* Limit pointer for checking native stack consumption. */ michael@0: uintptr_t nativeStackLimit[StackKindCount]; michael@0: michael@0: static const size_t RuntimeMainThreadOffset = offsetof(RuntimeDummy, mainThread); michael@0: michael@0: static inline PerThreadDataFriendFields *get(js::PerThreadData *pt) { michael@0: return reinterpret_cast(pt); michael@0: } michael@0: michael@0: static inline PerThreadDataFriendFields *getMainThread(JSRuntime *rt) { michael@0: // mainThread must always appear directly after |JS::shadow::Runtime|. michael@0: // Tested by a JS_STATIC_ASSERT in |jsfriendapi.cpp| michael@0: return reinterpret_cast( michael@0: reinterpret_cast(rt) + RuntimeMainThreadOffset); michael@0: } michael@0: michael@0: static inline const PerThreadDataFriendFields *getMainThread(const JSRuntime *rt) { michael@0: // mainThread must always appear directly after |JS::shadow::Runtime|. michael@0: // Tested by a JS_STATIC_ASSERT in |jsfriendapi.cpp| michael@0: return reinterpret_cast( michael@0: reinterpret_cast(rt) + RuntimeMainThreadOffset); michael@0: } michael@0: }; michael@0: michael@0: } /* namespace js */ michael@0: michael@0: #endif /* jspubtd_h */