|
|
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.