diff -r 000000000000 -r 6474c204b198 js/src/jspubtd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/js/src/jspubtd.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,455 @@ +/* -*- 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/LinkedList.h" +#include "mozilla/NullPtr.h" +#include "mozilla/PodOperations.h" + +#include "jsprototypes.h" +#include "jstypes.h" + +#include "js/TypeDecls.h" + +#if defined(JSGC_USE_EXACT_ROOTING) || defined(JS_DEBUG) +# define JSGC_TRACK_EXACT_ROOTS +#endif + +namespace JS { + +class AutoIdVector; +class CallArgs; + +template +class Rooted; + +class JS_PUBLIC_API(AutoGCRooter); + +class JS_FRIEND_API(CompileOptions); +class JS_FRIEND_API(ReadOnlyCompileOptions); +class JS_FRIEND_API(OwningCompileOptions); +class JS_PUBLIC_API(CompartmentOptions); + +struct Zone; + +} /* 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_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 +}; + +/* + * This enum type is used to control the behavior of a JSObject property + * iterator function that has type JSNewEnumerate. + */ +enum JSIterateOp { + /* Create new iterator state over enumerable properties. */ + JSENUMERATE_INIT, + + /* Create new iterator state over all properties. */ + JSENUMERATE_INIT_ALL, + + /* Iterate once. */ + JSENUMERATE_NEXT, + + /* Destroy iterator state. */ + JSENUMERATE_DESTROY +}; + +/* See Value::gcKind() and JSTraceCallback in Tracer.h. */ +enum JSGCTraceKind { + JSTRACE_OBJECT, + JSTRACE_STRING, + JSTRACE_SCRIPT, + + /* + * Trace kinds internal to the engine. The embedding can only see them if + * it implements JSTraceCallback. + */ + JSTRACE_LAZY_SCRIPT, + JSTRACE_JITCODE, + JSTRACE_SHAPE, + JSTRACE_BASE_SHAPE, + JSTRACE_TYPE_OBJECT, + JSTRACE_LAST = JSTRACE_TYPE_OBJECT +}; + +/* Struct forward declarations. */ +struct JSClass; +struct JSCompartment; +struct JSConstDoubleSpec; +struct JSCrossCompartmentCall; +struct JSErrorReport; +struct JSExceptionState; +struct JSFunctionSpec; +struct JSIdArray; +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; + +#ifdef JS_THREADSAFE +typedef struct PRCallOnceType JSCallOnceType; +#else +typedef bool JSCallOnceType; +#endif +typedef bool (*JSInitCallback)(void); + +/* + * Generic trace operation that calls JS_CallTracer on each traceable thing + * stored in data. + */ +typedef void +(* JSTraceDataOp)(JSTracer *trc, void *data); + +void js_FinishGC(JSRuntime *rt); + +namespace js { +namespace gc { +class StoreBuffer; +void MarkPersistentRootedChains(JSTracer *); +} +} + +namespace JS { + +typedef void (*OffThreadCompileCallback)(void *token, void *callbackData); + +namespace shadow { + +struct Runtime +{ + /* Restrict zone access during Minor GC. */ + bool needsBarrier_; + +#ifdef JSGC_GENERATIONAL + /* Allow inlining of Nursery::isInside. */ + uintptr_t gcNurseryStart_; + uintptr_t gcNurseryEnd_; + + private: + js::gc::StoreBuffer *gcStoreBufferPtr_; +#endif + + public: + Runtime( +#ifdef JSGC_GENERATIONAL + js::gc::StoreBuffer *storeBuffer +#endif + ) + : needsBarrier_(false) +#ifdef JSGC_GENERATIONAL + , gcNurseryStart_(0) + , gcNurseryEnd_(0) + , gcStoreBufferPtr_(storeBuffer) +#endif + {} + + bool needsBarrier() const { + return needsBarrier_; + } + +#ifdef JSGC_GENERATIONAL + js::gc::StoreBuffer *gcStoreBufferPtr() { return gcStoreBufferPtr_; } +#endif + + static JS::shadow::Runtime *asShadowRuntime(JSRuntime *rt) { + return reinterpret_cast(rt); + } + + /* Allow inlining of PersistentRooted constructors and destructors. */ + private: + template friend class JS::PersistentRooted; + friend void js::gc::MarkPersistentRootedChains(JSTracer *); + friend void ::js_FinishGC(JSRuntime *rt); + + mozilla::LinkedList functionPersistentRooteds; + mozilla::LinkedList idPersistentRooteds; + mozilla::LinkedList objectPersistentRooteds; + mozilla::LinkedList scriptPersistentRooteds; + mozilla::LinkedList stringPersistentRooteds; + mozilla::LinkedList valuePersistentRooteds; + + /* Specializations of this return references to the appropriate list. */ + template + inline mozilla::LinkedList > &getPersistentRootedList(); +}; + +template<> +inline mozilla::LinkedList +&Runtime::getPersistentRootedList() { return functionPersistentRooteds; } + +template<> +inline mozilla::LinkedList +&Runtime::getPersistentRootedList() { return idPersistentRooteds; } + +template<> +inline mozilla::LinkedList +&Runtime::getPersistentRootedList() { return objectPersistentRooteds; } + +template<> +inline mozilla::LinkedList +&Runtime::getPersistentRootedList() { return scriptPersistentRooteds; } + +template<> +inline mozilla::LinkedList +&Runtime::getPersistentRootedList() { return stringPersistentRooteds; } + +template<> +inline mozilla::LinkedList +&Runtime::getPersistentRootedList() { return valuePersistentRooteds; } + +} /* namespace shadow */ +} /* namespace JS */ + +namespace js { + +/* + * Parallel operations in general can have one of three states. They may + * succeed, fail, or "bail", where bail indicates that the code encountered an + * unexpected condition and should be re-run sequentially. Different + * subcategories of the "bail" state are encoded as variants of TP_RETRY_*. + */ +enum ParallelResult { TP_SUCCESS, TP_RETRY_SEQUENTIALLY, TP_RETRY_AFTER_GC, TP_FATAL }; + +struct ThreadSafeContext; +struct ForkJoinContext; +class ExclusiveContext; + +class Allocator; + +enum ThingRootKind +{ + THING_ROOT_OBJECT, + THING_ROOT_SHAPE, + THING_ROOT_BASE_SHAPE, + THING_ROOT_TYPE_OBJECT, + THING_ROOT_STRING, + THING_ROOT_JIT_CODE, + THING_ROOT_SCRIPT, + THING_ROOT_LAZY_SCRIPT, + THING_ROOT_ID, + THING_ROOT_VALUE, + THING_ROOT_TYPE, + THING_ROOT_BINDINGS, + THING_ROOT_PROPERTY_DESCRIPTOR, + THING_ROOT_CUSTOM, + THING_ROOT_LIMIT +}; + +/* + * 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 +}; + +template +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 +struct SpecificRootKind +{ + static ThingRootKind rootKind() { return Kind; } +}; + +template <> struct RootKind : SpecificRootKind {}; +template <> struct RootKind : SpecificRootKind {}; +template <> struct RootKind : SpecificRootKind {}; +template <> struct RootKind : SpecificRootKind {}; +template <> struct RootKind : SpecificRootKind {}; +template <> struct RootKind : SpecificRootKind {}; +template <> struct RootKind : SpecificRootKind {}; + +struct ContextFriendFields +{ + protected: + JSRuntime *const runtime_; + + /* The current compartment. */ + JSCompartment *compartment_; + + /* The current zone. */ + JS::Zone *zone_; + + public: + explicit ContextFriendFields(JSRuntime *rt) + : runtime_(rt), compartment_(nullptr), zone_(nullptr), autoGCRooters(nullptr) + { +#ifdef JSGC_TRACK_EXACT_ROOTS + mozilla::PodArrayZero(thingGCRooters); +#endif + } + + static const ContextFriendFields *get(const JSContext *cx) { + return reinterpret_cast(cx); + } + + static ContextFriendFields *get(JSContext *cx) { + return reinterpret_cast(cx); + } + +#ifdef JSGC_TRACK_EXACT_ROOTS + /* + * Stack allocated GC roots for stack GC heap pointers, which may be + * overwritten if moved during a GC. + */ + JS::Rooted *thingGCRooters[THING_ROOT_LIMIT]; +#endif + + /* Stack of thread-stack-allocated GC roots. */ + JS::AutoGCRooter *autoGCRooters; + + friend JSRuntime *GetRuntime(const JSContext *cx); + friend JSCompartment *GetContextCompartment(const JSContext *cx); + friend JS::Zone *GetContextZone(const JSContext *cx); +}; + +/* + * 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: + + PerThreadDataFriendFields(); + +#ifdef JSGC_TRACK_EXACT_ROOTS + /* + * Stack allocated GC roots for stack GC heap pointers, which may be + * overwritten if moved during a GC. + */ + JS::Rooted *thingGCRooters[THING_ROOT_LIMIT]; +#endif + + /* Limit pointer for checking native stack consumption. */ + uintptr_t nativeStackLimit[StackKindCount]; + + static const size_t RuntimeMainThreadOffset = offsetof(RuntimeDummy, mainThread); + + static inline PerThreadDataFriendFields *get(js::PerThreadData *pt) { + return reinterpret_cast(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( + reinterpret_cast(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( + reinterpret_cast(rt) + RuntimeMainThreadOffset); + } +}; + +} /* namespace js */ + +#endif /* jspubtd_h */