|
|
1.1 root 1: /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.1.1.2 ! root 2: * vim: set ts=8 sw=4 et tw=78: 1.1 root 3: * 4: * ***** BEGIN LICENSE BLOCK ***** 5: * Version: MPL 1.1/GPL 2.0/LGPL 2.1 6: * 7: * The contents of this file are subject to the Mozilla Public License Version 8: * 1.1 (the "License"); you may not use this file except in compliance with 9: * the License. You may obtain a copy of the License at 10: * http://www.mozilla.org/MPL/ 11: * 12: * Software distributed under the License is distributed on an "AS IS" basis, 13: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 14: * for the specific language governing rights and limitations under the 15: * License. 16: * 17: * The Original Code is Mozilla Communicator client code, released 18: * March 31, 1998. 19: * 20: * The Initial Developer of the Original Code is 21: * Netscape Communications Corporation. 22: * Portions created by the Initial Developer are Copyright (C) 1998 23: * the Initial Developer. All Rights Reserved. 24: * 25: * Contributor(s): 26: * 27: * Alternatively, the contents of this file may be used under the terms of 28: * either of the GNU General Public License Version 2 or later (the "GPL"), 29: * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 30: * in which case the provisions of the GPL or the LGPL are applicable instead 31: * of those above. If you wish to allow use of your version of this file only 32: * under the terms of either the GPL or the LGPL, and not to allow others to 33: * use your version of this file under the terms of the MPL, indicate your 34: * decision by deleting the provisions above and replace them with the notice 35: * and other provisions required by the GPL or the LGPL. If you do not delete 36: * the provisions above, a recipient may use your version of this file under 37: * the terms of any one of the MPL, the GPL or the LGPL. 38: * 39: * ***** END LICENSE BLOCK ***** */ 40: 41: #ifndef jscntxt_h___ 42: #define jscntxt_h___ 43: /* 44: * JS execution context. 45: */ 46: #include "jsarena.h" /* Added by JSIFY */ 47: #include "jsclist.h" 48: #include "jslong.h" 49: #include "jsatom.h" 50: #include "jsconfig.h" 51: #include "jsdhash.h" 52: #include "jsgc.h" 53: #include "jsinterp.h" 54: #include "jsobj.h" 55: #include "jsprvtd.h" 56: #include "jspubtd.h" 57: #include "jsregexp.h" 1.1.1.2 ! root 58: #include "jsutil.h" 1.1 root 59: 60: JS_BEGIN_EXTERN_C 61: 1.1.1.2 ! root 62: /* ! 63: * js_GetSrcNote cache to avoid O(n^2) growth in finding a source note for a ! 64: * given pc in a script. ! 65: */ ! 66: typedef struct JSGSNCache { ! 67: JSScript *script; ! 68: JSDHashTable table; ! 69: #ifdef JS_GSNMETER ! 70: uint32 hits; ! 71: uint32 misses; ! 72: uint32 fills; ! 73: uint32 clears; ! 74: # define GSN_CACHE_METER(cache,cnt) (++(cache)->cnt) ! 75: #else ! 76: # define GSN_CACHE_METER(cache,cnt) /* nothing */ ! 77: #endif ! 78: } JSGSNCache; ! 79: ! 80: #define GSN_CACHE_CLEAR(cache) \ ! 81: JS_BEGIN_MACRO \ ! 82: (cache)->script = NULL; \ ! 83: if ((cache)->table.ops) { \ ! 84: JS_DHashTableFinish(&(cache)->table); \ ! 85: (cache)->table.ops = NULL; \ ! 86: } \ ! 87: GSN_CACHE_METER(cache, clears); \ ! 88: JS_END_MACRO ! 89: ! 90: /* These helper macros take a cx as parameter and operate on its GSN cache. */ ! 91: #define JS_CLEAR_GSN_CACHE(cx) GSN_CACHE_CLEAR(&JS_GSN_CACHE(cx)) ! 92: #define JS_METER_GSN_CACHE(cx,cnt) GSN_CACHE_METER(&JS_GSN_CACHE(cx), cnt) ! 93: ! 94: #ifdef JS_THREADSAFE ! 95: ! 96: /* ! 97: * Structure uniquely representing a thread. It holds thread-private data ! 98: * that can be accessed without a global lock. ! 99: */ ! 100: struct JSThread { ! 101: /* Linked list of all contexts active on this thread. */ ! 102: JSCList contextList; ! 103: ! 104: /* Opaque thread-id, from NSPR's PR_GetCurrentThread(). */ ! 105: jsword id; ! 106: ! 107: /* Thread-local gc free lists array. */ ! 108: JSGCThing *gcFreeLists[GC_NUM_FREELISTS]; ! 109: ! 110: /* ! 111: * Thread-local version of JSRuntime.gcMallocBytes to avoid taking ! 112: * locks on each JS_malloc. ! 113: */ ! 114: uint32 gcMallocBytes; ! 115: ! 116: #if JS_HAS_GENERATORS ! 117: /* Flag indicating that the current thread is executing close hooks. */ ! 118: JSBool gcRunningCloseHooks; ! 119: #endif ! 120: ! 121: /* ! 122: * Store the GSN cache in struct JSThread, not struct JSContext, both to ! 123: * save space and to simplify cleanup in js_GC. Any embedding (Firefox ! 124: * or another Gecko application) that uses many contexts per thread is ! 125: * unlikely to interleave js_GetSrcNote-intensive loops in the decompiler ! 126: * among two or more contexts running script in one thread. ! 127: */ ! 128: JSGSNCache gsnCache; ! 129: }; ! 130: ! 131: #define JS_GSN_CACHE(cx) ((cx)->thread->gsnCache) ! 132: ! 133: extern void JS_DLL_CALLBACK ! 134: js_ThreadDestructorCB(void *ptr); ! 135: ! 136: extern JSBool ! 137: js_SetContextThread(JSContext *cx); ! 138: ! 139: extern void ! 140: js_ClearContextThread(JSContext *cx); ! 141: ! 142: extern JSThread * ! 143: js_GetCurrentThread(JSRuntime *rt); ! 144: ! 145: #endif /* JS_THREADSAFE */ ! 146: ! 147: typedef enum JSDestroyContextMode { ! 148: JSDCM_NO_GC, ! 149: JSDCM_MAYBE_GC, ! 150: JSDCM_FORCE_GC, ! 151: JSDCM_NEW_FAILED ! 152: } JSDestroyContextMode; 1.1 root 153: 154: typedef enum JSRuntimeState { 155: JSRTS_DOWN, 156: JSRTS_LAUNCHING, 157: JSRTS_UP, 158: JSRTS_LANDING 159: } JSRuntimeState; 160: 161: typedef struct JSPropertyTreeEntry { 162: JSDHashEntryHdr hdr; 163: JSScopeProperty *child; 164: } JSPropertyTreeEntry; 165: 1.1.1.2 ! root 166: /* ! 167: * Forward declaration for opaque JSRuntime.nativeIteratorStates. ! 168: */ ! 169: typedef struct JSNativeIteratorState JSNativeIteratorState; ! 170: 1.1 root 171: struct JSRuntime { 172: /* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */ 173: JSRuntimeState state; 174: 1.1.1.2 ! root 175: /* Context create/destroy callback. */ ! 176: JSContextCallback cxCallback; ! 177: 1.1 root 178: /* Garbage collector state, used by jsgc.c. */ 1.1.1.2 ! root 179: JSGCArenaList gcArenaList[GC_NUM_FREELISTS]; 1.1 root 180: JSDHashTable gcRootsHash; 181: JSDHashTable *gcLocksHash; 182: jsrefcount gcKeepAtoms; 183: uint32 gcBytes; 184: uint32 gcLastBytes; 185: uint32 gcMaxBytes; 1.1.1.2 ! root 186: uint32 gcMaxMallocBytes; 1.1 root 187: uint32 gcLevel; 188: uint32 gcNumber; 1.1.1.2 ! root 189: ! 190: /* ! 191: * NB: do not pack another flag here by claiming gcPadding unless the new ! 192: * flag is written only by the GC thread. Atomic updates to packed bytes ! 193: * are not guaranteed, so stores issued by one thread may be lost due to ! 194: * unsynchronized read-modify-write cycles on other threads. ! 195: */ 1.1 root 196: JSPackedBool gcPoke; 197: JSPackedBool gcRunning; 1.1.1.2 ! root 198: uint16 gcPadding; ! 199: 1.1 root 200: JSGCCallback gcCallback; 201: uint32 gcMallocBytes; 1.1.1.2 ! root 202: JSGCArena *gcUnscannedArenaStackTop; ! 203: #ifdef DEBUG ! 204: size_t gcUnscannedBagSize; ! 205: #endif ! 206: ! 207: /* ! 208: * API compatibility requires keeping GCX_PRIVATE bytes separate from the ! 209: * original GC types' byte tally. Otherwise embeddings that configure a ! 210: * good limit for pre-GCX_PRIVATE versions of the engine will see memory ! 211: * over-pressure too often, possibly leading to failed last-ditch GCs. ! 212: * ! 213: * The new XML GC-thing types do add to gcBytes, and they're larger than ! 214: * the original GC-thing type size (8 bytes on most architectures). So a ! 215: * user who enables E4X may want to increase the maxbytes value passed to ! 216: * JS_NewRuntime. TODO: Note this in the API docs. ! 217: */ ! 218: uint32 gcPrivateBytes; ! 219: ! 220: /* ! 221: * Table for tracking iterators to ensure that we close iterator's state ! 222: * before finalizing the iterable object. ! 223: */ ! 224: JSPtrTable gcIteratorTable; ! 225: ! 226: #if JS_HAS_GENERATORS ! 227: /* Runtime state to support close hooks. */ ! 228: JSGCCloseState gcCloseState; ! 229: #endif ! 230: 1.1 root 231: #ifdef JS_GCMETER 232: JSGCStats gcStats; 233: #endif 234: 235: /* Literal table maintained by jsatom.c functions. */ 236: JSAtomState atomState; 237: 238: /* Random number generator state, used by jsmath.c. */ 239: JSBool rngInitialized; 240: int64 rngMultiplier; 241: int64 rngAddend; 242: int64 rngMask; 243: int64 rngSeed; 244: jsdouble rngDscale; 245: 246: /* Well-known numbers held for use by this runtime's contexts. */ 247: jsdouble *jsNaN; 248: jsdouble *jsNegativeInfinity; 249: jsdouble *jsPositiveInfinity; 250: 1.1.1.2 ! root 251: #ifdef JS_THREADSAFE ! 252: JSLock *deflatedStringCacheLock; ! 253: #endif ! 254: JSHashTable *deflatedStringCache; ! 255: #ifdef DEBUG ! 256: uint32 deflatedStringCacheBytes; ! 257: #endif ! 258: 1.1 root 259: /* Empty string held for use by this runtime's contexts. */ 260: JSString *emptyString; 261: 262: /* List of active contexts sharing this runtime; protected by gcLock. */ 263: JSCList contextList; 264: 265: /* These are used for debugging -- see jsprvtd.h and jsdbgapi.h. */ 266: JSTrapHandler interruptHandler; 267: void *interruptHandlerData; 268: JSNewScriptHook newScriptHook; 269: void *newScriptHookData; 270: JSDestroyScriptHook destroyScriptHook; 271: void *destroyScriptHookData; 272: JSTrapHandler debuggerHandler; 273: void *debuggerHandlerData; 274: JSSourceHandler sourceHandler; 275: void *sourceHandlerData; 276: JSInterpreterHook executeHook; 277: void *executeHookData; 278: JSInterpreterHook callHook; 279: void *callHookData; 280: JSObjectHook objectHook; 281: void *objectHookData; 282: JSTrapHandler throwHook; 283: void *throwHookData; 284: JSDebugErrorHook debugErrorHook; 285: void *debugErrorHookData; 286: 287: /* More debugging state, see jsdbgapi.c. */ 288: JSCList trapList; 289: JSCList watchPointList; 290: 291: /* Weak links to properties, indexed by quickened get/set opcodes. */ 292: /* XXX must come after JSCLists or MSVC alignment bug bites empty lists */ 293: JSPropertyCache propertyCache; 294: 295: /* Client opaque pointer */ 296: void *data; 297: 298: #ifdef JS_THREADSAFE 299: /* These combine to interlock the GC and new requests. */ 300: PRLock *gcLock; 301: PRCondVar *gcDone; 302: PRCondVar *requestDone; 303: uint32 requestCount; 1.1.1.2 ! root 304: JSThread *gcThread; 1.1 root 305: 306: /* Lock and owning thread pointer for JS_LOCK_RUNTIME. */ 307: PRLock *rtLock; 308: #ifdef DEBUG 309: jsword rtLockOwner; 310: #endif 311: 312: /* Used to synchronize down/up state change; protected by gcLock. */ 313: PRCondVar *stateChange; 314: 315: /* Used to serialize cycle checks when setting __proto__ or __parent__. */ 316: PRLock *setSlotLock; 317: PRCondVar *setSlotDone; 318: JSBool setSlotBusy; 319: JSScope *setSlotScope; /* deadlock avoidance, see jslock.c */ 320: 321: /* 322: * State for sharing single-threaded scopes, once a second thread tries to 323: * lock a scope. The scopeSharingDone condvar is protected by rt->gcLock, 324: * to minimize number of locks taken in JS_EndRequest. 325: * 326: * The scopeSharingTodo linked list is likewise "global" per runtime, not 327: * one-list-per-context, to conserve space over all contexts, optimizing 328: * for the likely case that scopes become shared rarely, and among a very 329: * small set of threads (contexts). 330: */ 331: PRCondVar *scopeSharingDone; 332: JSScope *scopeSharingTodo; 333: 334: /* 335: * Magic terminator for the rt->scopeSharingTodo linked list, threaded through 336: * scope->u.link. This hack allows us to test whether a scope is on the list 337: * by asking whether scope->u.link is non-null. We use a large, likely bogus 338: * pointer here to distinguish this value from any valid u.count (small int) 339: * value. 340: */ 341: #define NO_SCOPE_SHARING_TODO ((JSScope *) 0xfeedbeef) 1.1.1.2 ! root 342: ! 343: /* ! 344: * The index for JSThread info, returned by PR_NewThreadPrivateIndex. ! 345: * The value is visible and shared by all threads, but the data is ! 346: * private to each thread. ! 347: */ ! 348: PRUintn threadTPIndex; 1.1 root 349: #endif /* JS_THREADSAFE */ 350: 351: /* 352: * Check property accessibility for objects of arbitrary class. Used at 353: * present to check f.caller accessibility for any function object f. 354: */ 355: JSCheckAccessOp checkObjectAccess; 356: 357: /* Security principals serialization support. */ 358: JSPrincipalsTranscoder principalsTranscoder; 359: 1.1.1.2 ! root 360: /* Optional hook to find principals for an object in this runtime. */ ! 361: JSObjectPrincipalsFinder findObjectPrincipals; ! 362: ! 363: /* ! 364: * Shared scope property tree, and arena-pool for allocating its nodes. ! 365: * The propertyRemovals counter is incremented for every js_ClearScope, ! 366: * and for each js_RemoveScopeProperty that frees a slot in an object. ! 367: * See js_NativeGet and js_NativeSet in jsobj.c. ! 368: */ 1.1 root 369: JSDHashTable propertyTreeHash; 370: JSScopeProperty *propertyFreeList; 371: JSArenaPool propertyArenaPool; 1.1.1.2 ! root 372: int32 propertyRemovals; 1.1 root 373: 374: /* Script filename table. */ 375: struct JSHashTable *scriptFilenameTable; 1.1.1.2 ! root 376: JSCList scriptFilenamePrefixes; 1.1 root 377: #ifdef JS_THREADSAFE 378: PRLock *scriptFilenameTableLock; 379: #endif 380: 381: /* Number localization, used by jsnum.c */ 382: const char *thousandsSeparator; 383: const char *decimalSeparator; 384: const char *numGrouping; 385: 1.1.1.2 ! root 386: /* ! 387: * Weak references to lazily-created, well-known XML singletons. ! 388: * ! 389: * NB: Singleton objects must be carefully disconnected from the rest of ! 390: * the object graph usually associated with a JSContext's global object, ! 391: * including the set of standard class objects. See jsxml.c for details. ! 392: */ ! 393: JSObject *anynameObject; ! 394: JSObject *functionNamespaceObject; ! 395: ! 396: /* ! 397: * A helper list for the GC, so it can mark native iterator states. See ! 398: * js_MarkNativeIteratorStates for details. ! 399: */ ! 400: JSNativeIteratorState *nativeIteratorStates; ! 401: ! 402: #ifndef JS_THREADSAFE ! 403: /* ! 404: * For thread-unsafe embeddings, the GSN cache lives in the runtime and ! 405: * not each context, since we expect it to be filled once when decompiling ! 406: * a longer script, then hit repeatedly as js_GetSrcNote is called during ! 407: * the decompiler activation that filled it. ! 408: */ ! 409: JSGSNCache gsnCache; ! 410: ! 411: #define JS_GSN_CACHE(cx) ((cx)->runtime->gsnCache) ! 412: #endif ! 413: 1.1 root 414: #ifdef DEBUG 415: /* Function invocation metering. */ 416: jsrefcount inlineCalls; 417: jsrefcount nativeCalls; 418: jsrefcount nonInlineCalls; 419: jsrefcount constructs; 420: 421: /* Scope lock and property metering. */ 422: jsrefcount claimAttempts; 423: jsrefcount claimedScopes; 424: jsrefcount deadContexts; 425: jsrefcount deadlocksAvoided; 426: jsrefcount liveScopes; 427: jsrefcount sharedScopes; 428: jsrefcount totalScopes; 429: jsrefcount badUndependStrings; 430: jsrefcount liveScopeProps; 431: jsrefcount totalScopeProps; 432: jsrefcount livePropTreeNodes; 433: jsrefcount duplicatePropTreeNodes; 434: jsrefcount totalPropTreeNodes; 435: jsrefcount propTreeKidsChunks; 436: jsrefcount middleDeleteFixups; 437: 438: /* String instrumentation. */ 439: jsrefcount liveStrings; 440: jsrefcount totalStrings; 441: jsrefcount liveDependentStrings; 442: jsrefcount totalDependentStrings; 443: double lengthSum; 444: double lengthSquaredSum; 445: double strdepLengthSum; 446: double strdepLengthSquaredSum; 447: #endif 448: }; 449: 450: #ifdef DEBUG 451: # define JS_RUNTIME_METER(rt, which) JS_ATOMIC_INCREMENT(&(rt)->which) 452: # define JS_RUNTIME_UNMETER(rt, which) JS_ATOMIC_DECREMENT(&(rt)->which) 453: #else 454: # define JS_RUNTIME_METER(rt, which) /* nothing */ 455: # define JS_RUNTIME_UNMETER(rt, which) /* nothing */ 456: #endif 457: 458: #define JS_KEEP_ATOMS(rt) JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms); 459: #define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms); 460: 461: #ifdef JS_ARGUMENT_FORMATTER_DEFINED 462: /* 463: * Linked list mapping format strings for JS_{Convert,Push}Arguments{,VA} to 464: * formatter functions. Elements are sorted in non-increasing format string 465: * length order. 466: */ 467: struct JSArgumentFormatMap { 468: const char *format; 469: size_t length; 470: JSArgumentFormatter formatter; 471: JSArgumentFormatMap *next; 472: }; 473: #endif 474: 475: struct JSStackHeader { 476: uintN nslots; 477: JSStackHeader *down; 478: }; 479: 480: #define JS_STACK_SEGMENT(sh) ((jsval *)(sh) + 2) 481: 482: /* 483: * Key and entry types for the JSContext.resolvingTable hash table, typedef'd 484: * here because all consumers need to see these declarations (and not just the 485: * typedef names, as would be the case for an opaque pointer-to-typedef'd-type 486: * declaration), along with cx->resolvingTable. 487: */ 488: typedef struct JSResolvingKey { 489: JSObject *obj; 490: jsid id; 491: } JSResolvingKey; 492: 493: typedef struct JSResolvingEntry { 494: JSDHashEntryHdr hdr; 495: JSResolvingKey key; 496: uint32 flags; 497: } JSResolvingEntry; 498: 499: #define JSRESFLAG_LOOKUP 0x1 /* resolving id from lookup */ 500: #define JSRESFLAG_WATCH 0x2 /* resolving id from watch */ 501: 502: typedef struct JSLocalRootChunk JSLocalRootChunk; 503: 1.1.1.2 ! root 504: #define JSLRS_CHUNK_SHIFT 8 1.1 root 505: #define JSLRS_CHUNK_SIZE JS_BIT(JSLRS_CHUNK_SHIFT) 506: #define JSLRS_CHUNK_MASK JS_BITMASK(JSLRS_CHUNK_SHIFT) 507: 508: struct JSLocalRootChunk { 509: jsval roots[JSLRS_CHUNK_SIZE]; 510: JSLocalRootChunk *down; 511: }; 512: 513: typedef struct JSLocalRootStack { 1.1.1.2 ! root 514: uint32 scopeMark; ! 515: uint32 rootCount; 1.1 root 516: JSLocalRootChunk *topChunk; 517: JSLocalRootChunk firstChunk; 518: } JSLocalRootStack; 519: 1.1.1.2 ! root 520: #define JSLRS_NULL_MARK ((uint32) -1) ! 521: ! 522: typedef struct JSTempValueRooter JSTempValueRooter; ! 523: typedef void ! 524: (* JS_DLL_CALLBACK JSTempValueMarker)(JSContext *cx, JSTempValueRooter *tvr); ! 525: ! 526: typedef union JSTempValueUnion { ! 527: jsval value; ! 528: JSObject *object; ! 529: JSString *string; ! 530: void *gcthing; ! 531: JSTempValueMarker marker; ! 532: JSScopeProperty *sprop; ! 533: JSWeakRoots *weakRoots; ! 534: jsval *array; ! 535: } JSTempValueUnion; ! 536: ! 537: /* ! 538: * The following allows to reinterpret JSTempValueUnion.object as jsval using ! 539: * the tagging property of a generic jsval described below. ! 540: */ ! 541: JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(jsval)); ! 542: JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(JSObject *)); ! 543: ! 544: /* ! 545: * Context-linked stack of temporary GC roots. ! 546: * ! 547: * If count is -1, then u.value contains the single value or GC-thing to root. ! 548: * If count is -2, then u.marker holds a mark hook called to mark the values. ! 549: * If count is -3, then u.sprop points to the property tree node to mark. ! 550: * If count is -4, then u.weakRoots points to saved weak roots. ! 551: * If count >= 0, then u.array points to a stack-allocated vector of jsvals. ! 552: * ! 553: * To root a single GC-thing pointer, which need not be tagged and stored as a ! 554: * jsval, use JS_PUSH_TEMP_ROOT_GCTHING. The macro reinterprets an arbitrary ! 555: * GC-thing as jsval. It works because a GC-thing is aligned on a 0 mod 8 ! 556: * boundary, and object has the 0 jsval tag. So any GC-thing may be tagged as ! 557: * if it were an object and untagged, if it's then used only as an opaque ! 558: * pointer until discriminated by other means than tag bits (this is how the ! 559: * GC mark function uses its |thing| parameter -- it consults GC-thing flags ! 560: * stored separately from the thing to decide the type of thing). ! 561: * ! 562: * JS_PUSH_TEMP_ROOT_OBJECT and JS_PUSH_TEMP_ROOT_STRING are type-safe ! 563: * alternatives to JS_PUSH_TEMP_ROOT_GCTHING for JSObject and JSString. They ! 564: * also provide a simple way to get a single pointer to rooted JSObject or ! 565: * JSString via JS_PUSH_TEMP_ROOT_(OBJECT|STRTING)(cx, NULL, &tvr). Then ! 566: * &tvr.u.object or tvr.u.string gives the necessary pointer, which puns ! 567: * tvr.u.value safely because JSObject * and JSString * are GC-things and, as ! 568: * such, their tag bits are all zeroes. ! 569: * ! 570: * If you need to protect a result value that flows out of a C function across ! 571: * several layers of other functions, use the js_LeaveLocalRootScopeWithResult ! 572: * internal API (see further below) instead. ! 573: */ ! 574: struct JSTempValueRooter { ! 575: JSTempValueRooter *down; ! 576: ptrdiff_t count; ! 577: JSTempValueUnion u; ! 578: }; ! 579: ! 580: #define JSTVU_SINGLE (-1) ! 581: #define JSTVU_MARKER (-2) ! 582: #define JSTVU_SPROP (-3) ! 583: #define JSTVU_WEAK_ROOTS (-4) ! 584: ! 585: #define JS_PUSH_TEMP_ROOT_COMMON(cx,tvr) \ ! 586: JS_BEGIN_MACRO \ ! 587: JS_ASSERT((cx)->tempValueRooters != (tvr)); \ ! 588: (tvr)->down = (cx)->tempValueRooters; \ ! 589: (cx)->tempValueRooters = (tvr); \ ! 590: JS_END_MACRO ! 591: ! 592: #define JS_PUSH_SINGLE_TEMP_ROOT(cx,val,tvr) \ ! 593: JS_BEGIN_MACRO \ ! 594: (tvr)->count = JSTVU_SINGLE; \ ! 595: (tvr)->u.value = val; \ ! 596: JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \ ! 597: JS_END_MACRO ! 598: ! 599: #define JS_PUSH_TEMP_ROOT(cx,cnt,arr,tvr) \ ! 600: JS_BEGIN_MACRO \ ! 601: JS_ASSERT((ptrdiff_t)(cnt) >= 0); \ ! 602: (tvr)->count = (ptrdiff_t)(cnt); \ ! 603: (tvr)->u.array = (arr); \ ! 604: JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \ ! 605: JS_END_MACRO ! 606: ! 607: #define JS_PUSH_TEMP_ROOT_MARKER(cx,marker_,tvr) \ ! 608: JS_BEGIN_MACRO \ ! 609: (tvr)->count = JSTVU_MARKER; \ ! 610: (tvr)->u.marker = (marker_); \ ! 611: JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \ ! 612: JS_END_MACRO ! 613: ! 614: #define JS_PUSH_TEMP_ROOT_OBJECT(cx,obj,tvr) \ ! 615: JS_BEGIN_MACRO \ ! 616: (tvr)->count = JSTVU_SINGLE; \ ! 617: (tvr)->u.object = (obj); \ ! 618: JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \ ! 619: JS_END_MACRO ! 620: ! 621: #define JS_PUSH_TEMP_ROOT_STRING(cx,str,tvr) \ ! 622: JS_BEGIN_MACRO \ ! 623: (tvr)->count = JSTVU_SINGLE; \ ! 624: (tvr)->u.string = (str); \ ! 625: JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \ ! 626: JS_END_MACRO ! 627: ! 628: #define JS_PUSH_TEMP_ROOT_GCTHING(cx,thing,tvr) \ ! 629: JS_BEGIN_MACRO \ ! 630: JS_ASSERT(JSVAL_IS_OBJECT((jsval)thing)); \ ! 631: (tvr)->count = JSTVU_SINGLE; \ ! 632: (tvr)->u.gcthing = (thing); \ ! 633: JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \ ! 634: JS_END_MACRO ! 635: ! 636: #define JS_POP_TEMP_ROOT(cx,tvr) \ ! 637: JS_BEGIN_MACRO \ ! 638: JS_ASSERT((cx)->tempValueRooters == (tvr)); \ ! 639: (cx)->tempValueRooters = (tvr)->down; \ ! 640: JS_END_MACRO ! 641: ! 642: #define JS_TEMP_ROOT_EVAL(cx,cnt,val,expr) \ ! 643: JS_BEGIN_MACRO \ ! 644: JSTempValueRooter tvr; \ ! 645: JS_PUSH_TEMP_ROOT(cx, cnt, val, &tvr); \ ! 646: (expr); \ ! 647: JS_POP_TEMP_ROOT(cx, &tvr); \ ! 648: JS_END_MACRO ! 649: ! 650: #define JS_PUSH_TEMP_ROOT_SPROP(cx,sprop_,tvr) \ ! 651: JS_BEGIN_MACRO \ ! 652: (tvr)->count = JSTVU_SPROP; \ ! 653: (tvr)->u.sprop = (sprop_); \ ! 654: JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \ ! 655: JS_END_MACRO ! 656: ! 657: #define JS_PUSH_TEMP_ROOT_WEAK_COPY(cx,weakRoots_,tvr) \ ! 658: JS_BEGIN_MACRO \ ! 659: (tvr)->count = JSTVU_WEAK_ROOTS; \ ! 660: (tvr)->u.weakRoots = (weakRoots_); \ ! 661: JS_PUSH_TEMP_ROOT_COMMON(cx, tvr); \ ! 662: JS_END_MACRO 1.1 root 663: 664: struct JSContext { 1.1.1.2 ! root 665: /* JSRuntime contextList linkage. */ 1.1 root 666: JSCList links; 667: 668: /* Interpreter activation count. */ 669: uintN interpLevel; 670: 671: /* Limit pointer for checking stack consumption during recursion. */ 672: jsuword stackLimit; 673: 674: /* Runtime version control identifier and equality operators. */ 1.1.1.2 ! root 675: uint16 version; 1.1 root 676: jsbytecode jsop_eq; 677: jsbytecode jsop_ne; 678: 679: /* Data shared by threads in an address space. */ 680: JSRuntime *runtime; 681: 682: /* Stack arena pool and frame pointer register. */ 683: JSArenaPool stackPool; 684: JSStackFrame *fp; 685: 686: /* Temporary arena pool used while compiling and decompiling. */ 687: JSArenaPool tempPool; 688: 689: /* Top-level object and pointer to top stack frame's scope chain. */ 690: JSObject *globalObject; 691: 1.1.1.2 ! root 692: /* Storage to root recently allocated GC things and script result. */ ! 693: JSWeakRoots weakRoots; 1.1 root 694: 695: /* Regular expression class statics (XXX not shared globally). */ 696: JSRegExpStatics regExpStatics; 697: 698: /* State for object and array toSource conversion. */ 699: JSSharpObjectMap sharpObjectMap; 700: 701: /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */ 702: JSArgumentFormatMap *argumentFormatMap; 703: 704: /* Last message string and trace file for debugging. */ 705: char *lastMessage; 706: #ifdef DEBUG 707: void *tracefp; 708: #endif 709: 710: /* Per-context optional user callbacks. */ 711: JSBranchCallback branchCallback; 712: JSErrorReporter errorReporter; 713: 714: /* Client opaque pointer */ 715: void *data; 716: 717: /* GC and thread-safe state. */ 718: JSStackFrame *dormantFrameChain; /* dormant stack frame to scan */ 719: #ifdef JS_THREADSAFE 1.1.1.2 ! root 720: JSThread *thread; 1.1 root 721: jsrefcount requestDepth; 722: JSScope *scopeToShare; /* weak reference, see jslock.c */ 723: JSScope *lockedSealedScope; /* weak ref, for low-cost sealed 724: scope locking */ 1.1.1.2 ! root 725: JSCList threadLinks; /* JSThread contextList linkage */ ! 726: ! 727: #define CX_FROM_THREAD_LINKS(tl) \ ! 728: ((JSContext *)((char *)(tl) - offsetof(JSContext, threadLinks))) 1.1 root 729: #endif 730: 731: #if JS_HAS_LVALUE_RETURN 732: /* 733: * Secondary return value from native method called on the left-hand side 734: * of an assignment operator. The native should store the object in which 735: * to set a property in *rval, and return the property's id expressed as a 736: * jsval by calling JS_SetCallReturnValue2(cx, idval). 737: */ 738: jsval rval2; 739: JSPackedBool rval2set; 740: #endif 741: 1.1.1.2 ! root 742: #if JS_HAS_XML_SUPPORT ! 743: /* ! 744: * Bit-set formed from binary exponentials of the XML_* tiny-ids defined ! 745: * for boolean settings in jsxml.c, plus an XSF_CACHE_VALID bit. Together ! 746: * these act as a cache of the boolean XML.ignore* and XML.prettyPrinting ! 747: * property values associated with this context's global object. ! 748: */ ! 749: uint8 xmlSettingFlags; ! 750: #endif ! 751: 1.1 root 752: /* 753: * True if creating an exception object, to prevent runaway recursion. 1.1.1.2 ! root 754: * NB: creatingException packs with rval2set, #if JS_HAS_LVALUE_RETURN; ! 755: * with xmlSettingFlags, #if JS_HAS_XML_SUPPORT; and with throwing below. 1.1 root 756: */ 757: JSPackedBool creatingException; 758: 759: /* 760: * Exception state -- the exception member is a GC root by definition. 761: * NB: throwing packs with creatingException and rval2set, above. 762: */ 763: JSPackedBool throwing; /* is there a pending exception? */ 764: jsval exception; /* most-recently-thrown exception */ 1.1.1.2 ! root 765: /* Flag to indicate that we run inside gcCallback(cx, JSGC_MARK_END). */ ! 766: JSPackedBool insideGCMarkCallback; 1.1 root 767: 768: /* Per-context options. */ 769: uint32 options; /* see jsapi.h for JSOPTION_* */ 770: 771: /* Locale specific callbacks for string conversion. */ 772: JSLocaleCallbacks *localeCallbacks; 773: 774: /* 775: * cx->resolvingTable is non-null and non-empty if we are initializing 776: * standard classes lazily, or if we are otherwise recursing indirectly 777: * from js_LookupProperty through a JSClass.resolve hook. It is used to 778: * limit runaway recursion (see jsapi.c and jsobj.c). 779: */ 780: JSDHashTable *resolvingTable; 781: 782: /* PDL of stack headers describing stack slots not rooted by argv, etc. */ 783: JSStackHeader *stackHeaders; 784: 1.1.1.2 ! root 785: /* Optional stack of heap-allocated scoped local GC roots. */ 1.1 root 786: JSLocalRootStack *localRootStack; 1.1.1.2 ! root 787: ! 788: /* Stack of thread-stack-allocated temporary GC roots. */ ! 789: JSTempValueRooter *tempValueRooters; ! 790: ! 791: #ifdef GC_MARK_DEBUG ! 792: /* Top of the GC mark stack. */ ! 793: void *gcCurrentMarkNode; ! 794: #endif ! 795: }; ! 796: ! 797: #ifdef JS_THREADSAFE ! 798: # define JS_THREAD_ID(cx) ((cx)->thread ? (cx)->thread->id : 0) ! 799: #endif ! 800: ! 801: #ifdef __cplusplus ! 802: /* FIXME(bug 332648): Move this into a public header. */ ! 803: class JSAutoTempValueRooter ! 804: { ! 805: public: ! 806: JSAutoTempValueRooter(JSContext *cx, size_t len, jsval *vec) ! 807: : mContext(cx) { ! 808: JS_PUSH_TEMP_ROOT(mContext, len, vec, &mTvr); ! 809: } ! 810: JSAutoTempValueRooter(JSContext *cx, jsval v) ! 811: : mContext(cx) { ! 812: JS_PUSH_SINGLE_TEMP_ROOT(mContext, v, &mTvr); ! 813: } ! 814: ! 815: ~JSAutoTempValueRooter() { ! 816: JS_POP_TEMP_ROOT(mContext, &mTvr); ! 817: } ! 818: ! 819: private: ! 820: static void *operator new(size_t); ! 821: static void operator delete(void *, size_t); ! 822: ! 823: JSContext *mContext; ! 824: JSTempValueRooter mTvr; 1.1 root 825: }; 1.1.1.2 ! root 826: #endif ! 827: ! 828: /* ! 829: * Slightly more readable macros for testing per-context option settings (also ! 830: * to hide bitset implementation detail). ! 831: * ! 832: * JSOPTION_XML must be handled specially in order to propagate from compile- ! 833: * to run-time (from cx->options to script->version/cx->version). To do that, ! 834: * we copy JSOPTION_XML from cx->options into cx->version as JSVERSION_HAS_XML ! 835: * whenever options are set, and preserve this XML flag across version number ! 836: * changes done via the JS_SetVersion API. ! 837: * ! 838: * But when executing a script or scripted function, the interpreter changes ! 839: * cx->version, including the XML flag, to script->version. Thus JSOPTION_XML ! 840: * is a compile-time option that causes a run-time version change during each ! 841: * activation of the compiled script. That version change has the effect of ! 842: * changing JS_HAS_XML_OPTION, so that any compiling done via eval enables XML ! 843: * support. If an XML-enabled script or function calls a non-XML function, ! 844: * the flag bit will be cleared during the callee's activation. ! 845: * ! 846: * Note that JS_SetVersion API calls never pass JSVERSION_HAS_XML or'd into ! 847: * that API's version parameter. ! 848: * ! 849: * Note also that script->version must contain this XML option flag in order ! 850: * for XDR'ed scripts to serialize and deserialize with that option preserved ! 851: * for detection at run-time. We can't copy other compile-time options into ! 852: * script->version because that would break backward compatibility (certain ! 853: * other options, e.g. JSOPTION_VAROBJFIX, are analogous to JSOPTION_XML). ! 854: */ ! 855: #define JS_HAS_OPTION(cx,option) (((cx)->options & (option)) != 0) ! 856: #define JS_HAS_STRICT_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_STRICT) ! 857: #define JS_HAS_WERROR_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_WERROR) ! 858: #define JS_HAS_COMPILE_N_GO_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_COMPILE_N_GO) ! 859: #define JS_HAS_ATLINE_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_ATLINE) ! 860: ! 861: #define JSVERSION_MASK 0x0FFF /* see JSVersion in jspubtd.h */ ! 862: #define JSVERSION_HAS_XML 0x1000 /* flag induced by XML option */ ! 863: ! 864: #define JSVERSION_NUMBER(cx) ((cx)->version & JSVERSION_MASK) ! 865: #define JS_HAS_XML_OPTION(cx) ((cx)->version & JSVERSION_HAS_XML || \ ! 866: JSVERSION_NUMBER(cx) >= JSVERSION_1_6) ! 867: ! 868: #define JS_HAS_NATIVE_BRANCH_CALLBACK_OPTION(cx) \ ! 869: JS_HAS_OPTION(cx, JSOPTION_NATIVE_BRANCH_CALLBACK) ! 870: ! 871: /* ! 872: * Wrappers for the JSVERSION_IS_* macros from jspubtd.h taking JSContext *cx ! 873: * and masking off the XML flag and any other high order bits. ! 874: */ ! 875: #define JS_VERSION_IS_ECMA(cx) JSVERSION_IS_ECMA(JSVERSION_NUMBER(cx)) ! 876: ! 877: /* ! 878: * Common subroutine of JS_SetVersion and js_SetVersion, to update per-context ! 879: * data that depends on version. ! 880: */ ! 881: extern void ! 882: js_OnVersionChange(JSContext *cx); 1.1 root 883: 884: /* 1.1.1.2 ! root 885: * Unlike the JS_SetVersion API, this function stores JSVERSION_HAS_XML and ! 886: * any future non-version-number flags induced by compiler options. 1.1 root 887: */ 1.1.1.2 ! root 888: extern void ! 889: js_SetVersion(JSContext *cx, JSVersion version); 1.1 root 890: 1.1.1.2 ! root 891: /* ! 892: * Create and destroy functions for JSContext, which is manually allocated ! 893: * and exclusively owned. ! 894: */ 1.1 root 895: extern JSContext * 896: js_NewContext(JSRuntime *rt, size_t stackChunkSize); 897: 898: extern void 1.1.1.2 ! root 899: js_DestroyContext(JSContext *cx, JSDestroyContextMode mode); 1.1 root 900: 901: /* 902: * Return true if cx points to a context in rt->contextList, else return false. 903: * NB: the caller (see jslock.c:ClaimScope) must hold rt->gcLock. 904: */ 905: extern JSBool 906: js_ValidContextPointer(JSRuntime *rt, JSContext *cx); 907: 908: /* 909: * If unlocked, acquire and release rt->gcLock around *iterp update; otherwise 910: * the caller must be holding rt->gcLock. 911: */ 912: extern JSContext * 913: js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp); 914: 915: /* 916: * JSClass.resolve and watchpoint recursion damping machinery. 917: */ 918: extern JSBool 919: js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag, 920: JSResolvingEntry **entryp); 921: 922: extern void 923: js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag, 924: JSResolvingEntry *entry, uint32 generation); 925: 926: /* 927: * Local root set management. 1.1.1.2 ! root 928: * ! 929: * NB: the jsval parameters below may be properly tagged jsvals, or GC-thing ! 930: * pointers cast to (jsval). This relies on JSObject's tag being zero, but ! 931: * on the up side it lets us push int-jsval-encoded scopeMark values on the ! 932: * local root stack. 1.1 root 933: */ 934: extern JSBool 935: js_EnterLocalRootScope(JSContext *cx); 936: 1.1.1.2 ! root 937: #define js_LeaveLocalRootScope(cx) \ ! 938: js_LeaveLocalRootScopeWithResult(cx, JSVAL_NULL) ! 939: 1.1 root 940: extern void 1.1.1.2 ! root 941: js_LeaveLocalRootScopeWithResult(JSContext *cx, jsval rval); 1.1 root 942: 943: extern void 944: js_ForgetLocalRoot(JSContext *cx, jsval v); 945: 946: extern int 947: js_PushLocalRoot(JSContext *cx, JSLocalRootStack *lrs, jsval v); 948: 949: extern void 950: js_MarkLocalRoots(JSContext *cx, JSLocalRootStack *lrs); 951: 952: /* 953: * Report an exception, which is currently realized as a printf-style format 954: * string and its arguments. 955: */ 956: typedef enum JSErrNum { 957: #define MSG_DEF(name, number, count, exception, format) \ 958: name = number, 959: #include "js.msg" 960: #undef MSG_DEF 961: JSErr_Limit 962: } JSErrNum; 963: 964: extern const JSErrorFormatString * 965: js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber); 966: 967: #ifdef va_start 968: extern JSBool 969: js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap); 970: 971: extern JSBool 972: js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback, 973: void *userRef, const uintN errorNumber, 974: JSBool charArgs, va_list ap); 975: 976: extern JSBool 977: js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback, 978: void *userRef, const uintN errorNumber, 979: char **message, JSErrorReport *reportp, 980: JSBool *warningp, JSBool charArgs, va_list ap); 981: #endif 982: 983: extern void 1.1.1.2 ! root 984: js_ReportOutOfMemory(JSContext *cx); 1.1 root 985: 986: /* 987: * Report an exception using a previously composed JSErrorReport. 988: * XXXbe remove from "friend" API 989: */ 990: extern JS_FRIEND_API(void) 991: js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report); 992: 993: extern void 994: js_ReportIsNotDefined(JSContext *cx, const char *name); 995: 996: extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit]; 997: 998: /* 999: * See JS_SetThreadStackLimit in jsapi.c, where we check that the stack grows 1000: * in the expected direction. On Unix-y systems, JS_STACK_GROWTH_DIRECTION is 1001: * computed on the build host by jscpucfg.c and written into jsautocfg.h. The 1002: * macro is hardcoded in jscpucfg.h on Windows and Mac systems (for historical 1003: * reasons pre-dating autoconf usage). 1004: */ 1005: #if JS_STACK_GROWTH_DIRECTION > 0 1006: # define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) < (cx)->stackLimit) 1007: #else 1008: # define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) > (cx)->stackLimit) 1009: #endif 1010: 1011: JS_END_EXTERN_C 1012: 1013: #endif /* jscntxt_h___ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.