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 /* Script filename table. */
213 struct JSHashTable *scriptFilenameTable;
214 #ifdef JS_THREADSAFE
215 PRLock *scriptFilenameTableLock;
216 #endif
218 /* Number localization, used by jsnum.c */
219 const char *thousandsSeparator;
220 const char *decimalSeparator;
221 const char *numGrouping;
223 #ifdef DEBUG
224 /* Function invocation metering. */
225 jsrefcount inlineCalls;
226 jsrefcount nativeCalls;
227 jsrefcount nonInlineCalls;
228 jsrefcount constructs;
230 /* Scope lock and property metering. */
231 jsrefcount claimAttempts;
232 jsrefcount claimedScopes;
233 jsrefcount deadContexts;
234 jsrefcount deadlocksAvoided;
235 jsrefcount liveScopes;
236 jsrefcount sharedScopes;
237 jsrefcount totalScopes;
238 jsrefcount badUndependStrings;
239 jsrefcount liveScopeProps;
240 jsrefcount totalScopeProps;
241 jsrefcount livePropTreeNodes;
242 jsrefcount duplicatePropTreeNodes;
243 jsrefcount totalPropTreeNodes;
244 jsrefcount propTreeKidsChunks;
245 jsrefcount middleDeleteFixups;
247 /* String instrumentation. */
248 jsrefcount liveStrings;
249 jsrefcount totalStrings;
250 jsrefcount liveDependentStrings;
251 jsrefcount totalDependentStrings;
252 double lengthSum;
253 double lengthSquaredSum;
254 double strdepLengthSum;
255 double strdepLengthSquaredSum;
256 #endif
257 };
259 #ifdef DEBUG
260 # define JS_RUNTIME_METER(rt, which) JS_ATOMIC_INCREMENT(&(rt)->which)
261 # define JS_RUNTIME_UNMETER(rt, which) JS_ATOMIC_DECREMENT(&(rt)->which)
262 #else
263 # define JS_RUNTIME_METER(rt, which) /* nothing */
264 # define JS_RUNTIME_UNMETER(rt, which) /* nothing */
265 #endif
267 #define JS_KEEP_ATOMS(rt) JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms);
268 #define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms);
270 #ifdef JS_ARGUMENT_FORMATTER_DEFINED
271 /*
272 * Linked list mapping format strings for JS_{Convert,Push}Arguments{,VA} to
273 * formatter functions. Elements are sorted in non-increasing format string
274 * length order.
275 */
276 struct JSArgumentFormatMap {
277 const char *format;
278 size_t length;
279 JSArgumentFormatter formatter;
280 JSArgumentFormatMap *next;
281 };
282 #endif
284 struct JSStackHeader {
285 uintN nslots;
286 JSStackHeader *down;
287 };
289 #define JS_STACK_SEGMENT(sh) ((jsval *)(sh) + 2)
291 /*
292 * Key and entry types for the JSContext.resolvingTable hash table, typedef'd
293 * here because all consumers need to see these declarations (and not just the
294 * typedef names, as would be the case for an opaque pointer-to-typedef'd-type
295 * declaration), along with cx->resolvingTable.
296 */
297 typedef struct JSResolvingKey {
298 JSObject *obj;
299 jsid id;
300 } JSResolvingKey;
302 typedef struct JSResolvingEntry {
303 JSDHashEntryHdr hdr;
304 JSResolvingKey key;
305 uint32 flags;
306 } JSResolvingEntry;
308 #define JSRESFLAG_LOOKUP 0x1 /* resolving id from lookup */
309 #define JSRESFLAG_WATCH 0x2 /* resolving id from watch */
311 typedef struct JSLocalRootChunk JSLocalRootChunk;
313 #define JSLRS_CHUNK_SHIFT 6
314 #define JSLRS_CHUNK_SIZE JS_BIT(JSLRS_CHUNK_SHIFT)
315 #define JSLRS_CHUNK_MASK JS_BITMASK(JSLRS_CHUNK_SHIFT)
317 struct JSLocalRootChunk {
318 jsval roots[JSLRS_CHUNK_SIZE];
319 JSLocalRootChunk *down;
320 };
322 typedef struct JSLocalRootStack {
323 uint16 scopeMark;
324 uint16 rootCount;
325 JSLocalRootChunk *topChunk;
326 JSLocalRootChunk firstChunk;
327 } JSLocalRootStack;
329 #define JSLRS_NULL_MARK ((uint16) -1)
331 struct JSContext {
332 JSCList links;
334 /* Interpreter activation count. */
335 uintN interpLevel;
337 /* Limit pointer for checking stack consumption during recursion. */
338 jsuword stackLimit;
340 /* Runtime version control identifier and equality operators. */
341 JSVersion version;
342 jsbytecode jsop_eq;
343 jsbytecode jsop_ne;
345 /* Data shared by threads in an address space. */
346 JSRuntime *runtime;
348 /* Stack arena pool and frame pointer register. */
349 JSArenaPool stackPool;
350 JSStackFrame *fp;
352 /* Temporary arena pool used while compiling and decompiling. */
353 JSArenaPool tempPool;
355 /* Top-level object and pointer to top stack frame's scope chain. */
356 JSObject *globalObject;
358 /* Most recently created things by type, members of the GC's root set. */
359 JSGCThing *newborn[GCX_NTYPES];
361 /* Atom root for the last-looked-up atom on this context. */
362 JSAtom *lastAtom;
364 /* Regular expression class statics (XXX not shared globally). */
365 JSRegExpStatics regExpStatics;
367 /* State for object and array toSource conversion. */
368 JSSharpObjectMap sharpObjectMap;
370 /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */
371 JSArgumentFormatMap *argumentFormatMap;
373 /* Last message string and trace file for debugging. */
374 char *lastMessage;
375 #ifdef DEBUG
376 void *tracefp;
377 #endif
379 /* Per-context optional user callbacks. */
380 JSBranchCallback branchCallback;
381 JSErrorReporter errorReporter;
383 /* Client opaque pointer */
384 void *data;
386 /* GC and thread-safe state. */
387 JSStackFrame *dormantFrameChain; /* dormant stack frame to scan */
388 #ifdef JS_THREADSAFE
389 jsword thread;
390 jsrefcount requestDepth;
391 JSScope *scopeToShare; /* weak reference, see jslock.c */
392 JSScope *lockedSealedScope; /* weak ref, for low-cost sealed
393 scope locking */
394 #endif
396 #if JS_HAS_LVALUE_RETURN
397 /*
398 * Secondary return value from native method called on the left-hand side
399 * of an assignment operator. The native should store the object in which
400 * to set a property in *rval, and return the property's id expressed as a
401 * jsval by calling JS_SetCallReturnValue2(cx, idval).
402 */
403 jsval rval2;
404 JSPackedBool rval2set;
405 #endif
407 /*
408 * True if creating an exception object, to prevent runaway recursion.
409 * NB: creatingException packs with rval2set, #if JS_HAS_LVALUE_RETURN,
410 * and with throwing, below.
411 */
412 JSPackedBool creatingException;
414 /*
415 * Exception state -- the exception member is a GC root by definition.
416 * NB: throwing packs with creatingException and rval2set, above.
417 */
418 JSPackedBool throwing; /* is there a pending exception? */
419 jsval exception; /* most-recently-thrown exception */
421 /* Per-context options. */
422 uint32 options; /* see jsapi.h for JSOPTION_* */
424 /* Locale specific callbacks for string conversion. */
425 JSLocaleCallbacks *localeCallbacks;
427 /*
428 * cx->resolvingTable is non-null and non-empty if we are initializing
429 * standard classes lazily, or if we are otherwise recursing indirectly
430 * from js_LookupProperty through a JSClass.resolve hook. It is used to
431 * limit runaway recursion (see jsapi.c and jsobj.c).
432 */
433 JSDHashTable *resolvingTable;
435 /* PDL of stack headers describing stack slots not rooted by argv, etc. */
436 JSStackHeader *stackHeaders;
438 /* Optional hook to find principals for an object being accessed on cx. */
439 JSObjectPrincipalsFinder findObjectPrincipals;
441 /* Optional stack of scoped local GC roots. */
442 JSLocalRootStack *localRootStack;
443 };
445 /*
446 * Slightly more readable macros, also to hide bitset implementation detail.
447 * XXX beware non-boolean truth values, which belie the bitset hiding claim!
448 */
449 #define JS_HAS_STRICT_OPTION(cx) ((cx)->options & JSOPTION_STRICT)
450 #define JS_HAS_WERROR_OPTION(cx) ((cx)->options & JSOPTION_WERROR)
451 #define JS_HAS_COMPILE_N_GO_OPTION(cx) ((cx)->options & JSOPTION_COMPILE_N_GO)
452 #define JS_HAS_ATLINE_OPTION(cx) ((cx)->options & JSOPTION_ATLINE)
454 extern JSContext *
455 js_NewContext(JSRuntime *rt, size_t stackChunkSize);
457 extern void
458 js_DestroyContext(JSContext *cx, JSGCMode gcmode);
460 /*
461 * Return true if cx points to a context in rt->contextList, else return false.
462 * NB: the caller (see jslock.c:ClaimScope) must hold rt->gcLock.
463 */
464 extern JSBool
465 js_ValidContextPointer(JSRuntime *rt, JSContext *cx);
467 /*
468 * If unlocked, acquire and release rt->gcLock around *iterp update; otherwise
469 * the caller must be holding rt->gcLock.
470 */
471 extern JSContext *
472 js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp);
474 /*
475 * JSClass.resolve and watchpoint recursion damping machinery.
476 */
477 extern JSBool
478 js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
479 JSResolvingEntry **entryp);
481 extern void
482 js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
483 JSResolvingEntry *entry, uint32 generation);
485 /*
486 * Local root set management.
487 */
488 extern JSBool
489 js_EnterLocalRootScope(JSContext *cx);
491 extern void
492 js_LeaveLocalRootScope(JSContext *cx);
494 extern void
495 js_ForgetLocalRoot(JSContext *cx, jsval v);
497 extern int
498 js_PushLocalRoot(JSContext *cx, JSLocalRootStack *lrs, jsval v);
500 extern void
501 js_MarkLocalRoots(JSContext *cx, JSLocalRootStack *lrs);
503 /*
504 * Report an exception, which is currently realized as a printf-style format
505 * string and its arguments.
506 */
507 typedef enum JSErrNum {
508 #define MSG_DEF(name, number, count, exception, format) \
509 name = number,
510 #include "js.msg"
511 #undef MSG_DEF
512 JSErr_Limit
513 } JSErrNum;
515 extern const JSErrorFormatString *
516 js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
518 #ifdef va_start
519 extern JSBool
520 js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap);
522 extern JSBool
523 js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
524 void *userRef, const uintN errorNumber,
525 JSBool charArgs, va_list ap);
527 extern JSBool
528 js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
529 void *userRef, const uintN errorNumber,
530 char **message, JSErrorReport *reportp,
531 JSBool *warningp, JSBool charArgs, va_list ap);
532 #endif
534 extern void
535 js_ReportOutOfMemory(JSContext *cx, JSErrorCallback errorCallback);
537 /*
538 * Report an exception using a previously composed JSErrorReport.
539 * XXXbe remove from "friend" API
540 */
541 extern JS_FRIEND_API(void)
542 js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report);
544 extern void
545 js_ReportIsNotDefined(JSContext *cx, const char *name);
547 extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
549 /*
550 * See JS_SetThreadStackLimit in jsapi.c, where we check that the stack grows
551 * in the expected direction. On Unix-y systems, JS_STACK_GROWTH_DIRECTION is
552 * computed on the build host by jscpucfg.c and written into jsautocfg.h. The
553 * macro is hardcoded in jscpucfg.h on Windows and Mac systems (for historical
554 * reasons pre-dating autoconf usage).
555 */
556 #if JS_STACK_GROWTH_DIRECTION > 0
557 # define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) < (cx)->stackLimit)
558 #else
559 # define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) > (cx)->stackLimit)
560 #endif
562 JS_END_EXTERN_C
564 #endif /* jscntxt_h___ */