|
|
1.1 root 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 ***** */
39:
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"
57:
58: JS_BEGIN_EXTERN_C
59:
60: typedef enum JSGCMode { JS_NO_GC, JS_MAYBE_GC, JS_FORCE_GC } JSGCMode;
61:
62: typedef enum JSRuntimeState {
63: JSRTS_DOWN,
64: JSRTS_LAUNCHING,
65: JSRTS_UP,
66: JSRTS_LANDING
67: } JSRuntimeState;
68:
69: typedef struct JSPropertyTreeEntry {
70: JSDHashEntryHdr hdr;
71: JSScopeProperty *child;
72: } JSPropertyTreeEntry;
73:
74: struct JSRuntime {
75: /* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */
76: JSRuntimeState state;
77:
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
96:
97: /* Literal table maintained by jsatom.c functions. */
98: JSAtomState atomState;
99:
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;
107:
108: /* Well-known numbers held for use by this runtime's contexts. */
109: jsdouble *jsNaN;
110: jsdouble *jsNegativeInfinity;
111: jsdouble *jsPositiveInfinity;
112:
113: /* Empty string held for use by this runtime's contexts. */
114: JSString *emptyString;
115:
116: /* List of active contexts sharing this runtime; protected by gcLock. */
117: JSCList contextList;
118:
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;
140:
141: /* More debugging state, see jsdbgapi.c. */
142: JSCList trapList;
143: JSCList watchPointList;
144:
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;
148:
149: /* Client opaque pointer */
150: void *data;
151:
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;
159:
160: /* Lock and owning thread pointer for JS_LOCK_RUNTIME. */
161: PRLock *rtLock;
162: #ifdef DEBUG
163: jsword rtLockOwner;
164: #endif
165:
166: /* Used to synchronize down/up state change; protected by gcLock. */
167: PRCondVar *stateChange;
168:
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 */
174:
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;
187:
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 */
197:
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;
203:
204: /* Security principals serialization support. */
205: JSPrincipalsTranscoder principalsTranscoder;
206:
207: /* Shared scope property tree, and allocator for its nodes. */
208: JSDHashTable propertyTreeHash;
209: JSScopeProperty *propertyFreeList;
210: JSArenaPool propertyArenaPool;
211:
212: /* Script filename table. */
213: struct JSHashTable *scriptFilenameTable;
214: #ifdef JS_THREADSAFE
215: PRLock *scriptFilenameTableLock;
216: #endif
217:
218: /* Number localization, used by jsnum.c */
219: const char *thousandsSeparator;
220: const char *decimalSeparator;
221: const char *numGrouping;
222:
223: #ifdef DEBUG
224: /* Function invocation metering. */
225: jsrefcount inlineCalls;
226: jsrefcount nativeCalls;
227: jsrefcount nonInlineCalls;
228: jsrefcount constructs;
229:
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;
246:
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: };
258:
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
266:
267: #define JS_KEEP_ATOMS(rt) JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms);
268: #define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms);
269:
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
283:
284: struct JSStackHeader {
285: uintN nslots;
286: JSStackHeader *down;
287: };
288:
289: #define JS_STACK_SEGMENT(sh) ((jsval *)(sh) + 2)
290:
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;
301:
302: typedef struct JSResolvingEntry {
303: JSDHashEntryHdr hdr;
304: JSResolvingKey key;
305: uint32 flags;
306: } JSResolvingEntry;
307:
308: #define JSRESFLAG_LOOKUP 0x1 /* resolving id from lookup */
309: #define JSRESFLAG_WATCH 0x2 /* resolving id from watch */
310:
311: typedef struct JSLocalRootChunk JSLocalRootChunk;
312:
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)
316:
317: struct JSLocalRootChunk {
318: jsval roots[JSLRS_CHUNK_SIZE];
319: JSLocalRootChunk *down;
320: };
321:
322: typedef struct JSLocalRootStack {
323: uint16 scopeMark;
324: uint16 rootCount;
325: JSLocalRootChunk *topChunk;
326: JSLocalRootChunk firstChunk;
327: } JSLocalRootStack;
328:
329: #define JSLRS_NULL_MARK ((uint16) -1)
330:
331: struct JSContext {
332: JSCList links;
333:
334: /* Interpreter activation count. */
335: uintN interpLevel;
336:
337: /* Limit pointer for checking stack consumption during recursion. */
338: jsuword stackLimit;
339:
340: /* Runtime version control identifier and equality operators. */
341: JSVersion version;
342: jsbytecode jsop_eq;
343: jsbytecode jsop_ne;
344:
345: /* Data shared by threads in an address space. */
346: JSRuntime *runtime;
347:
348: /* Stack arena pool and frame pointer register. */
349: JSArenaPool stackPool;
350: JSStackFrame *fp;
351:
352: /* Temporary arena pool used while compiling and decompiling. */
353: JSArenaPool tempPool;
354:
355: /* Top-level object and pointer to top stack frame's scope chain. */
356: JSObject *globalObject;
357:
358: /* Most recently created things by type, members of the GC's root set. */
359: JSGCThing *newborn[GCX_NTYPES];
360:
361: /* Atom root for the last-looked-up atom on this context. */
362: JSAtom *lastAtom;
363:
364: /* Regular expression class statics (XXX not shared globally). */
365: JSRegExpStatics regExpStatics;
366:
367: /* State for object and array toSource conversion. */
368: JSSharpObjectMap sharpObjectMap;
369:
370: /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */
371: JSArgumentFormatMap *argumentFormatMap;
372:
373: /* Last message string and trace file for debugging. */
374: char *lastMessage;
375: #ifdef DEBUG
376: void *tracefp;
377: #endif
378:
379: /* Per-context optional user callbacks. */
380: JSBranchCallback branchCallback;
381: JSErrorReporter errorReporter;
382:
383: /* Client opaque pointer */
384: void *data;
385:
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
395:
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
406:
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;
413:
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 */
420:
421: /* Per-context options. */
422: uint32 options; /* see jsapi.h for JSOPTION_* */
423:
424: /* Locale specific callbacks for string conversion. */
425: JSLocaleCallbacks *localeCallbacks;
426:
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;
434:
435: /* PDL of stack headers describing stack slots not rooted by argv, etc. */
436: JSStackHeader *stackHeaders;
437:
438: /* Optional hook to find principals for an object being accessed on cx. */
439: JSObjectPrincipalsFinder findObjectPrincipals;
440:
441: /* Optional stack of scoped local GC roots. */
442: JSLocalRootStack *localRootStack;
443: };
444:
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)
453:
454: extern JSContext *
455: js_NewContext(JSRuntime *rt, size_t stackChunkSize);
456:
457: extern void
458: js_DestroyContext(JSContext *cx, JSGCMode gcmode);
459:
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);
466:
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);
473:
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);
480:
481: extern void
482: js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
483: JSResolvingEntry *entry, uint32 generation);
484:
485: /*
486: * Local root set management.
487: */
488: extern JSBool
489: js_EnterLocalRootScope(JSContext *cx);
490:
491: extern void
492: js_LeaveLocalRootScope(JSContext *cx);
493:
494: extern void
495: js_ForgetLocalRoot(JSContext *cx, jsval v);
496:
497: extern int
498: js_PushLocalRoot(JSContext *cx, JSLocalRootStack *lrs, jsval v);
499:
500: extern void
501: js_MarkLocalRoots(JSContext *cx, JSLocalRootStack *lrs);
502:
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;
514:
515: extern const JSErrorFormatString *
516: js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
517:
518: #ifdef va_start
519: extern JSBool
520: js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap);
521:
522: extern JSBool
523: js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
524: void *userRef, const uintN errorNumber,
525: JSBool charArgs, va_list ap);
526:
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
533:
534: extern void
535: js_ReportOutOfMemory(JSContext *cx, JSErrorCallback errorCallback);
536:
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);
543:
544: extern void
545: js_ReportIsNotDefined(JSContext *cx, const char *name);
546:
547: extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
548:
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
561:
562: JS_END_EXTERN_C
563:
564: #endif /* jscntxt_h___ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.