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