Line data Source code
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 :
7 : #ifndef jspubtd_h
8 : #define jspubtd_h
9 :
10 : /*
11 : * JS public API typedefs.
12 : */
13 :
14 : #include "mozilla/Assertions.h"
15 : #include "mozilla/EnumeratedArray.h"
16 : #include "mozilla/LinkedList.h"
17 : #include "mozilla/PodOperations.h"
18 :
19 : #include "jsprototypes.h"
20 : #include "jstypes.h"
21 :
22 : #include "js/Result.h"
23 : #include "js/TraceKind.h"
24 : #include "js/TypeDecls.h"
25 :
26 : #if defined(JS_GC_ZEAL) || defined(DEBUG)
27 : # define JSGC_HASH_TABLE_CHECKS
28 : #endif
29 :
30 : namespace JS {
31 :
32 : class AutoIdVector;
33 : class CallArgs;
34 :
35 : template <typename T>
36 : class Rooted;
37 :
38 : class JS_FRIEND_API(CompileOptions);
39 : class JS_FRIEND_API(ReadOnlyCompileOptions);
40 : class JS_FRIEND_API(OwningCompileOptions);
41 : class JS_FRIEND_API(TransitiveCompileOptions);
42 : class JS_PUBLIC_API(CompartmentOptions);
43 :
44 : class Value;
45 : struct Zone;
46 :
47 : } // namespace JS
48 :
49 : /*
50 : * Run-time version enumeration. For compile-time version checking, please use
51 : * the JS_HAS_* macros in jsversion.h, or use MOZJS_MAJOR_VERSION,
52 : * MOZJS_MINOR_VERSION, MOZJS_PATCH_VERSION, and MOZJS_ALPHA definitions.
53 : */
54 : enum JSVersion {
55 : JSVERSION_ECMA_3 = 148,
56 : JSVERSION_1_6 = 160,
57 : JSVERSION_1_7 = 170,
58 : JSVERSION_1_8 = 180,
59 : JSVERSION_ECMA_5 = 185,
60 : JSVERSION_DEFAULT = 0,
61 : JSVERSION_UNKNOWN = -1,
62 : JSVERSION_LATEST = JSVERSION_ECMA_5
63 : };
64 :
65 : /* Result of typeof operator enumeration. */
66 : enum JSType {
67 : JSTYPE_UNDEFINED, /* undefined */
68 : JSTYPE_OBJECT, /* object */
69 : JSTYPE_FUNCTION, /* function */
70 : JSTYPE_STRING, /* string */
71 : JSTYPE_NUMBER, /* number */
72 : JSTYPE_BOOLEAN, /* boolean */
73 : JSTYPE_NULL, /* null */
74 : JSTYPE_SYMBOL, /* symbol */
75 : JSTYPE_LIMIT
76 : };
77 :
78 : /* Dense index into cached prototypes and class atoms for standard objects. */
79 : enum JSProtoKey {
80 : #define PROTOKEY_AND_INITIALIZER(name,code,init,clasp) JSProto_##name = code,
81 : JS_FOR_EACH_PROTOTYPE(PROTOKEY_AND_INITIALIZER)
82 : #undef PROTOKEY_AND_INITIALIZER
83 : JSProto_LIMIT
84 : };
85 :
86 : /* Struct forward declarations. */
87 : struct JSClass;
88 : struct JSCompartment;
89 : struct JSCrossCompartmentCall;
90 : class JSErrorReport;
91 : struct JSExceptionState;
92 : struct JSFunctionSpec;
93 : struct JSLocaleCallbacks;
94 : struct JSObjectMap;
95 : struct JSPrincipals;
96 : struct JSPropertyName;
97 : struct JSPropertySpec;
98 : struct JSRuntime;
99 : struct JSSecurityCallbacks;
100 : struct JSStructuredCloneCallbacks;
101 : struct JSStructuredCloneReader;
102 : struct JSStructuredCloneWriter;
103 : class JS_PUBLIC_API(JSTracer);
104 :
105 : class JSFlatString;
106 :
107 : typedef bool (*JSInitCallback)(void);
108 :
109 : template<typename T> struct JSConstScalarSpec;
110 : typedef JSConstScalarSpec<double> JSConstDoubleSpec;
111 : typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec;
112 :
113 : /*
114 : * Generic trace operation that calls JS::TraceEdge on each traceable thing's
115 : * location reachable from data.
116 : */
117 : typedef void
118 : (* JSTraceDataOp)(JSTracer* trc, void* data);
119 :
120 : namespace js {
121 : namespace gc {
122 : class AutoTraceSession;
123 : class StoreBuffer;
124 : } // namespace gc
125 :
126 : class CooperatingContext;
127 :
128 : inline JSCompartment* GetContextCompartment(const JSContext* cx);
129 : inline JS::Zone* GetContextZone(const JSContext* cx);
130 :
131 : // Whether the current thread is permitted access to any part of the specified
132 : // runtime or zone.
133 : JS_FRIEND_API(bool)
134 : CurrentThreadCanAccessRuntime(const JSRuntime* rt);
135 :
136 : #ifdef DEBUG
137 : JS_FRIEND_API(bool)
138 : CurrentThreadIsPerformingGC();
139 : #endif
140 :
141 : } // namespace js
142 :
143 : namespace JS {
144 :
145 : class JS_PUBLIC_API(AutoEnterCycleCollection);
146 : class JS_PUBLIC_API(AutoAssertOnBarrier);
147 : struct JS_PUBLIC_API(PropertyDescriptor);
148 :
149 : typedef void (*OffThreadCompileCallback)(void* token, void* callbackData);
150 :
151 : enum class HeapState {
152 : Idle, // doing nothing with the GC heap
153 : Tracing, // tracing the GC heap without collecting, e.g. IterateCompartments()
154 : MajorCollecting, // doing a GC of the major heap
155 : MinorCollecting, // doing a GC of the minor heap (nursery)
156 : CycleCollecting // in the "Unlink" phase of cycle collection
157 : };
158 :
159 : JS_PUBLIC_API(HeapState)
160 : CurrentThreadHeapState();
161 :
162 : static inline bool
163 797788 : CurrentThreadIsHeapBusy()
164 : {
165 797788 : return CurrentThreadHeapState() != HeapState::Idle;
166 : }
167 :
168 : static inline bool
169 : CurrentThreadIsHeapTracing()
170 : {
171 : return CurrentThreadHeapState() == HeapState::Tracing;
172 : }
173 :
174 : static inline bool
175 70730 : CurrentThreadIsHeapMajorCollecting()
176 : {
177 70730 : return CurrentThreadHeapState() == HeapState::MajorCollecting;
178 : }
179 :
180 : static inline bool
181 141570 : CurrentThreadIsHeapMinorCollecting()
182 : {
183 141570 : return CurrentThreadHeapState() == HeapState::MinorCollecting;
184 : }
185 :
186 : static inline bool
187 1559466 : CurrentThreadIsHeapCollecting()
188 : {
189 1559466 : HeapState state = CurrentThreadHeapState();
190 1559469 : return state == HeapState::MajorCollecting || state == HeapState::MinorCollecting;
191 : }
192 :
193 : static inline bool
194 1074232 : CurrentThreadIsHeapCycleCollecting()
195 : {
196 1074232 : return CurrentThreadHeapState() == HeapState::CycleCollecting;
197 : }
198 :
199 : // Decorates the Unlinking phase of CycleCollection so that accidental use
200 : // of barriered accessors results in assertions instead of leaks.
201 : class MOZ_STACK_CLASS JS_PUBLIC_API(AutoEnterCycleCollection)
202 : {
203 : #ifdef DEBUG
204 : public:
205 : explicit AutoEnterCycleCollection(JSRuntime* rt);
206 : ~AutoEnterCycleCollection();
207 : #else
208 : public:
209 : explicit AutoEnterCycleCollection(JSRuntime* rt) {}
210 : ~AutoEnterCycleCollection() {}
211 : #endif
212 : };
213 :
214 : class RootingContext;
215 :
216 : class JS_PUBLIC_API(AutoGCRooter)
217 : {
218 : public:
219 : AutoGCRooter(JSContext* cx, ptrdiff_t tag);
220 : AutoGCRooter(RootingContext* cx, ptrdiff_t tag);
221 :
222 141824 : ~AutoGCRooter() {
223 70912 : MOZ_ASSERT(this == *stackTop);
224 70912 : *stackTop = down;
225 70912 : }
226 :
227 : /* Implemented in gc/RootMarking.cpp. */
228 : inline void trace(JSTracer* trc);
229 : static void traceAll(const js::CooperatingContext& target, JSTracer* trc);
230 : static void traceAllWrappers(const js::CooperatingContext& target, JSTracer* trc);
231 :
232 : protected:
233 : AutoGCRooter * const down;
234 :
235 : /*
236 : * Discriminates actual subclass of this being used. If non-negative, the
237 : * subclass roots an array of values of the length stored in this field.
238 : * If negative, meaning is indicated by the corresponding value in the enum
239 : * below. Any other negative value indicates some deeper problem such as
240 : * memory corruption.
241 : */
242 : ptrdiff_t tag_;
243 :
244 : enum {
245 : VALARRAY = -2, /* js::AutoValueArray */
246 : PARSER = -3, /* js::frontend::Parser */
247 : VALVECTOR = -10, /* js::AutoValueVector */
248 : IDVECTOR = -11, /* js::AutoIdVector */
249 : OBJVECTOR = -14, /* js::AutoObjectVector */
250 : IONMASM = -19, /* js::jit::MacroAssembler */
251 : WRAPVECTOR = -20, /* js::AutoWrapperVector */
252 : WRAPPER = -21, /* js::AutoWrapperRooter */
253 : CUSTOM = -26 /* js::CustomAutoRooter */
254 : };
255 :
256 : static ptrdiff_t GetTag(const Value& value) { return VALVECTOR; }
257 : static ptrdiff_t GetTag(const jsid& id) { return IDVECTOR; }
258 : static ptrdiff_t GetTag(JSObject* obj) { return OBJVECTOR; }
259 :
260 : private:
261 : AutoGCRooter ** const stackTop;
262 :
263 : /* No copy or assignment semantics. */
264 : AutoGCRooter(AutoGCRooter& ida) = delete;
265 : void operator=(AutoGCRooter& ida) = delete;
266 : };
267 :
268 : // Our instantiations of Rooted<void*> and PersistentRooted<void*> require an
269 : // instantiation of MapTypeToRootKind.
270 : template <>
271 : struct MapTypeToRootKind<void*> {
272 : static const RootKind kind = RootKind::Traceable;
273 : };
274 :
275 : using RootedListHeads = mozilla::EnumeratedArray<RootKind, RootKind::Limit,
276 : Rooted<void*>*>;
277 :
278 : /*
279 : * This list enumerates the different types of conceptual stacks we have in
280 : * SpiderMonkey. In reality, they all share the C stack, but we allow different
281 : * stack limits depending on the type of code running.
282 : */
283 : enum StackKind
284 : {
285 : StackForSystemCode, // C++, such as the GC, running on behalf of the VM.
286 : StackForTrustedScript, // Script running with trusted principals.
287 : StackForUntrustedScript, // Script running with untrusted principals.
288 : StackKindCount
289 : };
290 :
291 : // Superclass of JSContext which can be used for rooting data in use by the
292 : // current thread but that does not provide all the functions of a JSContext.
293 : class RootingContext
294 : {
295 : // Stack GC roots for Rooted GC heap pointers.
296 : RootedListHeads stackRoots_;
297 : template <typename T> friend class JS::Rooted;
298 :
299 : // Stack GC roots for AutoFooRooter classes.
300 : JS::AutoGCRooter* autoGCRooters_;
301 : friend class JS::AutoGCRooter;
302 :
303 : public:
304 : RootingContext();
305 :
306 : void traceStackRoots(JSTracer* trc);
307 : void checkNoGCRooters();
308 :
309 : protected:
310 : // The remaining members in this class should only be accessed through
311 : // JSContext pointers. They are unrelated to rooting and are in place so
312 : // that inlined API functions can directly access the data.
313 :
314 : /* The current compartment. */
315 : JSCompartment* compartment_;
316 :
317 : /* The current zone. */
318 : JS::Zone* zone_;
319 :
320 : public:
321 : /* Limit pointer for checking native stack consumption. */
322 : uintptr_t nativeStackLimit[StackKindCount];
323 :
324 43798 : static const RootingContext* get(const JSContext* cx) {
325 43798 : return reinterpret_cast<const RootingContext*>(cx);
326 : }
327 :
328 7808743 : static RootingContext* get(JSContext* cx) {
329 7808743 : return reinterpret_cast<RootingContext*>(cx);
330 : }
331 :
332 : friend JSCompartment* js::GetContextCompartment(const JSContext* cx);
333 : friend JS::Zone* js::GetContextZone(const JSContext* cx);
334 : };
335 :
336 : } /* namespace JS */
337 :
338 : namespace js {
339 :
340 : /*
341 : * Inlinable accessors for JSContext.
342 : *
343 : * - These must not be available on the more restricted superclasses of
344 : * JSContext, so we can't simply define them on RootingContext.
345 : *
346 : * - They're perfectly ordinary JSContext functionality, so ought to be
347 : * usable without resorting to jsfriendapi.h, and when JSContext is an
348 : * incomplete type.
349 : */
350 : inline JSCompartment*
351 43793 : GetContextCompartment(const JSContext* cx)
352 : {
353 43793 : return JS::RootingContext::get(cx)->compartment_;
354 : }
355 :
356 : inline JS::Zone*
357 5 : GetContextZone(const JSContext* cx)
358 : {
359 5 : return JS::RootingContext::get(cx)->zone_;
360 : }
361 :
362 : } /* namespace js */
363 :
364 : MOZ_BEGIN_EXTERN_C
365 :
366 : // Defined in NSPR prio.h.
367 : typedef struct PRFileDesc PRFileDesc;
368 :
369 : MOZ_END_EXTERN_C
370 :
371 : #endif /* jspubtd_h */
|