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