1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 *
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * The Original Code is Mozilla Communicator client code, released
17 * March 31, 1998.
18 *
19 * The Initial Developer of the Original Code is
20 * Netscape Communications Corporation.
21 * Portions created by the Initial Developer are Copyright (C) 1998
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
40 #ifndef jscntxt_h___
41 #define jscntxt_h___
42 /*
43 * JS execution context.
44 */
45 #include "jsarena.h" /* Added by JSIFY */
46 #include "jsclist.h"
47 #include "jslong.h"
48 #include "jsatom.h"
49 #include "jsconfig.h"
50 #include "jsdhash.h"
51 #include "jsgc.h"
52 #include "jsinterp.h"
53 #include "jsobj.h"
54 #include "jsprvtd.h"
55 #include "jspubtd.h"
56 #include "jsregexp.h"
58 JS_BEGIN_EXTERN_C
60 typedef enum JSGCMode { JS_NO_GC, JS_MAYBE_GC, JS_FORCE_GC } JSGCMode;
62 typedef enum JSRuntimeState {
63 JSRTS_DOWN,
64 JSRTS_LAUNCHING,
65 JSRTS_UP,
66 JSRTS_LANDING
67 } JSRuntimeState;
69 typedef struct JSPropertyTreeEntry {
70 JSDHashEntryHdr hdr;
71 JSScopeProperty *child;
72 } JSPropertyTreeEntry;
74 struct JSRuntime {
75 /* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */
76 JSRuntimeState state;
78 /* Garbage collector state, used by jsgc.c. */
79 JSArenaPool gcArenaPool;
80 JSDHashTable gcRootsHash;
81 JSDHashTable *gcLocksHash;
82 JSGCThing *gcFreeList;
83 jsrefcount gcKeepAtoms;
84 uint32 gcBytes;
85 uint32 gcLastBytes;
86 uint32 gcMaxBytes;
87 uint32 gcLevel;
88 uint32 gcNumber;
89 JSPackedBool gcPoke;
90 JSPackedBool gcRunning;
91 JSGCCallback gcCallback;
92 uint32 gcMallocBytes;
93 #ifdef JS_GCMETER
94 JSGCStats gcStats;
95 #endif
97 /* Literal table maintained by jsatom.c functions. */
98 JSAtomState atomState;
100 /* Random number generator state, used by jsmath.c. */
101 JSBool rngInitialized;
102 int64 rngMultiplier;
103 int64 rngAddend;
104 int64 rngMask;
105 int64 rngSeed;
106 jsdouble rngDscale;
108 /* Well-known numbers held for use by this runtime's contexts. */
109 jsdouble *jsNaN;
110 jsdouble *jsNegativeInfinity;
111 jsdouble *jsPositiveInfinity;
113 /* Empty string held for use by this runtime's contexts. */
114 JSString *emptyString;
116 /* List of active contexts sharing this runtime; protected by gcLock. */
117 JSCList contextList;
119 /* These are used for debugging -- see jsprvtd.h and jsdbgapi.h. */
120 JSTrapHandler interruptHandler;
121 void *interruptHandlerData;
122 JSNewScriptHook newScriptHook;
123 void *newScriptHookData;
124 JSDestroyScriptHook destroyScriptHook;
125 void *destroyScriptHookData;
126 JSTrapHandler debuggerHandler;
127 void *debuggerHandlerData;
128 JSSourceHandler sourceHandler;
129 void *sourceHandlerData;
130 JSInterpreterHook executeHook;
131 void *executeHookData;
132 JSInterpreterHook callHook;
133 void *callHookData;
134 JSObjectHook objectHook;
135 void *objectHookData;
136 JSTrapHandler throwHook;
137 void *throwHookData;
138 JSDebugErrorHook debugErrorHook;
139 void *debugErrorHookData;
141 /* More debugging state, see jsdbgapi.c. */
142 JSCList trapList;
143 JSCList watchPointList;
145 /* Weak links to properties, indexed by quickened get/set opcodes. */
146 /* XXX must come after JSCLists or MSVC alignment bug bites empty lists */
147 JSPropertyCache propertyCache;
149 /* Client opaque pointer */
150 void *data;
152 #ifdef JS_THREADSAFE
153 /* These combine to interlock the GC and new requests. */
154 PRLock *gcLock;
155 PRCondVar *gcDone;
156 PRCondVar *requestDone;
157 uint32 requestCount;
158 jsword gcThread;
160 /* Lock and owning thread pointer for JS_LOCK_RUNTIME. */
161 PRLock *rtLock;
162 #ifdef DEBUG
163 jsword rtLockOwner;
164 #endif
166 /* Used to synchronize down/up state change; protected by gcLock. */
167 PRCondVar *stateChange;
169 /* Used to serialize cycle checks when setting __proto__ or __parent__. */
170 PRLock *setSlotLock;
171 PRCondVar *setSlotDone;
172 JSBool setSlotBusy;
173 JSScope *setSlotScope; /* deadlock avoidance, see jslock.c */
175 /*
176 * State for sharing single-threaded scopes, once a second thread tries to
177 * lock a scope. The scopeSharingDone condvar is protected by rt->gcLock,
178 * to minimize number of locks taken in JS_EndRequest.
179 *
180 * The scopeSharingTodo linked list is likewise "global" per runtime, not
181 * one-list-per-context, to conserve space over all contexts, optimizing
182 * for the likely case that scopes become shared rarely, and among a very
183 * small set of threads (contexts).
184 */
185 PRCondVar *scopeSharingDone;
186 JSScope *scopeSharingTodo;
188 /*
189 * Magic terminator for the rt->scopeSharingTodo linked list, threaded through
190 * scope->u.link. This hack allows us to test whether a scope is on the list
191 * by asking whether scope->u.link is non-null. We use a large, likely bogus
192 * pointer here to distinguish this value from any valid u.count (small int)
193 * value.
194 */
195 #define NO_SCOPE_SHARING_TODO ((JSScope *) 0xfeedbeef)
196 #endif /* JS_THREADSAFE */
198 /*
199 * Check property accessibility for objects of arbitrary class. Used at
200 * present to check f.caller accessibility for any function object f.
201 */
202 JSCheckAccessOp checkObjectAccess;
204 /* Security principals serialization support. */
205 JSPrincipalsTranscoder principalsTranscoder;
207 /* Shared scope property tree, and allocator for its nodes. */
208 JSDHashTable propertyTreeHash;
209 JSScopeProperty *propertyFreeList;
210 JSArenaPool propertyArenaPool;
212 #ifdef DEBUG
213 /* Function invocation metering. */
214 jsrefcount inlineCalls;
215 jsrefcount nativeCalls;
216 jsrefcount nonInlineCalls;
217 jsrefcount constructs;
219 /* Scope lock and property metering. */
220 jsrefcount claimAttempts;
221 jsrefcount claimedScopes;
222 jsrefcount deadContexts;
223 jsrefcount deadlocksAvoided;
224 jsrefcount liveScopes;
225 jsrefcount sharedScopes;
226 jsrefcount totalScopes;
227 jsrefcount badUndependStrings;
228 jsrefcount liveScopeProps;
229 jsrefcount totalScopeProps;
230 jsrefcount livePropTreeNodes;
231 jsrefcount duplicatePropTreeNodes;
232 jsrefcount totalPropTreeNodes;
233 jsrefcount propTreeKidsChunks;
234 jsrefcount middleDeleteFixups;
236 /* String instrumentation. */
237 jsrefcount liveStrings;
238 jsrefcount totalStrings;
239 jsrefcount liveDependentStrings;
240 jsrefcount totalDependentStrings;
241 double lengthSum;
242 double lengthSquaredSum;
243 double strdepLengthSum;
244 double strdepLengthSquaredSum;
245 #endif
246 };
248 #ifdef DEBUG
249 # define JS_RUNTIME_METER(rt, which) JS_ATOMIC_INCREMENT(&(rt)->which)
250 # define JS_RUNTIME_UNMETER(rt, which) JS_ATOMIC_DECREMENT(&(rt)->which)
251 #else
252 # define JS_RUNTIME_METER(rt, which) /* nothing */
253 # define JS_RUNTIME_UNMETER(rt, which) /* nothing */
254 #endif
256 #define JS_KEEP_ATOMS(rt) JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms);
257 #define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms);
259 #ifdef JS_ARGUMENT_FORMATTER_DEFINED
260 /*
261 * Linked list mapping format strings for JS_{Convert,Push}Arguments{,VA} to
262 * formatter functions. Elements are sorted in non-increasing format string
263 * length order.
264 */
265 struct JSArgumentFormatMap {
266 const char *format;
267 size_t length;
268 JSArgumentFormatter formatter;
269 JSArgumentFormatMap *next;
270 };
271 #endif
273 struct JSStackHeader {
274 uintN nslots;
275 JSStackHeader *down;
276 };
278 #define JS_STACK_SEGMENT(sh) ((jsval *)(sh) + 2)
280 /*
281 * Key and entry types for the JSContext.resolvingTable hash table, typedef'd
282 * here because all consumers need to see these declarations (and not just the
283 * typedef names, as would be the case for an opaque pointer-to-typedef'd-type
284 * declaration), along with cx->resolvingTable.
285 */
286 typedef struct JSResolvingKey {
287 JSObject *obj;
288 jsid id;
289 } JSResolvingKey;
291 typedef struct JSResolvingEntry {
292 JSDHashEntryHdr hdr;
293 JSResolvingKey key;
294 uint32 flags;
295 } JSResolvingEntry;
297 #define JSRESFLAG_LOOKUP 0x1 /* resolving id from lookup */
298 #define JSRESFLAG_WATCH 0x2 /* resolving id from watch */
300 struct JSContext {
301 JSCList links;
303 /* Interpreter activation count. */
304 uintN interpLevel;
306 /* Limit pointer for checking stack consumption during recursion. */
307 jsuword stackLimit;
309 /* Runtime version control identifier and equality operators. */
310 JSVersion version;
311 jsbytecode jsop_eq;
312 jsbytecode jsop_ne;
314 /* Data shared by threads in an address space. */
315 JSRuntime *runtime;
317 /* Stack arena pool and frame pointer register. */
318 JSArenaPool stackPool;
319 JSStackFrame *fp;
321 /* Temporary arena pool used while compiling and decompiling. */
322 JSArenaPool tempPool;
324 /* Top-level object and pointer to top stack frame's scope chain. */
325 JSObject *globalObject;
327 /* Most recently created things by type, members of the GC's root set. */
328 JSGCThing *newborn[GCX_NTYPES];
330 /* Atom root for the last-looked-up atom on this context. */
331 JSAtom *lastAtom;
333 /* Regular expression class statics (XXX not shared globally). */
334 JSRegExpStatics regExpStatics;
336 /* State for object and array toSource conversion. */
337 JSSharpObjectMap sharpObjectMap;
339 /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */
340 JSArgumentFormatMap *argumentFormatMap;
342 /* Last message string and trace file for debugging. */
343 char *lastMessage;
344 #ifdef DEBUG
345 void *tracefp;
346 #endif
348 /* Per-context optional user callbacks. */
349 JSBranchCallback branchCallback;
350 JSErrorReporter errorReporter;
352 /* Client opaque pointer */
353 void *data;
355 /* GC and thread-safe state. */
356 JSStackFrame *dormantFrameChain; /* dormant stack frame to scan */
357 #ifdef JS_THREADSAFE
358 jsword thread;
359 jsrefcount requestDepth;
360 JSScope *scopeToShare; /* weak reference, see jslock.c */
361 JSScope *lockedSealedScope; /* weak ref, for low-cost sealed
362 scope locking */
363 #endif
365 #if JS_HAS_LVALUE_RETURN
366 /*
367 * Secondary return value from native method called on the left-hand side
368 * of an assignment operator. The native should store the object in which
369 * to set a property in *rval, and return the property's id expressed as a
370 * jsval by calling JS_SetCallReturnValue2(cx, idval).
371 */
372 jsval rval2;
373 JSPackedBool rval2set;
374 #endif
376 /*
377 * True if creating an exception object, to prevent runaway recursion.
378 * NB: creatingException packs with rval2set, #if JS_HAS_LVALUE_RETURN,
379 * and with throwing, below.
380 */
381 JSPackedBool creatingException;
383 /*
384 * Exception state -- the exception member is a GC root by definition.
385 * NB: throwing packs with creatingException and rval2set, above.
386 */
387 JSPackedBool throwing; /* is there a pending exception? */
388 jsval exception; /* most-recently-thrown exception */
390 /* Per-context options. */
391 uint32 options; /* see jsapi.h for JSOPTION_* */
393 /* Locale specific callbacks for string conversion. */
394 JSLocaleCallbacks *localeCallbacks;
396 /*
397 * cx->resolvingTable is non-null and non-empty if we are initializing
398 * standard classes lazily, or if we are otherwise recursing indirectly
399 * from js_LookupProperty through a JSClass.resolve hook. It is used to
400 * limit runaway recursion (see jsapi.c and jsobj.c).
401 */
402 JSDHashTable *resolvingTable;
404 /* PDL of stack headers describing stack slots not rooted by argv, etc. */
405 JSStackHeader *stackHeaders;
407 /* Optional hook to find principals for an object being accessed on cx. */
408 JSObjectPrincipalsFinder findObjectPrincipals;
409 };
411 /* Slightly more readable macros, also to hide bitset implementation detail. */
412 #define JS_HAS_STRICT_OPTION(cx) ((cx)->options & JSOPTION_STRICT)
413 #define JS_HAS_WERROR_OPTION(cx) ((cx)->options & JSOPTION_WERROR)
415 extern JSContext *
416 js_NewContext(JSRuntime *rt, size_t stackChunkSize);
418 extern void
419 js_DestroyContext(JSContext *cx, JSGCMode gcmode);
421 /*
422 * Return true if cx points to a context in rt->contextList, else return false.
423 * NB: the caller (see jslock.c:ClaimScope) must hold rt->gcLock.
424 */
425 extern JSBool
426 js_ValidContextPointer(JSRuntime *rt, JSContext *cx);
428 /*
429 * If unlocked, acquire and release rt->gcLock around *iterp update; otherwise
430 * the caller must be holding rt->gcLock.
431 */
432 extern JSContext *
433 js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp);
435 /*
436 * Report an exception, which is currently realized as a printf-style format
437 * string and its arguments.
438 */
439 typedef enum JSErrNum {
440 #define MSG_DEF(name, number, count, exception, format) \
441 name = number,
442 #include "js.msg"
443 #undef MSG_DEF
444 JSErr_Limit
445 } JSErrNum;
447 extern const JSErrorFormatString *
448 js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
450 #ifdef va_start
451 extern JSBool
452 js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap);
454 extern JSBool
455 js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
456 void *userRef, const uintN errorNumber,
457 JSBool charArgs, va_list ap);
459 extern JSBool
460 js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
461 void *userRef, const uintN errorNumber,
462 char **message, JSErrorReport *reportp,
463 JSBool *warningp, JSBool charArgs, va_list ap);
464 #endif
466 extern void
467 js_ReportOutOfMemory(JSContext *cx, JSErrorCallback errorCallback);
469 /*
470 * Report an exception using a previously composed JSErrorReport.
471 * XXXbe remove from "friend" API
472 */
473 extern JS_FRIEND_API(void)
474 js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report);
476 extern void
477 js_ReportIsNotDefined(JSContext *cx, const char *name);
479 extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
481 /*
482 * See JS_SetThreadStackLimit in jsapi.c, where we check that the stack grows
483 * in the expected direction. On Unix-y systems, JS_STACK_GROWTH_DIRECTION is
484 * computed on the build host by jscpucfg.c and written into jsautocfg.h. The
485 * macro is hardcoded in jscpucfg.h on Windows and Mac systems (for historical
486 * reasons pre-dating autoconf usage).
487 */
488 #if JS_STACK_GROWTH_DIRECTION > 0
489 # define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) < (cx)->stackLimit)
490 #else
491 # define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) > (cx)->stackLimit)
492 #endif
494 JS_END_EXTERN_C
496 #endif /* jscntxt_h___ */