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