/[jscoverage]/trunk/js/jsfun.h
ViewVC logotype

Contents of /trunk/js/jsfun.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 460 - (show annotations)
Sat Sep 26 23:15:22 2009 UTC (10 years, 1 month ago) by siliconforks
File MIME type: text/plain
File size: 14742 byte(s)
Upgrade to SpiderMonkey from Firefox 3.5.3.

1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 *
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * The Original Code is Mozilla Communicator client code, released
17 * March 31, 1998.
18 *
19 * The Initial Developer of the Original Code is
20 * Netscape Communications Corporation.
21 * Portions created by the Initial Developer are Copyright (C) 1998
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
39
40 #ifndef jsfun_h___
41 #define jsfun_h___
42 /*
43 * JS function definitions.
44 */
45 #include "jsprvtd.h"
46 #include "jspubtd.h"
47 #include "jsobj.h"
48
49 JS_BEGIN_EXTERN_C
50
51 typedef struct JSLocalNameMap JSLocalNameMap;
52
53 /*
54 * Depending on the number of arguments and variables in the function their
55 * names and attributes are stored either as a single atom or as an array of
56 * tagged atoms (when there are few locals) or as a hash-based map (when there
57 * are many locals). In the first 2 cases the lowest bit of the atom is used
58 * as a tag to distinguish const from var. See jsfun.c for details.
59 */
60 typedef union JSLocalNames {
61 jsuword taggedAtom;
62 jsuword *array;
63 JSLocalNameMap *map;
64 } JSLocalNames;
65
66 /*
67 * The high two bits of JSFunction.flags encode whether the function is native
68 * or interpreted, and if interpreted, what kind of optimized closure form (if
69 * any) it might be.
70 *
71 * 00 not interpreted
72 * 01 interpreted, neither flat nor null closure
73 * 10 interpreted, flat closure
74 * 11 interpreted, null closure
75 *
76 * FUN_FLAT_CLOSURE implies FUN_INTERPRETED and u.i.script->upvarsOffset != 0.
77 * FUN_NULL_CLOSURE implies FUN_INTERPRETED and u.i.script->upvarsOffset == 0.
78 *
79 * FUN_INTERPRETED but not FUN_FLAT_CLOSURE and u.i.script->upvarsOffset != 0
80 * is an Algol-like function expression or nested function, i.e., a function
81 * that never escapes upward or downward (heapward), and is only ever called.
82 *
83 * Finally, FUN_INTERPRETED and u.i.script->upvarsOffset == 0 could be either
84 * a non-closure (a global function definition, or any function that uses no
85 * outer names), or a closure of an escaping function that uses outer names
86 * whose values can't be snapshot (because the outer names could be reassigned
87 * after the closure is formed, or because assignments could not be analyzed
88 * due to with or eval).
89 *
90 * Such a hard-case function must use JSOP_NAME, etc., and reify outer function
91 * activations' call objects, etc. if it's not a global function.
92 *
93 * NB: JSFUN_EXPR_CLOSURE reuses JSFUN_STUB_GSOPS, which is an API request flag
94 * bit only, never stored in fun->flags.
95 *
96 * If we need more bits in the future, all flags for FUN_INTERPRETED functions
97 * can move to u.i.script->flags. For now we use function flag bits to minimize
98 * pointer-chasing.
99 */
100 #define JSFUN_EXPR_CLOSURE 0x1000 /* expression closure: function(x) x*x */
101 #define JSFUN_TRACEABLE 0x2000 /* can trace across calls to this native
102 function; use FUN_TRCINFO if set,
103 FUN_CLASP if unset */
104 #define JSFUN_INTERPRETED 0x4000 /* use u.i if kind >= this value else u.n */
105 #define JSFUN_FLAT_CLOSURE 0x8000 /* flag (aka "display") closure */
106 #define JSFUN_NULL_CLOSURE 0xc000 /* null closure entrains no scope chain */
107 #define JSFUN_KINDMASK 0xc000 /* encode interp vs. native and closure
108 optimization level -- see above */
109
110 #define FUN_OBJECT(fun) (&(fun)->object)
111 #define FUN_KIND(fun) ((fun)->flags & JSFUN_KINDMASK)
112 #define FUN_SET_KIND(fun,k) ((fun)->flags = ((fun)->flags & ~JSFUN_KINDMASK) | (k))
113 #define FUN_INTERPRETED(fun) (FUN_KIND(fun) >= JSFUN_INTERPRETED)
114 #define FUN_FLAT_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_FLAT_CLOSURE)
115 #define FUN_NULL_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_NULL_CLOSURE)
116 #define FUN_SLOW_NATIVE(fun) (!FUN_INTERPRETED(fun) && !((fun)->flags & JSFUN_FAST_NATIVE))
117 #define FUN_SCRIPT(fun) (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NULL)
118 #define FUN_NATIVE(fun) (FUN_SLOW_NATIVE(fun) ? (fun)->u.n.native : NULL)
119 #define FUN_FAST_NATIVE(fun) (((fun)->flags & JSFUN_FAST_NATIVE) \
120 ? (JSFastNative) (fun)->u.n.native \
121 : NULL)
122 #define FUN_MINARGS(fun) (((fun)->flags & JSFUN_FAST_NATIVE) \
123 ? 0 \
124 : (fun)->nargs)
125 #define FUN_CLASP(fun) (JS_ASSERT(!FUN_INTERPRETED(fun)), \
126 fun->u.n.clasp)
127 #define FUN_TRCINFO(fun) (JS_ASSERT(!FUN_INTERPRETED(fun)), \
128 JS_ASSERT((fun)->flags & JSFUN_TRACEABLE), \
129 fun->u.n.trcinfo)
130
131 struct JSFunction {
132 JSObject object; /* GC'ed object header */
133 uint16 nargs; /* maximum number of specified arguments,
134 reflected as f.length/f.arity */
135 uint16 flags; /* flags, see JSFUN_* below and in jsapi.h */
136 union {
137 struct {
138 uint16 extra; /* number of arg slots for local GC roots */
139 uint16 spare; /* reserved for future use */
140 JSNative native; /* native method pointer or null */
141 JSClass *clasp; /* class of objects constructed
142 by this function */
143 JSTraceableNative *trcinfo; /* tracer metadata; can be first
144 element of array */
145 } n;
146 struct {
147 uint16 nvars; /* number of local variables */
148 uint16 nupvars; /* number of upvars (computable from script
149 but here for faster access) */
150 uint16 skipmin; /* net skip amount up (toward zero) from
151 script->staticLevel to nearest upvar,
152 including upvars in nested functions */
153 JSPackedBool wrapper; /* true if this function is a wrapper that
154 rewrites bytecode optimized for a function
155 judged non-escaping by the compiler, which
156 then escaped via the debugger or a rogue
157 indirect eval; if true, then this function
158 object's proto is the wrapped object */
159 JSScript *script; /* interpreted bytecode descriptor or null */
160 JSLocalNames names; /* argument and variable names */
161 } i;
162 } u;
163 JSAtom *atom; /* name for diagnostics and decompiling */
164
165 #ifdef __cplusplus
166 bool optimizedClosure() { return FUN_KIND(this) > JSFUN_INTERPRETED; }
167 bool needsWrapper() { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; }
168
169 uintN countArgsAndVars() const {
170 JS_ASSERT(FUN_INTERPRETED(this));
171 return nargs + u.i.nvars;
172 }
173
174 uintN countLocalNames() const {
175 JS_ASSERT(FUN_INTERPRETED(this));
176 return countArgsAndVars() + u.i.nupvars;
177 }
178
179 bool hasLocalNames() const {
180 JS_ASSERT(FUN_INTERPRETED(this));
181 return countLocalNames() != 0;
182 }
183 #endif
184 };
185
186 /*
187 * Traceable native. This expands to a JSFunctionSpec initializer (like JS_FN
188 * in jsapi.h). fastcall is a JSFastNative; trcinfo is a JSTraceableNative *.
189 */
190 #ifdef JS_TRACER
191 /* MSVC demands the intermediate (void *) cast here. */
192 # define JS_TN(name,fastcall,nargs,flags,trcinfo) \
193 JS_FN(name, JS_DATA_TO_FUNC_PTR(JSNative, trcinfo), nargs, \
194 (flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | JSFUN_TRACEABLE)
195 #else
196 # define JS_TN(name,fastcall,nargs,flags,trcinfo) \
197 JS_FN(name, fastcall, nargs, flags)
198 #endif
199
200 extern JSClass js_ArgumentsClass;
201 extern JS_FRIEND_DATA(JSClass) js_CallClass;
202 extern JSClass js_DeclEnvClass;
203
204 /* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */
205 extern JS_FRIEND_DATA(JSClass) js_FunctionClass;
206
207 #define HAS_FUNCTION_CLASS(obj) (STOBJ_GET_CLASS(obj) == &js_FunctionClass)
208
209 /*
210 * NB: jsapi.h and jsobj.h must be included before any call to this macro.
211 */
212 #define VALUE_IS_FUNCTION(cx, v) \
213 (!JSVAL_IS_PRIMITIVE(v) && HAS_FUNCTION_CLASS(JSVAL_TO_OBJECT(v)))
214
215 /*
216 * Macro to access the private slot of the function object after the slot is
217 * initialized.
218 */
219 #define GET_FUNCTION_PRIVATE(cx, funobj) \
220 (JS_ASSERT(HAS_FUNCTION_CLASS(funobj)), \
221 (JSFunction *) OBJ_GET_PRIVATE(cx, funobj))
222
223 extern JSObject *
224 js_InitFunctionClass(JSContext *cx, JSObject *obj);
225
226 extern JSObject *
227 js_InitArgumentsClass(JSContext *cx, JSObject *obj);
228
229 extern JSFunction *
230 js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
231 uintN flags, JSObject *parent, JSAtom *atom);
232
233 extern void
234 js_TraceFunction(JSTracer *trc, JSFunction *fun);
235
236 extern void
237 js_FinalizeFunction(JSContext *cx, JSFunction *fun);
238
239 extern JSObject *
240 js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent);
241
242 extern JS_REQUIRES_STACK JSObject *
243 js_NewFlatClosure(JSContext *cx, JSFunction *fun);
244
245 extern JS_REQUIRES_STACK JSObject *
246 js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun);
247
248 extern JSFunction *
249 js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
250 uintN nargs, uintN flags);
251
252 /*
253 * Flags for js_ValueToFunction and js_ReportIsNotFunction. We depend on the
254 * fact that JSINVOKE_CONSTRUCT (aka JSFRAME_CONSTRUCTING) is 1, and test that
255 * with #if/#error in jsfun.c.
256 */
257 #define JSV2F_CONSTRUCT JSINVOKE_CONSTRUCT
258 #define JSV2F_ITERATOR JSINVOKE_ITERATOR
259 #define JSV2F_SEARCH_STACK 0x10000
260
261 extern JSFunction *
262 js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags);
263
264 extern JSObject *
265 js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags);
266
267 extern JSObject *
268 js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags);
269
270 extern void
271 js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags);
272
273 extern JSObject *
274 js_GetCallObject(JSContext *cx, JSStackFrame *fp);
275
276 extern JS_FRIEND_API(JSBool)
277 js_PutCallObject(JSContext *cx, JSStackFrame *fp);
278
279 extern JSBool
280 js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
281
282 extern JS_REQUIRES_STACK JSBool
283 js_GetCallVar(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
284
285 /*
286 * Slower version of js_GetCallVar used when call_resolve detects an attempt to
287 * leak an optimized closure via indirect or debugger eval.
288 */
289 extern JS_REQUIRES_STACK JSBool
290 js_GetCallVarChecked(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
291
292 extern JSBool
293 js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp);
294
295 extern JSBool
296 js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, jsval *vp);
297
298 extern JSObject *
299 js_GetArgsObject(JSContext *cx, JSStackFrame *fp);
300
301 extern JS_FRIEND_API(JSBool)
302 js_PutArgsObject(JSContext *cx, JSStackFrame *fp);
303
304 extern JSBool
305 js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp);
306
307 typedef enum JSLocalKind {
308 JSLOCAL_NONE,
309 JSLOCAL_ARG,
310 JSLOCAL_VAR,
311 JSLOCAL_CONST,
312 JSLOCAL_UPVAR
313 } JSLocalKind;
314
315 extern JSBool
316 js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind);
317
318 /*
319 * Look up an argument or variable name returning its kind when found or
320 * JSLOCAL_NONE when no such name exists. When indexp is not null and the name
321 * exists, *indexp will receive the index of the corresponding argument or
322 * variable.
323 */
324 extern JSLocalKind
325 js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp);
326
327 /*
328 * Functions to work with local names as an array of words.
329 *
330 * js_GetLocalNameArray returns the array, or null if we are out of memory.
331 * This function must be called only when fun->hasLocalNames().
332 *
333 * The supplied pool is used to allocate the returned array, so the caller is
334 * obligated to mark and release to free it.
335 *
336 * The elements of the array with index less than fun->nargs correspond to the
337 * names of function formal parameters. An index >= fun->nargs addresses a var
338 * binding. Use JS_LOCAL_NAME_TO_ATOM to convert array's element to an atom
339 * pointer. This pointer can be null when the element is for a formal parameter
340 * corresponding to a destructuring pattern.
341 *
342 * If nameWord does not name a formal parameter, use JS_LOCAL_NAME_IS_CONST to
343 * check if nameWord corresponds to the const declaration.
344 */
345 extern jsuword *
346 js_GetLocalNameArray(JSContext *cx, JSFunction *fun, struct JSArenaPool *pool);
347
348 #define JS_LOCAL_NAME_TO_ATOM(nameWord) \
349 ((JSAtom *) ((nameWord) & ~(jsuword) 1))
350
351 #define JS_LOCAL_NAME_IS_CONST(nameWord) \
352 ((((nameWord) & (jsuword) 1)) != 0)
353
354 extern void
355 js_FreezeLocalNames(JSContext *cx, JSFunction *fun);
356
357 extern JS_REQUIRES_STACK JSBool
358 js_fun_apply(JSContext *cx, uintN argc, jsval *vp);
359
360 extern JS_REQUIRES_STACK JSBool
361 js_fun_call(JSContext *cx, uintN argc, jsval *vp);
362
363
364 JS_END_EXTERN_C
365
366 #endif /* jsfun_h___ */

  ViewVC Help
Powered by ViewVC 1.1.24