Back to index

lightning-sunbird  0.9+nobinonly
jscntxt.h
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * vim: set ts=8 sw=4 et tw=78:
00003  *
00004  * ***** BEGIN LICENSE BLOCK *****
00005  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  * The contents of this file are subject to the Mozilla Public License Version
00008  * 1.1 (the "License"); you may not use this file except in compliance with
00009  * the License. You may obtain a copy of the License at
00010  * http://www.mozilla.org/MPL/
00011  *
00012  * Software distributed under the License is distributed on an "AS IS" basis,
00013  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00014  * for the specific language governing rights and limitations under the
00015  * License.
00016  *
00017  * The Original Code is Mozilla Communicator client code, released
00018  * March 31, 1998.
00019  *
00020  * The Initial Developer of the Original Code is
00021  * Netscape Communications Corporation.
00022  * Portions created by the Initial Developer are Copyright (C) 1998
00023  * the Initial Developer. All Rights Reserved.
00024  *
00025  * Contributor(s):
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 #ifndef jscntxt_h___
00042 #define jscntxt_h___
00043 /*
00044  * JS execution context.
00045  */
00046 #include "jsarena.h" /* Added by JSIFY */
00047 #include "jsclist.h"
00048 #include "jslong.h"
00049 #include "jsatom.h"
00050 #include "jsconfig.h"
00051 #include "jsdhash.h"
00052 #include "jsgc.h"
00053 #include "jsinterp.h"
00054 #include "jsobj.h"
00055 #include "jsprvtd.h"
00056 #include "jspubtd.h"
00057 #include "jsregexp.h"
00058 #include "jsutil.h"
00059 
00060 JS_BEGIN_EXTERN_C
00061 
00062 /*
00063  * js_GetSrcNote cache to avoid O(n^2) growth in finding a source note for a
00064  * given pc in a script.
00065  */
00066 typedef struct JSGSNCache {
00067     JSScript        *script;
00068     JSDHashTable    table;
00069 #ifdef JS_GSNMETER
00070     uint32          hits;
00071     uint32          misses;
00072     uint32          fills;
00073     uint32          clears;
00074 # define GSN_CACHE_METER(cache,cnt) (++(cache)->cnt)
00075 #else
00076 # define GSN_CACHE_METER(cache,cnt) /* nothing */
00077 #endif
00078 } JSGSNCache;
00079 
00080 #define GSN_CACHE_CLEAR(cache)                                                \
00081     JS_BEGIN_MACRO                                                            \
00082         (cache)->script = NULL;                                               \
00083         if ((cache)->table.ops) {                                             \
00084             JS_DHashTableFinish(&(cache)->table);                             \
00085             (cache)->table.ops = NULL;                                        \
00086         }                                                                     \
00087         GSN_CACHE_METER(cache, clears);                                       \
00088     JS_END_MACRO
00089 
00090 /* These helper macros take a cx as parameter and operate on its GSN cache. */
00091 #define JS_CLEAR_GSN_CACHE(cx)      GSN_CACHE_CLEAR(&JS_GSN_CACHE(cx))
00092 #define JS_METER_GSN_CACHE(cx,cnt)  GSN_CACHE_METER(&JS_GSN_CACHE(cx), cnt)
00093 
00094 #ifdef JS_THREADSAFE
00095 
00096 /*
00097  * Structure uniquely representing a thread.  It holds thread-private data
00098  * that can be accessed without a global lock.
00099  */
00100 struct JSThread {
00101     /* Linked list of all contexts active on this thread. */
00102     JSCList             contextList;
00103 
00104     /* Opaque thread-id, from NSPR's PR_GetCurrentThread(). */
00105     jsword              id;
00106 
00107     /* Thread-local gc free lists array. */
00108     JSGCThing           *gcFreeLists[GC_NUM_FREELISTS];
00109 
00110     /*
00111      * Thread-local version of JSRuntime.gcMallocBytes to avoid taking
00112      * locks on each JS_malloc.
00113      */
00114     uint32              gcMallocBytes;
00115 
00116 #if JS_HAS_GENERATORS
00117     /* Flag indicating that the current thread is executing close hooks. */
00118     JSBool              gcRunningCloseHooks;
00119 #endif
00120 
00121     /*
00122      * Store the GSN cache in struct JSThread, not struct JSContext, both to
00123      * save space and to simplify cleanup in js_GC.  Any embedding (Firefox
00124      * or another Gecko application) that uses many contexts per thread is
00125      * unlikely to interleave js_GetSrcNote-intensive loops in the decompiler
00126      * among two or more contexts running script in one thread.
00127      */
00128     JSGSNCache          gsnCache;
00129 };
00130 
00131 #define JS_GSN_CACHE(cx) ((cx)->thread->gsnCache)
00132 
00133 extern void JS_DLL_CALLBACK
00134 js_ThreadDestructorCB(void *ptr);
00135 
00136 extern JSBool
00137 js_SetContextThread(JSContext *cx);
00138 
00139 extern void
00140 js_ClearContextThread(JSContext *cx);
00141 
00142 extern JSThread *
00143 js_GetCurrentThread(JSRuntime *rt);
00144 
00145 #endif /* JS_THREADSAFE */
00146 
00147 typedef enum JSDestroyContextMode {
00148     JSDCM_NO_GC,
00149     JSDCM_MAYBE_GC,
00150     JSDCM_FORCE_GC,
00151     JSDCM_NEW_FAILED
00152 } JSDestroyContextMode;
00153 
00154 typedef enum JSRuntimeState {
00155     JSRTS_DOWN,
00156     JSRTS_LAUNCHING,
00157     JSRTS_UP,
00158     JSRTS_LANDING
00159 } JSRuntimeState;
00160 
00161 typedef struct JSPropertyTreeEntry {
00162     JSDHashEntryHdr     hdr;
00163     JSScopeProperty     *child;
00164 } JSPropertyTreeEntry;
00165 
00166 /*
00167  * Forward declaration for opaque JSRuntime.nativeIteratorStates.
00168  */
00169 typedef struct JSNativeIteratorState JSNativeIteratorState;
00170 
00171 struct JSRuntime {
00172     /* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */
00173     JSRuntimeState      state;
00174 
00175     /* Context create/destroy callback. */
00176     JSContextCallback   cxCallback;
00177 
00178     /* Garbage collector state, used by jsgc.c. */
00179     JSGCArenaList       gcArenaList[GC_NUM_FREELISTS];
00180     JSDHashTable        gcRootsHash;
00181     JSDHashTable        *gcLocksHash;
00182     jsrefcount          gcKeepAtoms;
00183     uint32              gcBytes;
00184     uint32              gcLastBytes;
00185     uint32              gcMaxBytes;
00186     uint32              gcMaxMallocBytes;
00187     uint32              gcLevel;
00188     uint32              gcNumber;
00189 
00190     /*
00191      * NB: do not pack another flag here by claiming gcPadding unless the new
00192      * flag is written only by the GC thread.  Atomic updates to packed bytes
00193      * are not guaranteed, so stores issued by one thread may be lost due to
00194      * unsynchronized read-modify-write cycles on other threads.
00195      */
00196     JSPackedBool        gcPoke;
00197     JSPackedBool        gcRunning;
00198     uint16              gcPadding;
00199 #ifdef JS_GC_ZEAL
00200     jsrefcount          gcZeal;
00201 #endif
00202 
00203 
00204     JSGCCallback        gcCallback;
00205     uint32              gcMallocBytes;
00206     JSGCArena           *gcUnscannedArenaStackTop;
00207 #ifdef DEBUG
00208     size_t              gcUnscannedBagSize;
00209 #endif
00210 
00211     /*
00212      * API compatibility requires keeping GCX_PRIVATE bytes separate from the
00213      * original GC types' byte tally.  Otherwise embeddings that configure a
00214      * good limit for pre-GCX_PRIVATE versions of the engine will see memory
00215      * over-pressure too often, possibly leading to failed last-ditch GCs.
00216      *
00217      * The new XML GC-thing types do add to gcBytes, and they're larger than
00218      * the original GC-thing type size (8 bytes on most architectures).  So a
00219      * user who enables E4X may want to increase the maxbytes value passed to
00220      * JS_NewRuntime.  TODO: Note this in the API docs.
00221      */
00222     uint32              gcPrivateBytes;
00223 
00224     /*
00225      * Table for tracking iterators to ensure that we close iterator's state
00226      * before finalizing the iterable object.
00227      */
00228     JSPtrTable          gcIteratorTable;
00229 
00230 #if JS_HAS_GENERATORS
00231     /* Runtime state to support close hooks. */
00232     JSGCCloseState      gcCloseState;
00233 #endif
00234 
00235 #ifdef JS_GCMETER
00236     JSGCStats           gcStats;
00237 #endif
00238 
00239     /* Literal table maintained by jsatom.c functions. */
00240     JSAtomState         atomState;
00241 
00242     /* Random number generator state, used by jsmath.c. */
00243     JSBool              rngInitialized;
00244     int64               rngMultiplier;
00245     int64               rngAddend;
00246     int64               rngMask;
00247     int64               rngSeed;
00248     jsdouble            rngDscale;
00249 
00250     /* Well-known numbers held for use by this runtime's contexts. */
00251     jsdouble            *jsNaN;
00252     jsdouble            *jsNegativeInfinity;
00253     jsdouble            *jsPositiveInfinity;
00254 
00255 #ifdef JS_THREADSAFE
00256     JSLock              *deflatedStringCacheLock;
00257 #endif
00258     JSHashTable         *deflatedStringCache;
00259 #ifdef DEBUG
00260     uint32              deflatedStringCacheBytes;
00261 #endif
00262 
00263     /* Empty string held for use by this runtime's contexts. */
00264     JSString            *emptyString;
00265 
00266     /* List of active contexts sharing this runtime; protected by gcLock. */
00267     JSCList             contextList;
00268 
00269     /* These are used for debugging -- see jsprvtd.h and jsdbgapi.h. */
00270     JSTrapHandler       interruptHandler;
00271     void                *interruptHandlerData;
00272     JSNewScriptHook     newScriptHook;
00273     void                *newScriptHookData;
00274     JSDestroyScriptHook destroyScriptHook;
00275     void                *destroyScriptHookData;
00276     JSTrapHandler       debuggerHandler;
00277     void                *debuggerHandlerData;
00278     JSSourceHandler     sourceHandler;
00279     void                *sourceHandlerData;
00280     JSInterpreterHook   executeHook;
00281     void                *executeHookData;
00282     JSInterpreterHook   callHook;
00283     void                *callHookData;
00284     JSObjectHook        objectHook;
00285     void                *objectHookData;
00286     JSTrapHandler       throwHook;
00287     void                *throwHookData;
00288     JSDebugErrorHook    debugErrorHook;
00289     void                *debugErrorHookData;
00290 
00291     /* More debugging state, see jsdbgapi.c. */
00292     JSCList             trapList;
00293     JSCList             watchPointList;
00294 
00295     /* Weak links to properties, indexed by quickened get/set opcodes. */
00296     /* XXX must come after JSCLists or MSVC alignment bug bites empty lists */
00297     JSPropertyCache     propertyCache;
00298 
00299     /* Client opaque pointer */
00300     void                *data;
00301 
00302 #ifdef JS_THREADSAFE
00303     /* These combine to interlock the GC and new requests. */
00304     PRLock              *gcLock;
00305     PRCondVar           *gcDone;
00306     PRCondVar           *requestDone;
00307     uint32              requestCount;
00308     JSThread            *gcThread;
00309 
00310     /* Lock and owning thread pointer for JS_LOCK_RUNTIME. */
00311     PRLock              *rtLock;
00312 #ifdef DEBUG
00313     jsword              rtLockOwner;
00314 #endif
00315 
00316     /* Used to synchronize down/up state change; protected by gcLock. */
00317     PRCondVar           *stateChange;
00318 
00319     /* Used to serialize cycle checks when setting __proto__ or __parent__. */
00320     PRLock              *setSlotLock;
00321     PRCondVar           *setSlotDone;
00322     JSBool              setSlotBusy;
00323     JSScope             *setSlotScope;  /* deadlock avoidance, see jslock.c */
00324 
00325     /*
00326      * State for sharing single-threaded scopes, once a second thread tries to
00327      * lock a scope.  The scopeSharingDone condvar is protected by rt->gcLock,
00328      * to minimize number of locks taken in JS_EndRequest.
00329      *
00330      * The scopeSharingTodo linked list is likewise "global" per runtime, not
00331      * one-list-per-context, to conserve space over all contexts, optimizing
00332      * for the likely case that scopes become shared rarely, and among a very
00333      * small set of threads (contexts).
00334      */
00335     PRCondVar           *scopeSharingDone;
00336     JSScope             *scopeSharingTodo;
00337 
00338 /*
00339  * Magic terminator for the rt->scopeSharingTodo linked list, threaded through
00340  * scope->u.link.  This hack allows us to test whether a scope is on the list
00341  * by asking whether scope->u.link is non-null.  We use a large, likely bogus
00342  * pointer here to distinguish this value from any valid u.count (small int)
00343  * value.
00344  */
00345 #define NO_SCOPE_SHARING_TODO   ((JSScope *) 0xfeedbeef)
00346 
00347     /*
00348      * The index for JSThread info, returned by PR_NewThreadPrivateIndex.
00349      * The value is visible and shared by all threads, but the data is
00350      * private to each thread.
00351      */
00352     PRUintn             threadTPIndex;
00353 #endif /* JS_THREADSAFE */
00354 
00355     /*
00356      * Check property accessibility for objects of arbitrary class.  Used at
00357      * present to check f.caller accessibility for any function object f.
00358      */
00359     JSCheckAccessOp     checkObjectAccess;
00360 
00361     /* Security principals serialization support. */
00362     JSPrincipalsTranscoder principalsTranscoder;
00363 
00364     /* Optional hook to find principals for an object in this runtime. */
00365     JSObjectPrincipalsFinder findObjectPrincipals;
00366 
00367     /*
00368      * Shared scope property tree, and arena-pool for allocating its nodes.
00369      * The propertyRemovals counter is incremented for every js_ClearScope,
00370      * and for each js_RemoveScopeProperty that frees a slot in an object.
00371      * See js_NativeGet and js_NativeSet in jsobj.c.
00372      */
00373     JSDHashTable        propertyTreeHash;
00374     JSScopeProperty     *propertyFreeList;
00375     JSArenaPool         propertyArenaPool;
00376     int32               propertyRemovals;
00377 
00378     /* Script filename table. */
00379     struct JSHashTable  *scriptFilenameTable;
00380     JSCList             scriptFilenamePrefixes;
00381 #ifdef JS_THREADSAFE
00382     PRLock              *scriptFilenameTableLock;
00383 #endif
00384 
00385     /* Number localization, used by jsnum.c */
00386     const char          *thousandsSeparator;
00387     const char          *decimalSeparator;
00388     const char          *numGrouping;
00389 
00390     /*
00391      * Weak references to lazily-created, well-known XML singletons.
00392      *
00393      * NB: Singleton objects must be carefully disconnected from the rest of
00394      * the object graph usually associated with a JSContext's global object,
00395      * including the set of standard class objects.  See jsxml.c for details.
00396      */
00397     JSObject            *anynameObject;
00398     JSObject            *functionNamespaceObject;
00399 
00400     /*
00401      * A helper list for the GC, so it can mark native iterator states. See
00402      * js_MarkNativeIteratorStates for details.
00403      */
00404     JSNativeIteratorState *nativeIteratorStates;
00405 
00406 #ifndef JS_THREADSAFE
00407     /*
00408      * For thread-unsafe embeddings, the GSN cache lives in the runtime and
00409      * not each context, since we expect it to be filled once when decompiling
00410      * a longer script, then hit repeatedly as js_GetSrcNote is called during
00411      * the decompiler activation that filled it.
00412      */
00413     JSGSNCache          gsnCache;
00414 
00415 #define JS_GSN_CACHE(cx) ((cx)->runtime->gsnCache)
00416 #endif
00417 
00418 #ifdef DEBUG
00419     /* Function invocation metering. */
00420     jsrefcount          inlineCalls;
00421     jsrefcount          nativeCalls;
00422     jsrefcount          nonInlineCalls;
00423     jsrefcount          constructs;
00424 
00425     /* Scope lock and property metering. */
00426     jsrefcount          claimAttempts;
00427     jsrefcount          claimedScopes;
00428     jsrefcount          deadContexts;
00429     jsrefcount          deadlocksAvoided;
00430     jsrefcount          liveScopes;
00431     jsrefcount          sharedScopes;
00432     jsrefcount          totalScopes;
00433     jsrefcount          badUndependStrings;
00434     jsrefcount          liveScopeProps;
00435     jsrefcount          totalScopeProps;
00436     jsrefcount          livePropTreeNodes;
00437     jsrefcount          duplicatePropTreeNodes;
00438     jsrefcount          totalPropTreeNodes;
00439     jsrefcount          propTreeKidsChunks;
00440     jsrefcount          middleDeleteFixups;
00441 
00442     /* String instrumentation. */
00443     jsrefcount          liveStrings;
00444     jsrefcount          totalStrings;
00445     jsrefcount          liveDependentStrings;
00446     jsrefcount          totalDependentStrings;
00447     double              lengthSum;
00448     double              lengthSquaredSum;
00449     double              strdepLengthSum;
00450     double              strdepLengthSquaredSum;
00451 #endif
00452 };
00453 
00454 #ifdef DEBUG
00455 # define JS_RUNTIME_METER(rt, which)    JS_ATOMIC_INCREMENT(&(rt)->which)
00456 # define JS_RUNTIME_UNMETER(rt, which)  JS_ATOMIC_DECREMENT(&(rt)->which)
00457 #else
00458 # define JS_RUNTIME_METER(rt, which)    /* nothing */
00459 # define JS_RUNTIME_UNMETER(rt, which)  /* nothing */
00460 #endif
00461 
00462 #define JS_KEEP_ATOMS(rt)   JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms);
00463 #define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms);
00464 
00465 #ifdef JS_ARGUMENT_FORMATTER_DEFINED
00466 /*
00467  * Linked list mapping format strings for JS_{Convert,Push}Arguments{,VA} to
00468  * formatter functions.  Elements are sorted in non-increasing format string
00469  * length order.
00470  */
00471 struct JSArgumentFormatMap {
00472     const char          *format;
00473     size_t              length;
00474     JSArgumentFormatter formatter;
00475     JSArgumentFormatMap *next;
00476 };
00477 #endif
00478 
00479 struct JSStackHeader {
00480     uintN               nslots;
00481     JSStackHeader       *down;
00482 };
00483 
00484 #define JS_STACK_SEGMENT(sh)    ((jsval *)(sh) + 2)
00485 
00486 /*
00487  * Key and entry types for the JSContext.resolvingTable hash table, typedef'd
00488  * here because all consumers need to see these declarations (and not just the
00489  * typedef names, as would be the case for an opaque pointer-to-typedef'd-type
00490  * declaration), along with cx->resolvingTable.
00491  */
00492 typedef struct JSResolvingKey {
00493     JSObject            *obj;
00494     jsid                id;
00495 } JSResolvingKey;
00496 
00497 typedef struct JSResolvingEntry {
00498     JSDHashEntryHdr     hdr;
00499     JSResolvingKey      key;
00500     uint32              flags;
00501 } JSResolvingEntry;
00502 
00503 #define JSRESFLAG_LOOKUP        0x1     /* resolving id from lookup */
00504 #define JSRESFLAG_WATCH         0x2     /* resolving id from watch */
00505 
00506 typedef struct JSLocalRootChunk JSLocalRootChunk;
00507 
00508 #define JSLRS_CHUNK_SHIFT       8
00509 #define JSLRS_CHUNK_SIZE        JS_BIT(JSLRS_CHUNK_SHIFT)
00510 #define JSLRS_CHUNK_MASK        JS_BITMASK(JSLRS_CHUNK_SHIFT)
00511 
00512 struct JSLocalRootChunk {
00513     jsval               roots[JSLRS_CHUNK_SIZE];
00514     JSLocalRootChunk    *down;
00515 };
00516 
00517 typedef struct JSLocalRootStack {
00518     uint32              scopeMark;
00519     uint32              rootCount;
00520     JSLocalRootChunk    *topChunk;
00521     JSLocalRootChunk    firstChunk;
00522 } JSLocalRootStack;
00523 
00524 #define JSLRS_NULL_MARK ((uint32) -1)
00525 
00526 /*
00527  * Macros to push/pop JSTempValueRooter instances to context-linked stack of
00528  * temporary GC roots. If you need to protect a result value that flows out of
00529  * a C function across several layers of other functions, use the
00530  * js_LeaveLocalRootScopeWithResult internal API (see further below) instead.
00531  *
00532  * The macros also provide a simple way to get a single rooted pointer via
00533  * JS_PUSH_TEMP_ROOT_<KIND>(cx, NULL, &tvr). Then &tvr.u.<kind> gives the
00534  * necessary pointer.
00535  *
00536  * JSTempValueRooter.count defines the type of the rooted value referenced by
00537  * JSTempValueRooter.u union of type JSTempValueUnion. When count is positive
00538  * or zero, u.array points to a vector of jsvals. Otherwise it must be one of
00539  * the following constants:
00540  */
00541 #define JSTVU_SINGLE        (-1)    /* u.value or u.<gcthing> is single jsval
00542                                        or GC-thing */
00543 #define JSTVU_MARKER        (-2)    /* u.marker is a hook to mark a custom
00544                                      * structure */
00545 #define JSTVU_SPROP         (-3)    /* u.sprop roots property tree node */
00546 #define JSTVU_WEAK_ROOTS    (-4)    /* u.weakRoots points to saved weak roots */
00547 #define JSTVU_SCRIPT        (-5)    /* u.script roots JSScript* */
00548 
00549 /*
00550  * Here single JSTVU_SINGLE covers both jsval and pointers to any GC-thing via
00551  * reinterpreting the thing as JSVAL_OBJECT. It works because the GC-thing is
00552  * aligned on a 0 mod 8 boundary, and object has the 0 jsval tag. So any
00553  * GC-thing may be tagged as if it were an object and untagged, if it's then
00554  * used only as an opaque pointer until discriminated by other means than tag
00555  * bits. This is how, for example, js_GetGCThingTraceKind uses its |thing|
00556  * parameter -- it consults GC-thing flags stored separately from the thing to
00557  * decide the kind of thing.
00558  *
00559  * The following checks that this type-punning is possible.
00560  */
00561 JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(jsval));
00562 JS_STATIC_ASSERT(sizeof(JSTempValueUnion) == sizeof(void *));
00563 
00564 #define JS_PUSH_TEMP_ROOT_COMMON(cx,x,tvr,cnt,kind)                           \
00565     JS_BEGIN_MACRO                                                            \
00566         JS_ASSERT((cx)->tempValueRooters != (tvr));                           \
00567         (tvr)->count = (cnt);                                                 \
00568         (tvr)->u.kind = (x);                                                  \
00569         (tvr)->down = (cx)->tempValueRooters;                                 \
00570         (cx)->tempValueRooters = (tvr);                                       \
00571     JS_END_MACRO
00572 
00573 #define JS_POP_TEMP_ROOT(cx,tvr)                                              \
00574     JS_BEGIN_MACRO                                                            \
00575         JS_ASSERT((cx)->tempValueRooters == (tvr));                           \
00576         (cx)->tempValueRooters = (tvr)->down;                                 \
00577     JS_END_MACRO
00578 
00579 #define JS_PUSH_TEMP_ROOT(cx,cnt,arr,tvr)                                     \
00580     JS_BEGIN_MACRO                                                            \
00581         JS_ASSERT((ptrdiff_t)(cnt) >= 0);                                     \
00582         JS_PUSH_TEMP_ROOT_COMMON(cx, arr, tvr, (ptrdiff_t) (cnt), array);     \
00583     JS_END_MACRO
00584 
00585 #define JS_PUSH_SINGLE_TEMP_ROOT(cx,val,tvr)                                  \
00586     JS_PUSH_TEMP_ROOT_COMMON(cx, val, tvr, JSTVU_SINGLE, value)
00587 
00588 #define JS_PUSH_TEMP_ROOT_OBJECT(cx,obj,tvr)                                  \
00589     JS_PUSH_TEMP_ROOT_COMMON(cx, obj, tvr, JSTVU_SINGLE, object)
00590 
00591 #define JS_PUSH_TEMP_ROOT_STRING(cx,str,tvr)                                  \
00592     JS_PUSH_TEMP_ROOT_COMMON(cx, str, tvr, JSTVU_SINGLE, string)
00593 
00594 #define JS_PUSH_TEMP_ROOT_QNAME(cx,qn,tvr)                                    \
00595     JS_PUSH_TEMP_ROOT_COMMON(cx, qn, tvr, JSTVU_SINGLE, qname)
00596 
00597 #define JS_PUSH_TEMP_ROOT_NAMESPACE(cx,ns,tvr)                                \
00598     JS_PUSH_TEMP_ROOT_COMMON(cx, ns, tvr, JSTVU_SINGLE, nspace)
00599 
00600 #define JS_PUSH_TEMP_ROOT_XML(cx,xml_,tvr)                                    \
00601     JS_PUSH_TEMP_ROOT_COMMON(cx, xml_, tvr, JSTVU_SINGLE, xml)
00602 
00603 #define JS_PUSH_TEMP_ROOT_MARKER(cx,marker_,tvr)                              \
00604     JS_PUSH_TEMP_ROOT_COMMON(cx, marker_, tvr, JSTVU_MARKER, marker)
00605 
00606 #define JS_PUSH_TEMP_ROOT_SPROP(cx,sprop_,tvr)                                \
00607     JS_PUSH_TEMP_ROOT_COMMON(cx, sprop_, tvr, JSTVU_SPROP, sprop)
00608 
00609 #define JS_PUSH_TEMP_ROOT_WEAK_COPY(cx,weakRoots_,tvr)                        \
00610     JS_PUSH_TEMP_ROOT_COMMON(cx, weakRoots_, tvr, JSTVU_WEAK_ROOTS, weakRoots)
00611 
00612 #define JS_PUSH_TEMP_ROOT_SCRIPT(cx,script_,tvr)                              \
00613     JS_PUSH_TEMP_ROOT_COMMON(cx, script_, tvr, JSTVU_SCRIPT, script)
00614 
00615 struct JSContext {
00616     /* JSRuntime contextList linkage. */
00617     JSCList             links;
00618 
00619     /* Interpreter activation count. */
00620     uintN               interpLevel;
00621 
00622     /* Limit pointer for checking stack consumption during recursion. */
00623     jsuword             stackLimit;
00624 
00625     /* Runtime version control identifier and equality operators. */
00626     uint16              version;
00627     jsbytecode          jsop_eq;
00628     jsbytecode          jsop_ne;
00629 
00630     /* Data shared by threads in an address space. */
00631     JSRuntime           *runtime;
00632 
00633     /* Stack arena pool and frame pointer register. */
00634     JSArenaPool         stackPool;
00635     JSStackFrame        *fp;
00636 
00637     /* Temporary arena pool used while compiling and decompiling. */
00638     JSArenaPool         tempPool;
00639 
00640     /* Top-level object and pointer to top stack frame's scope chain. */
00641     JSObject            *globalObject;
00642 
00643     /* Storage to root recently allocated GC things and script result. */
00644     JSWeakRoots         weakRoots;
00645 
00646     /* Regular expression class statics (XXX not shared globally). */
00647     JSRegExpStatics     regExpStatics;
00648 
00649     /* State for object and array toSource conversion. */
00650     JSSharpObjectMap    sharpObjectMap;
00651 
00652     /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */
00653     JSArgumentFormatMap *argumentFormatMap;
00654 
00655     /* Last message string and trace file for debugging. */
00656     char                *lastMessage;
00657 #ifdef DEBUG
00658     void                *tracefp;
00659 #endif
00660 
00661     /* Per-context optional user callbacks. */
00662     JSBranchCallback    branchCallback;
00663     JSErrorReporter     errorReporter;
00664 
00665     /* Client opaque pointer */
00666     void                *data;
00667 
00668     /* GC and thread-safe state. */
00669     JSStackFrame        *dormantFrameChain; /* dormant stack frame to scan */
00670 #ifdef JS_THREADSAFE
00671     JSThread            *thread;
00672     jsrefcount          requestDepth;
00673     JSScope             *scopeToShare;      /* weak reference, see jslock.c */
00674     JSScope             *lockedSealedScope; /* weak ref, for low-cost sealed
00675                                                scope locking */
00676     JSCList             threadLinks;        /* JSThread contextList linkage */
00677 
00678 #define CX_FROM_THREAD_LINKS(tl) \
00679     ((JSContext *)((char *)(tl) - offsetof(JSContext, threadLinks)))
00680 #endif
00681 
00682 #if JS_HAS_LVALUE_RETURN
00683     /*
00684      * Secondary return value from native method called on the left-hand side
00685      * of an assignment operator.  The native should store the object in which
00686      * to set a property in *rval, and return the property's id expressed as a
00687      * jsval by calling JS_SetCallReturnValue2(cx, idval).
00688      */
00689     jsval               rval2;
00690     JSPackedBool        rval2set;
00691 #endif
00692 
00693 #if JS_HAS_XML_SUPPORT
00694     /*
00695      * Bit-set formed from binary exponentials of the XML_* tiny-ids defined
00696      * for boolean settings in jsxml.c, plus an XSF_CACHE_VALID bit.  Together
00697      * these act as a cache of the boolean XML.ignore* and XML.prettyPrinting
00698      * property values associated with this context's global object.
00699      */
00700     uint8               xmlSettingFlags;
00701 #endif
00702 
00703     /*
00704      * True if creating an exception object, to prevent runaway recursion.
00705      * NB: creatingException packs with rval2set, #if JS_HAS_LVALUE_RETURN;
00706      * with xmlSettingFlags, #if JS_HAS_XML_SUPPORT; and with throwing below.
00707      */
00708     JSPackedBool        creatingException;
00709 
00710     /*
00711      * Exception state -- the exception member is a GC root by definition.
00712      * NB: throwing packs with creatingException and rval2set, above.
00713      */
00714     JSPackedBool        throwing;           /* is there a pending exception? */
00715     jsval               exception;          /* most-recently-thrown exception */
00716     /* Flag to indicate that we run inside gcCallback(cx, JSGC_MARK_END). */
00717     JSPackedBool        insideGCMarkCallback;
00718 
00719     /* Per-context options. */
00720     uint32              options;            /* see jsapi.h for JSOPTION_* */
00721 
00722     /* Locale specific callbacks for string conversion. */
00723     JSLocaleCallbacks   *localeCallbacks;
00724 
00725     /*
00726      * cx->resolvingTable is non-null and non-empty if we are initializing
00727      * standard classes lazily, or if we are otherwise recursing indirectly
00728      * from js_LookupProperty through a JSClass.resolve hook.  It is used to
00729      * limit runaway recursion (see jsapi.c and jsobj.c).
00730      */
00731     JSDHashTable        *resolvingTable;
00732 
00733     /* PDL of stack headers describing stack slots not rooted by argv, etc. */
00734     JSStackHeader       *stackHeaders;
00735 
00736     /* Optional stack of heap-allocated scoped local GC roots. */
00737     JSLocalRootStack    *localRootStack;
00738 
00739     /* Stack of thread-stack-allocated temporary GC roots. */
00740     JSTempValueRooter   *tempValueRooters;
00741 
00742 #ifdef GC_MARK_DEBUG
00743     /* Top of the GC mark stack. */
00744     void                *gcCurrentMarkNode;
00745 #endif
00746 };
00747 
00748 #ifdef JS_THREADSAFE
00749 # define JS_THREAD_ID(cx)       ((cx)->thread ? (cx)->thread->id : 0)
00750 #endif
00751 
00752 #ifdef __cplusplus
00753 /* FIXME(bug 332648): Move this into a public header. */
00754 class JSAutoTempValueRooter
00755 {
00756   public:
00757     JSAutoTempValueRooter(JSContext *cx, size_t len, jsval *vec)
00758         : mContext(cx) {
00759         JS_PUSH_TEMP_ROOT(mContext, len, vec, &mTvr);
00760     }
00761     JSAutoTempValueRooter(JSContext *cx, jsval v)
00762         : mContext(cx) {
00763         JS_PUSH_SINGLE_TEMP_ROOT(mContext, v, &mTvr);
00764     }
00765 
00766     ~JSAutoTempValueRooter() {
00767         JS_POP_TEMP_ROOT(mContext, &mTvr);
00768     }
00769 
00770   private:
00771     static void *operator new(size_t);
00772     static void operator delete(void *, size_t);
00773 
00774     JSContext *mContext;
00775     JSTempValueRooter mTvr;
00776 };
00777 #endif
00778 
00779 /*
00780  * Slightly more readable macros for testing per-context option settings (also
00781  * to hide bitset implementation detail).
00782  *
00783  * JSOPTION_XML must be handled specially in order to propagate from compile-
00784  * to run-time (from cx->options to script->version/cx->version).  To do that,
00785  * we copy JSOPTION_XML from cx->options into cx->version as JSVERSION_HAS_XML
00786  * whenever options are set, and preserve this XML flag across version number
00787  * changes done via the JS_SetVersion API.
00788  *
00789  * But when executing a script or scripted function, the interpreter changes
00790  * cx->version, including the XML flag, to script->version.  Thus JSOPTION_XML
00791  * is a compile-time option that causes a run-time version change during each
00792  * activation of the compiled script.  That version change has the effect of
00793  * changing JS_HAS_XML_OPTION, so that any compiling done via eval enables XML
00794  * support.  If an XML-enabled script or function calls a non-XML function,
00795  * the flag bit will be cleared during the callee's activation.
00796  *
00797  * Note that JS_SetVersion API calls never pass JSVERSION_HAS_XML or'd into
00798  * that API's version parameter.
00799  *
00800  * Note also that script->version must contain this XML option flag in order
00801  * for XDR'ed scripts to serialize and deserialize with that option preserved
00802  * for detection at run-time.  We can't copy other compile-time options into
00803  * script->version because that would break backward compatibility (certain
00804  * other options, e.g. JSOPTION_VAROBJFIX, are analogous to JSOPTION_XML).
00805  */
00806 #define JS_HAS_OPTION(cx,option)        (((cx)->options & (option)) != 0)
00807 #define JS_HAS_STRICT_OPTION(cx)        JS_HAS_OPTION(cx, JSOPTION_STRICT)
00808 #define JS_HAS_WERROR_OPTION(cx)        JS_HAS_OPTION(cx, JSOPTION_WERROR)
00809 #define JS_HAS_COMPILE_N_GO_OPTION(cx)  JS_HAS_OPTION(cx, JSOPTION_COMPILE_N_GO)
00810 #define JS_HAS_ATLINE_OPTION(cx)        JS_HAS_OPTION(cx, JSOPTION_ATLINE)
00811 
00812 #define JSVERSION_MASK                  0x0FFF  /* see JSVersion in jspubtd.h */
00813 #define JSVERSION_HAS_XML               0x1000  /* flag induced by XML option */
00814 
00815 #define JSVERSION_NUMBER(cx)            ((cx)->version & JSVERSION_MASK)
00816 #define JS_HAS_XML_OPTION(cx)           ((cx)->version & JSVERSION_HAS_XML || \
00817                                          JSVERSION_NUMBER(cx) >= JSVERSION_1_6)
00818 
00819 #define JS_HAS_NATIVE_BRANCH_CALLBACK_OPTION(cx)                              \
00820     JS_HAS_OPTION(cx, JSOPTION_NATIVE_BRANCH_CALLBACK)
00821 
00822 /*
00823  * Wrappers for the JSVERSION_IS_* macros from jspubtd.h taking JSContext *cx
00824  * and masking off the XML flag and any other high order bits.
00825  */
00826 #define JS_VERSION_IS_ECMA(cx)          JSVERSION_IS_ECMA(JSVERSION_NUMBER(cx))
00827 
00828 /*
00829  * Common subroutine of JS_SetVersion and js_SetVersion, to update per-context
00830  * data that depends on version.
00831  */
00832 extern void
00833 js_OnVersionChange(JSContext *cx);
00834 
00835 /*
00836  * Unlike the JS_SetVersion API, this function stores JSVERSION_HAS_XML and
00837  * any future non-version-number flags induced by compiler options.
00838  */
00839 extern void
00840 js_SetVersion(JSContext *cx, JSVersion version);
00841 
00842 /*
00843  * Create and destroy functions for JSContext, which is manually allocated
00844  * and exclusively owned.
00845  */
00846 extern JSContext *
00847 js_NewContext(JSRuntime *rt, size_t stackChunkSize);
00848 
00849 extern void
00850 js_DestroyContext(JSContext *cx, JSDestroyContextMode mode);
00851 
00852 /*
00853  * Return true if cx points to a context in rt->contextList, else return false.
00854  * NB: the caller (see jslock.c:ClaimScope) must hold rt->gcLock.
00855  */
00856 extern JSBool
00857 js_ValidContextPointer(JSRuntime *rt, JSContext *cx);
00858 
00859 /*
00860  * If unlocked, acquire and release rt->gcLock around *iterp update; otherwise
00861  * the caller must be holding rt->gcLock.
00862  */
00863 extern JSContext *
00864 js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp);
00865 
00866 /*
00867  * JSClass.resolve and watchpoint recursion damping machinery.
00868  */
00869 extern JSBool
00870 js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
00871                   JSResolvingEntry **entryp);
00872 
00873 extern void
00874 js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
00875                  JSResolvingEntry *entry, uint32 generation);
00876 
00877 /*
00878  * Local root set management.
00879  *
00880  * NB: the jsval parameters below may be properly tagged jsvals, or GC-thing
00881  * pointers cast to (jsval).  This relies on JSObject's tag being zero, but
00882  * on the up side it lets us push int-jsval-encoded scopeMark values on the
00883  * local root stack.
00884  */
00885 extern JSBool
00886 js_EnterLocalRootScope(JSContext *cx);
00887 
00888 #define js_LeaveLocalRootScope(cx) \
00889     js_LeaveLocalRootScopeWithResult(cx, JSVAL_NULL)
00890 
00891 extern void
00892 js_LeaveLocalRootScopeWithResult(JSContext *cx, jsval rval);
00893 
00894 extern void
00895 js_ForgetLocalRoot(JSContext *cx, jsval v);
00896 
00897 extern int
00898 js_PushLocalRoot(JSContext *cx, JSLocalRootStack *lrs, jsval v);
00899 
00900 extern void
00901 js_MarkLocalRoots(JSContext *cx, JSLocalRootStack *lrs);
00902 
00903 /*
00904  * Report an exception, which is currently realized as a printf-style format
00905  * string and its arguments.
00906  */
00907 typedef enum JSErrNum {
00908 #define MSG_DEF(name, number, count, exception, format) \
00909     name = number,
00910 #include "js.msg"
00911 #undef MSG_DEF
00912     JSErr_Limit
00913 } JSErrNum;
00914 
00915 extern const JSErrorFormatString *
00916 js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
00917 
00918 #ifdef va_start
00919 extern JSBool
00920 js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap);
00921 
00922 extern JSBool
00923 js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
00924                        void *userRef, const uintN errorNumber,
00925                        JSBool charArgs, va_list ap);
00926 
00927 extern JSBool
00928 js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
00929                         void *userRef, const uintN errorNumber,
00930                         char **message, JSErrorReport *reportp,
00931                         JSBool *warningp, JSBool charArgs, va_list ap);
00932 #endif
00933 
00934 extern void
00935 js_ReportOutOfMemory(JSContext *cx);
00936 
00937 /*
00938  * Report an exception using a previously composed JSErrorReport.
00939  * XXXbe remove from "friend" API
00940  */
00941 extern JS_FRIEND_API(void)
00942 js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report);
00943 
00944 extern void
00945 js_ReportIsNotDefined(JSContext *cx, const char *name);
00946 
00947 extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
00948 
00949 /*
00950  * See JS_SetThreadStackLimit in jsapi.c, where we check that the stack grows
00951  * in the expected direction.  On Unix-y systems, JS_STACK_GROWTH_DIRECTION is
00952  * computed on the build host by jscpucfg.c and written into jsautocfg.h.  The
00953  * macro is hardcoded in jscpucfg.h on Windows and Mac systems (for historical
00954  * reasons pre-dating autoconf usage).
00955  */
00956 #if JS_STACK_GROWTH_DIRECTION > 0
00957 # define JS_CHECK_STACK_SIZE(cx, lval)  ((jsuword)&(lval) < (cx)->stackLimit)
00958 #else
00959 # define JS_CHECK_STACK_SIZE(cx, lval)  ((jsuword)&(lval) > (cx)->stackLimit)
00960 #endif
00961 
00962 JS_END_EXTERN_C
00963 
00964 #endif /* jscntxt_h___ */