|
|
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 jsinterp_h___ ! 36: #define jsinterp_h___ ! 37: /* ! 38: * JS interpreter interface. ! 39: */ ! 40: #include "jsprvtd.h" ! 41: #include "jspubtd.h" ! 42: ! 43: JS_BEGIN_EXTERN_C ! 44: ! 45: /* ! 46: * JS stack frame, allocated on the C stack. ! 47: */ ! 48: struct JSStackFrame { ! 49: JSObject *callobj; /* lazily created Call object */ ! 50: JSObject *argsobj; /* lazily created arguments object */ ! 51: JSObject *varobj; /* variables object, where vars go */ ! 52: JSScript *script; /* script being interpreted */ ! 53: JSFunction *fun; /* function being called or null */ ! 54: JSObject *thisp; /* "this" pointer if in method */ ! 55: uintN argc; /* actual argument count */ ! 56: jsval *argv; /* base of argument stack slots */ ! 57: jsval rval; /* function return value */ ! 58: uintN nvars; /* local variable count */ ! 59: jsval *vars; /* base of variable stack slots */ ! 60: JSStackFrame *down; /* previous frame */ ! 61: void *annotation; /* used by Java security */ ! 62: JSObject *scopeChain; /* scope chain */ ! 63: jsbytecode *pc; /* program counter */ ! 64: jsval *sp; /* stack pointer */ ! 65: jsval *spbase; /* operand stack base */ ! 66: uintN sharpDepth; /* array/object initializer depth */ ! 67: JSObject *sharpArray; /* scope for #n= initializer vars */ ! 68: uint32 flags; /* frame flags -- see below */ ! 69: JSStackFrame *dormantNext; /* next dormant frame chain */ ! 70: JSAtomMap *objAtomMap; /* object atom map, non-null only if we ! 71: hit a regexp object literal */ ! 72: }; ! 73: ! 74: typedef struct JSInlineFrame { ! 75: JSStackFrame frame; /* base struct */ ! 76: void *mark; /* mark before inline frame */ ! 77: void *hookData; /* debugger call hook data */ ! 78: JSVersion callerVersion; /* dynamic version of calling script */ ! 79: } JSInlineFrame; ! 80: ! 81: /* JS stack frame flags. */ ! 82: #define JSFRAME_CONSTRUCTING 0x1 /* frame is for a constructor invocation */ ! 83: #define JSFRAME_ASSIGNING 0x2 /* a complex (not simplex JOF_ASSIGNING) op ! 84: is currently assigning to a property */ ! 85: #define JSFRAME_DEBUGGER 0x4 /* frame for JS_EvaluateInStackFrame */ ! 86: #define JSFRAME_EVAL 0x8 /* frame for obj_eval */ ! 87: #define JSFRAME_SPECIAL 0xc /* special evaluation frame flags */ ! 88: #define JSFRAME_OVERRIDE_SHIFT 24 /* override bit-set params; see jsfun.c */ ! 89: #define JSFRAME_OVERRIDE_BITS 8 ! 90: ! 91: /* ! 92: * Property cache for quickened get/set property opcodes. ! 93: */ ! 94: #define PROPERTY_CACHE_LOG2 10 ! 95: #define PROPERTY_CACHE_SIZE JS_BIT(PROPERTY_CACHE_LOG2) ! 96: #define PROPERTY_CACHE_MASK JS_BITMASK(PROPERTY_CACHE_LOG2) ! 97: ! 98: #define PROPERTY_CACHE_HASH(obj, id) \ ! 99: ((((jsuword)(obj) >> JSVAL_TAGBITS) ^ (jsuword)(id)) & PROPERTY_CACHE_MASK) ! 100: ! 101: #ifdef JS_THREADSAFE ! 102: ! 103: #if HAVE_ATOMIC_DWORD_ACCESS ! 104: ! 105: #define PCE_LOAD(cache, pce, entry) JS_ATOMIC_DWORD_LOAD(pce, entry) ! 106: #define PCE_STORE(cache, pce, entry) JS_ATOMIC_DWORD_STORE(pce, entry) ! 107: ! 108: #else /* !HAVE_ATOMIC_DWORD_ACCESS */ ! 109: ! 110: #define JS_PROPERTY_CACHE_METERING 1 ! 111: ! 112: #define PCE_LOAD(cache, pce, entry) \ ! 113: JS_BEGIN_MACRO \ ! 114: uint32 prefills_; \ ! 115: uint32 fills_ = (cache)->fills; \ ! 116: do { \ ! 117: /* Load until cache->fills is stable (see FILL macro below). */ \ ! 118: prefills_ = fills_; \ ! 119: (entry) = *(pce); \ ! 120: } while ((fills_ = (cache)->fills) != prefills_); \ ! 121: JS_END_MACRO ! 122: ! 123: #define PCE_STORE(cache, pce, entry) \ ! 124: JS_BEGIN_MACRO \ ! 125: do { \ ! 126: /* Store until no racing collider stores half or all of pce. */ \ ! 127: *(pce) = (entry); \ ! 128: } while (PCE_OBJECT(*pce) != PCE_OBJECT(entry) || \ ! 129: PCE_PROPERTY(*pce) != PCE_PROPERTY(entry)); \ ! 130: JS_END_MACRO ! 131: ! 132: #endif /* !HAVE_ATOMIC_DWORD_ACCESS */ ! 133: ! 134: #else /* !JS_THREADSAFE */ ! 135: ! 136: #define PCE_LOAD(cache, pce, entry) ((entry) = *(pce)) ! 137: #define PCE_STORE(cache, pce, entry) (*(pce) = (entry)) ! 138: ! 139: #endif /* !JS_THREADSAFE */ ! 140: ! 141: typedef union JSPropertyCacheEntry { ! 142: struct { ! 143: JSObject *object; /* weak link to object */ ! 144: JSScopeProperty *property; /* weak link to property */ ! 145: } s; ! 146: #ifdef HAVE_ATOMIC_DWORD_ACCESS ! 147: prdword align; ! 148: #endif ! 149: } JSPropertyCacheEntry; ! 150: ! 151: /* These may be called in lvalue or rvalue position. */ ! 152: #define PCE_OBJECT(entry) ((entry).s.object) ! 153: #define PCE_PROPERTY(entry) ((entry).s.property) ! 154: ! 155: typedef struct JSPropertyCache { ! 156: JSPropertyCacheEntry table[PROPERTY_CACHE_SIZE]; ! 157: JSBool empty; ! 158: JSBool disabled; ! 159: #ifdef JS_PROPERTY_CACHE_METERING ! 160: uint32 fills; ! 161: uint32 recycles; ! 162: uint32 tests; ! 163: uint32 misses; ! 164: uint32 flushes; ! 165: # define PCMETER(x) x ! 166: #else ! 167: # define PCMETER(x) /* nothing */ ! 168: #endif ! 169: } JSPropertyCache; ! 170: ! 171: #define PROPERTY_CACHE_FILL(cache, obj, id, sprop) \ ! 172: JS_BEGIN_MACRO \ ! 173: JSPropertyCache *cache_ = (cache); \ ! 174: if (!cache_->disabled) { \ ! 175: uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id); \ ! 176: JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_]; \ ! 177: JSPropertyCacheEntry entry_; \ ! 178: JSScopeProperty *pce_sprop_; \ ! 179: PCE_LOAD(cache_, pce_, entry_); \ ! 180: pce_sprop_ = PCE_PROPERTY(entry_); \ ! 181: PCMETER(if (pce_sprop_ && pce_sprop_ != sprop) \ ! 182: cache_->recycles++); \ ! 183: PCE_OBJECT(entry_) = obj; \ ! 184: PCE_PROPERTY(entry_) = sprop; \ ! 185: cache_->empty = JS_FALSE; \ ! 186: PCMETER(cache_->fills++); \ ! 187: PCE_STORE(cache_, pce_, entry_); \ ! 188: } \ ! 189: JS_END_MACRO ! 190: ! 191: #define PROPERTY_CACHE_TEST(cache, obj, id, sprop) \ ! 192: JS_BEGIN_MACRO \ ! 193: uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id); \ ! 194: JSPropertyCache *cache_ = (cache); \ ! 195: JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_]; \ ! 196: JSPropertyCacheEntry entry_; \ ! 197: JSScopeProperty *pce_sprop_; \ ! 198: PCE_LOAD(cache_, pce_, entry_); \ ! 199: pce_sprop_ = PCE_PROPERTY(entry_); \ ! 200: PCMETER(cache_->tests++); \ ! 201: if (pce_sprop_ && \ ! 202: PCE_OBJECT(entry_) == obj && \ ! 203: pce_sprop_->id == id) { \ ! 204: sprop = pce_sprop_; \ ! 205: } else { \ ! 206: PCMETER(cache_->misses++); \ ! 207: sprop = NULL; \ ! 208: } \ ! 209: JS_END_MACRO ! 210: ! 211: extern void ! 212: js_FlushPropertyCache(JSContext *cx); ! 213: ! 214: extern void ! 215: js_DisablePropertyCache(JSContext *cx); ! 216: ! 217: extern void ! 218: js_EnablePropertyCache(JSContext *cx); ! 219: ! 220: extern JS_FRIEND_API(jsval *) ! 221: js_AllocStack(JSContext *cx, uintN nslots, void **markp); ! 222: ! 223: extern JS_FRIEND_API(void) ! 224: js_FreeStack(JSContext *cx, void *mark); ! 225: ! 226: extern JSBool ! 227: js_GetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp); ! 228: ! 229: extern JSBool ! 230: js_SetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp); ! 231: ! 232: extern JSBool ! 233: js_GetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); ! 234: ! 235: extern JSBool ! 236: js_SetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); ! 237: ! 238: /* ! 239: * NB: js_Invoke requires that cx is currently running JS (i.e., that cx->fp ! 240: * is non-null). ! 241: */ ! 242: extern JS_FRIEND_API(JSBool) ! 243: js_Invoke(JSContext *cx, uintN argc, uintN flags); ! 244: ! 245: /* ! 246: * Consolidated js_Invoke flags. NB: JSINVOKE_CONSTRUCT must be the same bit ! 247: * as JSFRAME_CONSTRUCTING (see js_Invoke's initialization of frame.flags -- ! 248: * there's a #error check to ensure this identity in jsinterp.c). ! 249: */ ! 250: #define JSINVOKE_CONSTRUCT 0x1 /* construct object rather than call */ ! 251: #define JSINVOKE_INTERNAL 0x2 /* internal call, not from a script */ ! 252: ! 253: /* ! 254: * "Internal" calls may come from C or C++ code using a JSContext on which no ! 255: * JS is running (!cx->fp), so they may need to push a dummy JSStackFrame. ! 256: */ ! 257: #define js_InternalCall(cx,obj,fval,argc,argv,rval) \ ! 258: js_InternalInvoke(cx, obj, fval, 0, argc, argv, rval) ! 259: ! 260: #define js_InternalConstruct(cx,obj,fval,argc,argv,rval) \ ! 261: js_InternalInvoke(cx, obj, fval, JSINVOKE_CONSTRUCT, argc, argv, rval) ! 262: ! 263: extern JSBool ! 264: js_InternalInvoke(JSContext *cx, JSObject *obj, jsval fval, uintN flags, ! 265: uintN argc, jsval *argv, jsval *rval); ! 266: ! 267: extern JSBool ! 268: js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval, ! 269: JSAccessMode mode, uintN argc, jsval *argv, jsval *rval); ! 270: ! 271: extern JSBool ! 272: js_Execute(JSContext *cx, JSObject *chain, JSScript *script, ! 273: JSStackFrame *down, uintN flags, jsval *result); ! 274: ! 275: extern JSBool ! 276: js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs, ! 277: JSBool *foundp); ! 278: ! 279: extern JSBool ! 280: js_Interpret(JSContext *cx, jsval *result); ! 281: ! 282: JS_END_EXTERN_C ! 283: ! 284: #endif /* jsinterp_h___ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.