jspubtd.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2. * vim: set ts=8 sts=4 et sw=4 tw=99:
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. #ifndef jspubtd_h
  7. #define jspubtd_h
  8. /*
  9. * JS public API typedefs.
  10. */
  11. #include "mozilla/Assertions.h"
  12. #include "mozilla/EnumeratedArray.h"
  13. #include "mozilla/LinkedList.h"
  14. #include "mozilla/PodOperations.h"
  15. #include "jsprototypes.h"
  16. #include "jstypes.h"
  17. #include "js/TraceKind.h"
  18. #include "js/TypeDecls.h"
  19. #if defined(JS_GC_ZEAL) || defined(DEBUG)
  20. # define JSGC_HASH_TABLE_CHECKS
  21. #endif
  22. namespace JS {
  23. class AutoIdVector;
  24. class CallArgs;
  25. template <typename T>
  26. class Rooted;
  27. class JS_FRIEND_API(CompileOptions);
  28. class JS_FRIEND_API(ReadOnlyCompileOptions);
  29. class JS_FRIEND_API(OwningCompileOptions);
  30. class JS_FRIEND_API(TransitiveCompileOptions);
  31. class JS_PUBLIC_API(CompartmentOptions);
  32. struct RootingContext;
  33. class Value;
  34. struct Zone;
  35. namespace shadow {
  36. struct Runtime;
  37. } // namespace shadow
  38. } // namespace JS
  39. namespace js {
  40. class RootLists;
  41. } // namespace js
  42. /*
  43. * Run-time version enumeration. For compile-time version checking, please use
  44. * the JS_HAS_* macros in jsversion.h, or use MOZJS_MAJOR_VERSION,
  45. * MOZJS_MINOR_VERSION, MOZJS_PATCH_VERSION, and MOZJS_ALPHA definitions.
  46. */
  47. enum JSVersion {
  48. JSVERSION_ECMA_3 = 148,
  49. JSVERSION_1_6 = 160,
  50. JSVERSION_1_7 = 170,
  51. JSVERSION_1_8 = 180,
  52. JSVERSION_ECMA_5 = 185,
  53. JSVERSION_DEFAULT = 0,
  54. JSVERSION_UNKNOWN = -1,
  55. JSVERSION_LATEST = JSVERSION_ECMA_5
  56. };
  57. /* Result of typeof operator enumeration. */
  58. enum JSType {
  59. JSTYPE_VOID, /* undefined */
  60. JSTYPE_OBJECT, /* object */
  61. JSTYPE_FUNCTION, /* function */
  62. JSTYPE_STRING, /* string */
  63. JSTYPE_NUMBER, /* number */
  64. JSTYPE_BOOLEAN, /* boolean */
  65. JSTYPE_NULL, /* null */
  66. JSTYPE_SYMBOL, /* symbol */
  67. JSTYPE_LIMIT
  68. };
  69. /* Dense index into cached prototypes and class atoms for standard objects. */
  70. enum JSProtoKey {
  71. #define PROTOKEY_AND_INITIALIZER(name,code,init,clasp) JSProto_##name = code,
  72. JS_FOR_EACH_PROTOTYPE(PROTOKEY_AND_INITIALIZER)
  73. #undef PROTOKEY_AND_INITIALIZER
  74. JSProto_LIMIT
  75. };
  76. /* Struct forward declarations. */
  77. struct JSClass;
  78. struct JSCompartment;
  79. struct JSCrossCompartmentCall;
  80. class JSErrorReport;
  81. struct JSExceptionState;
  82. struct JSFunctionSpec;
  83. struct JSLocaleCallbacks;
  84. struct JSObjectMap;
  85. struct JSPrincipals;
  86. struct JSPropertyName;
  87. struct JSPropertySpec;
  88. struct JSRuntime;
  89. struct JSSecurityCallbacks;
  90. struct JSStructuredCloneCallbacks;
  91. struct JSStructuredCloneReader;
  92. struct JSStructuredCloneWriter;
  93. class JS_PUBLIC_API(JSTracer);
  94. class JSFlatString;
  95. typedef bool (*JSInitCallback)(void);
  96. template<typename T> struct JSConstScalarSpec;
  97. typedef JSConstScalarSpec<double> JSConstDoubleSpec;
  98. typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec;
  99. /*
  100. * Generic trace operation that calls JS::TraceEdge on each traceable thing's
  101. * location reachable from data.
  102. */
  103. typedef void
  104. (* JSTraceDataOp)(JSTracer* trc, void* data);
  105. namespace js {
  106. namespace gc {
  107. class AutoTraceSession;
  108. class StoreBuffer;
  109. } // namespace gc
  110. // Whether the current thread is permitted access to any part of the specified
  111. // runtime or zone.
  112. JS_FRIEND_API(bool)
  113. CurrentThreadCanAccessRuntime(const JSRuntime* rt);
  114. #ifdef DEBUG
  115. JS_FRIEND_API(bool)
  116. CurrentThreadIsPerformingGC();
  117. #endif
  118. } // namespace js
  119. namespace JS {
  120. class JS_PUBLIC_API(AutoEnterCycleCollection);
  121. class JS_PUBLIC_API(AutoAssertOnBarrier);
  122. struct JS_PUBLIC_API(PropertyDescriptor);
  123. typedef void (*OffThreadCompileCallback)(void* token, void* callbackData);
  124. enum class HeapState {
  125. Idle, // doing nothing with the GC heap
  126. Tracing, // tracing the GC heap without collecting, e.g. IterateCompartments()
  127. MajorCollecting, // doing a GC of the major heap
  128. MinorCollecting, // doing a GC of the minor heap (nursery)
  129. CycleCollecting // in the "Unlink" phase of cycle collection
  130. };
  131. namespace shadow {
  132. struct Runtime
  133. {
  134. private:
  135. JS::HeapState heapState_;
  136. protected:
  137. void setHeapState(JS::HeapState newState) {
  138. MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(asRuntime()));
  139. MOZ_ASSERT(heapState_ != newState);
  140. heapState_ = newState;
  141. }
  142. JS::HeapState heapState() const {
  143. MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(asRuntime()) ||
  144. js::CurrentThreadIsPerformingGC());
  145. return heapState_;
  146. }
  147. // In some cases, invoking GC barriers (incremental or otherwise) will break
  148. // things. These barriers assert if this flag is set.
  149. bool allowGCBarriers_;
  150. friend class JS::AutoAssertOnBarrier;
  151. js::gc::StoreBuffer* gcStoreBufferPtr_;
  152. // The gray bits can become invalid if UnmarkGray overflows the stack. A
  153. // full GC will reset this bit, since it fills in all the gray bits.
  154. bool gcGrayBitsValid_;
  155. public:
  156. Runtime()
  157. : heapState_(JS::HeapState::Idle)
  158. , allowGCBarriers_(true)
  159. , gcStoreBufferPtr_(nullptr)
  160. , gcGrayBitsValid_(false)
  161. {}
  162. bool isHeapBusy() const { return heapState() != JS::HeapState::Idle; }
  163. bool isHeapTracing() const { return heapState() == JS::HeapState::Tracing; }
  164. bool isHeapMajorCollecting() const { return heapState() == JS::HeapState::MajorCollecting; }
  165. bool isHeapMinorCollecting() const { return heapState() == JS::HeapState::MinorCollecting; }
  166. bool isHeapCollecting() const { return isHeapMinorCollecting() || isHeapMajorCollecting(); }
  167. bool isCycleCollecting() const {
  168. return heapState() == JS::HeapState::CycleCollecting;
  169. }
  170. bool allowGCBarriers() const { return allowGCBarriers_; }
  171. js::gc::StoreBuffer* gcStoreBufferPtr() { return gcStoreBufferPtr_; }
  172. bool areGCGrayBitsValid() const { return gcGrayBitsValid_; }
  173. void setGCGrayBitsValid(bool valid) { gcGrayBitsValid_ = valid; }
  174. const JSRuntime* asRuntime() const {
  175. return reinterpret_cast<const JSRuntime*>(this);
  176. }
  177. static JS::shadow::Runtime* asShadowRuntime(JSRuntime* rt) {
  178. return reinterpret_cast<JS::shadow::Runtime*>(rt);
  179. }
  180. protected:
  181. void setGCStoreBufferPtr(js::gc::StoreBuffer* storeBuffer) {
  182. gcStoreBufferPtr_ = storeBuffer;
  183. }
  184. };
  185. } /* namespace shadow */
  186. // Decorates the Unlinking phase of CycleCollection so that accidental use
  187. // of barriered accessors results in assertions instead of leaks.
  188. class MOZ_STACK_CLASS JS_PUBLIC_API(AutoEnterCycleCollection)
  189. {
  190. #ifdef DEBUG
  191. JSRuntime* runtime;
  192. public:
  193. explicit AutoEnterCycleCollection(JSContext* cx);
  194. ~AutoEnterCycleCollection();
  195. #else
  196. public:
  197. explicit AutoEnterCycleCollection(JSContext* cx) {}
  198. ~AutoEnterCycleCollection() {}
  199. #endif
  200. };
  201. class JS_PUBLIC_API(AutoGCRooter)
  202. {
  203. public:
  204. AutoGCRooter(JSContext* cx, ptrdiff_t tag);
  205. AutoGCRooter(JS::RootingContext* cx, ptrdiff_t tag);
  206. ~AutoGCRooter() {
  207. MOZ_ASSERT(this == *stackTop);
  208. *stackTop = down;
  209. }
  210. /* Implemented in gc/RootMarking.cpp. */
  211. inline void trace(JSTracer* trc);
  212. static void traceAll(JSTracer* trc);
  213. static void traceAllWrappers(JSTracer* trc);
  214. protected:
  215. AutoGCRooter * const down;
  216. /*
  217. * Discriminates actual subclass of this being used. If non-negative, the
  218. * subclass roots an array of values of the length stored in this field.
  219. * If negative, meaning is indicated by the corresponding value in the enum
  220. * below. Any other negative value indicates some deeper problem such as
  221. * memory corruption.
  222. */
  223. ptrdiff_t tag_;
  224. enum {
  225. VALARRAY = -2, /* js::AutoValueArray */
  226. PARSER = -3, /* js::frontend::Parser */
  227. VALVECTOR = -10, /* js::AutoValueVector */
  228. IDVECTOR = -11, /* js::AutoIdVector */
  229. OBJVECTOR = -14, /* js::AutoObjectVector */
  230. IONMASM = -19, /* js::jit::MacroAssembler */
  231. WRAPVECTOR = -20, /* js::AutoWrapperVector */
  232. WRAPPER = -21, /* js::AutoWrapperRooter */
  233. CUSTOM = -26 /* js::CustomAutoRooter */
  234. };
  235. static ptrdiff_t GetTag(const Value& value) { return VALVECTOR; }
  236. static ptrdiff_t GetTag(const jsid& id) { return IDVECTOR; }
  237. static ptrdiff_t GetTag(JSObject* obj) { return OBJVECTOR; }
  238. private:
  239. AutoGCRooter ** const stackTop;
  240. /* No copy or assignment semantics. */
  241. AutoGCRooter(AutoGCRooter& ida) = delete;
  242. void operator=(AutoGCRooter& ida) = delete;
  243. };
  244. // Our instantiations of Rooted<void*> and PersistentRooted<void*> require an
  245. // instantiation of MapTypeToRootKind.
  246. template <>
  247. struct MapTypeToRootKind<void*> {
  248. static const RootKind kind = RootKind::Traceable;
  249. };
  250. } /* namespace JS */
  251. namespace js {
  252. class ExclusiveContext;
  253. /*
  254. * This list enumerates the different types of conceptual stacks we have in
  255. * SpiderMonkey. In reality, they all share the C stack, but we allow different
  256. * stack limits depending on the type of code running.
  257. */
  258. enum StackKind
  259. {
  260. StackForSystemCode, // C++, such as the GC, running on behalf of the VM.
  261. StackForTrustedScript, // Script running with trusted principals.
  262. StackForUntrustedScript, // Script running with untrusted principals.
  263. StackKindCount
  264. };
  265. using RootedListHeads = mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit,
  266. JS::Rooted<void*>*>;
  267. // Abstracts JS rooting mechanisms so they can be shared between the JSContext
  268. // and JSRuntime.
  269. class RootLists
  270. {
  271. // Stack GC roots for Rooted GC heap pointers.
  272. RootedListHeads stackRoots_;
  273. template <typename T> friend class JS::Rooted;
  274. // Stack GC roots for AutoFooRooter classes.
  275. JS::AutoGCRooter* autoGCRooters_;
  276. friend class JS::AutoGCRooter;
  277. // Heap GC roots for PersistentRooted pointers.
  278. mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit,
  279. mozilla::LinkedList<JS::PersistentRooted<void*>>> heapRoots_;
  280. template <typename T> friend class JS::PersistentRooted;
  281. public:
  282. RootLists() : autoGCRooters_(nullptr) {
  283. for (auto& stackRootPtr : stackRoots_)
  284. stackRootPtr = nullptr;
  285. }
  286. ~RootLists() {
  287. // The semantics of PersistentRooted containing pointers and tagged
  288. // pointers are somewhat different from those of PersistentRooted
  289. // containing a structure with a trace method. PersistentRooted
  290. // containing pointers are allowed to outlive the owning RootLists,
  291. // whereas those containing a traceable structure are not.
  292. //
  293. // The purpose of this feature is to support lazy initialization of
  294. // global references for the several places in Gecko that do not have
  295. // access to a tighter context, but that still need to refer to GC
  296. // pointers. For such pointers, FinishPersistentRootedChains ensures
  297. // that the contained references are nulled out when the owning
  298. // RootLists dies to prevent UAF errors.
  299. //
  300. // However, for RootKind::Traceable, we do not know the concrete type
  301. // of the held thing, so we simply cannot do this without accruing
  302. // extra overhead and complexity for all users for a case that is
  303. // unlikely to ever be used in practice. For this reason, the following
  304. // assertion disallows usage of PersistentRooted<Traceable> that
  305. // outlives the RootLists.
  306. MOZ_ASSERT(heapRoots_[JS::RootKind::Traceable].isEmpty());
  307. }
  308. void traceStackRoots(JSTracer* trc);
  309. void checkNoGCRooters();
  310. void tracePersistentRoots(JSTracer* trc);
  311. void finishPersistentRoots();
  312. };
  313. } // namespace js
  314. namespace JS {
  315. /*
  316. * JS::RootingContext is a base class of ContextFriendFields and JSContext.
  317. * This class can be used to let code construct a Rooted<> or PersistentRooted<>
  318. * instance, without giving it full access to the JSContext.
  319. */
  320. struct RootingContext
  321. {
  322. js::RootLists roots;
  323. #ifdef DEBUG
  324. // Whether the derived class is a JSContext or an ExclusiveContext.
  325. bool isJSContext;
  326. #endif
  327. explicit RootingContext(bool isJSContextArg)
  328. #ifdef DEBUG
  329. : isJSContext(isJSContextArg)
  330. #endif
  331. {}
  332. static RootingContext* get(JSContext* cx) {
  333. return reinterpret_cast<RootingContext*>(cx);
  334. }
  335. };
  336. } // namespace JS
  337. namespace js {
  338. struct ContextFriendFields : public JS::RootingContext
  339. {
  340. protected:
  341. /* The current compartment. */
  342. JSCompartment* compartment_;
  343. /* The current zone. */
  344. JS::Zone* zone_;
  345. public:
  346. /* Limit pointer for checking native stack consumption. */
  347. uintptr_t nativeStackLimit[js::StackKindCount];
  348. explicit ContextFriendFields(bool isJSContext);
  349. static const ContextFriendFields* get(const JSContext* cx) {
  350. return reinterpret_cast<const ContextFriendFields*>(cx);
  351. }
  352. static ContextFriendFields* get(JSContext* cx) {
  353. return reinterpret_cast<ContextFriendFields*>(cx);
  354. }
  355. friend JSCompartment* GetContextCompartment(const JSContext* cx);
  356. friend JS::Zone* GetContextZone(const JSContext* cx);
  357. template <typename T> friend class JS::Rooted;
  358. };
  359. /*
  360. * Inlinable accessors for JSContext.
  361. *
  362. * - These must not be available on the more restricted superclasses of
  363. * JSContext, so we can't simply define them on ContextFriendFields.
  364. *
  365. * - They're perfectly ordinary JSContext functionality, so ought to be
  366. * usable without resorting to jsfriendapi.h, and when JSContext is an
  367. * incomplete type.
  368. */
  369. inline JSCompartment*
  370. GetContextCompartment(const JSContext* cx)
  371. {
  372. return ContextFriendFields::get(cx)->compartment_;
  373. }
  374. inline JS::Zone*
  375. GetContextZone(const JSContext* cx)
  376. {
  377. return ContextFriendFields::get(cx)->zone_;
  378. }
  379. } /* namespace js */
  380. MOZ_BEGIN_EXTERN_C
  381. // Defined in NSPR prio.h.
  382. typedef struct PRFileDesc PRFileDesc;
  383. MOZ_END_EXTERN_C
  384. #endif /* jspubtd_h */