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

Annotation of /trunk/js/jsfun.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 507 - (hide annotations)
Sun Jan 10 07:23:34 2010 UTC (10 years ago) by siliconforks
File MIME type: text/plain
File size: 17401 byte(s)
Update SpiderMonkey from Firefox 3.6rc1.

1 siliconforks 332 /* -*- 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 siliconforks 460 /*
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 siliconforks 507 #define JSFUN_TRCINFO 0x2000 /* when set, u.n.trcinfo is non-null,
102     JSFunctionSpec::call points to a
103     JSNativeTraceInfo. */
104 siliconforks 460 #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 siliconforks 507 JS_ASSERT((fun)->flags & JSFUN_TRCINFO), \
129 siliconforks 460 fun->u.n.trcinfo)
130    
131 siliconforks 332 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 siliconforks 460 JSClass *clasp; /* class of objects constructed
142     by this function */
143 siliconforks 507 JSNativeTraceInfo *trcinfo;
144 siliconforks 332 } n;
145     struct {
146     uint16 nvars; /* number of local variables */
147     uint16 nupvars; /* number of upvars (computable from script
148     but here for faster access) */
149 siliconforks 460 uint16 skipmin; /* net skip amount up (toward zero) from
150     script->staticLevel to nearest upvar,
151     including upvars in nested functions */
152     JSPackedBool wrapper; /* true if this function is a wrapper that
153     rewrites bytecode optimized for a function
154     judged non-escaping by the compiler, which
155     then escaped via the debugger or a rogue
156     indirect eval; if true, then this function
157     object's proto is the wrapped object */
158 siliconforks 332 JSScript *script; /* interpreted bytecode descriptor or null */
159     JSLocalNames names; /* argument and variable names */
160     } i;
161     } u;
162     JSAtom *atom; /* name for diagnostics and decompiling */
163    
164 siliconforks 507 #ifdef __cplusplus /* Allow inclusion from LiveConnect C files. */
165 siliconforks 460 bool optimizedClosure() { return FUN_KIND(this) > JSFUN_INTERPRETED; }
166     bool needsWrapper() { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; }
167 siliconforks 332
168 siliconforks 460 uintN countArgsAndVars() const {
169     JS_ASSERT(FUN_INTERPRETED(this));
170     return nargs + u.i.nvars;
171     }
172 siliconforks 332
173 siliconforks 460 uintN countLocalNames() const {
174     JS_ASSERT(FUN_INTERPRETED(this));
175     return countArgsAndVars() + u.i.nupvars;
176     }
177 siliconforks 332
178 siliconforks 460 bool hasLocalNames() const {
179     JS_ASSERT(FUN_INTERPRETED(this));
180     return countLocalNames() != 0;
181     }
182 siliconforks 507
183     uint32 countInterpretedReservedSlots() const;
184     #endif /* __cplusplus */
185 siliconforks 460 };
186    
187 siliconforks 399 /*
188 siliconforks 507 * Trace-annotated native. This expands to a JSFunctionSpec initializer (like
189     * JS_FN in jsapi.h). fastcall is a JSFastNative; trcinfo is a
190     * JSNativeTraceInfo*.
191 siliconforks 399 */
192     #ifdef JS_TRACER
193     /* MSVC demands the intermediate (void *) cast here. */
194     # define JS_TN(name,fastcall,nargs,flags,trcinfo) \
195 siliconforks 460 JS_FN(name, JS_DATA_TO_FUNC_PTR(JSNative, trcinfo), nargs, \
196 siliconforks 507 (flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | JSFUN_TRCINFO)
197 siliconforks 399 #else
198     # define JS_TN(name,fastcall,nargs,flags,trcinfo) \
199     JS_FN(name, fastcall, nargs, flags)
200     #endif
201    
202 siliconforks 332 extern JSClass js_ArgumentsClass;
203     extern JS_FRIEND_DATA(JSClass) js_CallClass;
204 siliconforks 460 extern JSClass js_DeclEnvClass;
205 siliconforks 332
206     /* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */
207     extern JS_FRIEND_DATA(JSClass) js_FunctionClass;
208    
209     #define HAS_FUNCTION_CLASS(obj) (STOBJ_GET_CLASS(obj) == &js_FunctionClass)
210    
211     /*
212     * NB: jsapi.h and jsobj.h must be included before any call to this macro.
213     */
214     #define VALUE_IS_FUNCTION(cx, v) \
215     (!JSVAL_IS_PRIMITIVE(v) && HAS_FUNCTION_CLASS(JSVAL_TO_OBJECT(v)))
216    
217     /*
218     * Macro to access the private slot of the function object after the slot is
219     * initialized.
220     */
221     #define GET_FUNCTION_PRIVATE(cx, funobj) \
222     (JS_ASSERT(HAS_FUNCTION_CLASS(funobj)), \
223 siliconforks 507 (JSFunction *) (funobj)->getPrivate())
224 siliconforks 332
225 siliconforks 507 struct js_ArgsPrivateNative;
226    
227     #ifdef __cplusplus /* Allow inclusion from LiveConnect C files. */
228     inline js_ArgsPrivateNative *
229     js_GetArgsPrivateNative(JSObject *argsobj)
230     {
231     JS_ASSERT(STOBJ_GET_CLASS(argsobj) == &js_ArgumentsClass);
232     uintptr_t p = (uintptr_t) argsobj->getPrivate();
233     return (js_ArgsPrivateNative *) (p & 2 ? p & ~2 : NULL);
234     }
235     #endif
236    
237 siliconforks 332 extern JSObject *
238     js_InitFunctionClass(JSContext *cx, JSObject *obj);
239    
240     extern JSObject *
241     js_InitArgumentsClass(JSContext *cx, JSObject *obj);
242    
243     extern JSFunction *
244     js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
245     uintN flags, JSObject *parent, JSAtom *atom);
246    
247     extern void
248     js_TraceFunction(JSTracer *trc, JSFunction *fun);
249    
250     extern void
251     js_FinalizeFunction(JSContext *cx, JSFunction *fun);
252    
253     extern JSObject *
254     js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent);
255    
256 siliconforks 460 extern JS_REQUIRES_STACK JSObject *
257     js_NewFlatClosure(JSContext *cx, JSFunction *fun);
258 siliconforks 332
259 siliconforks 460 extern JS_REQUIRES_STACK JSObject *
260     js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun);
261    
262 siliconforks 332 extern JSFunction *
263     js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
264     uintN nargs, uintN flags);
265    
266     /*
267     * Flags for js_ValueToFunction and js_ReportIsNotFunction. We depend on the
268     * fact that JSINVOKE_CONSTRUCT (aka JSFRAME_CONSTRUCTING) is 1, and test that
269     * with #if/#error in jsfun.c.
270     */
271     #define JSV2F_CONSTRUCT JSINVOKE_CONSTRUCT
272     #define JSV2F_ITERATOR JSINVOKE_ITERATOR
273     #define JSV2F_SEARCH_STACK 0x10000
274    
275     extern JSFunction *
276     js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags);
277    
278     extern JSObject *
279     js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags);
280    
281     extern JSObject *
282     js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags);
283    
284     extern void
285     js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags);
286    
287     extern JSObject *
288 siliconforks 460 js_GetCallObject(JSContext *cx, JSStackFrame *fp);
289 siliconforks 332
290 siliconforks 507 #ifdef OJI
291     JS_EXTERN_API(void)
292     #else
293     extern void
294     #endif
295 siliconforks 332 js_PutCallObject(JSContext *cx, JSStackFrame *fp);
296    
297 siliconforks 507 extern JSFunction *
298     js_GetCallObjectFunction(JSObject *obj);
299    
300 siliconforks 332 extern JSBool
301     js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
302    
303 siliconforks 507 extern JSBool
304     js_GetCallVar(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
305 siliconforks 332
306 siliconforks 507 extern JSBool
307     SetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
308    
309     extern JSBool
310     SetCallVar(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
311    
312 siliconforks 460 /*
313 siliconforks 507 * js_SetCallArg and js_SetCallVar are extern fastcall copies of the setter
314     * functions. These versions are required in order to set call vars from traces.
315     * The normal versions must not be fastcall because they are stored in the
316     * property ops map.
317     */
318     extern JSBool JS_FASTCALL
319     js_SetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval v);
320    
321     extern JSBool JS_FASTCALL
322     js_SetCallVar(JSContext *cx, JSObject *obj, jsid id, jsval v);
323    
324     /*
325 siliconforks 460 * Slower version of js_GetCallVar used when call_resolve detects an attempt to
326     * leak an optimized closure via indirect or debugger eval.
327     */
328 siliconforks 507 extern JSBool
329 siliconforks 460 js_GetCallVarChecked(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
330    
331 siliconforks 332 extern JSBool
332     js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp);
333    
334     extern JSBool
335     js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, jsval *vp);
336    
337 siliconforks 507 #ifdef OJI
338     JS_EXTERN_API(JSObject *)
339     #else
340 siliconforks 332 extern JSObject *
341 siliconforks 507 #endif
342 siliconforks 332 js_GetArgsObject(JSContext *cx, JSStackFrame *fp);
343    
344 siliconforks 507 #ifdef OJI
345     JS_EXTERN_API(void)
346     #else
347     extern void
348     #endif
349 siliconforks 332 js_PutArgsObject(JSContext *cx, JSStackFrame *fp);
350    
351 siliconforks 507 /*
352     * Reserved slot structure for Arguments objects:
353     *
354     * JSSLOT_PRIVATE - the corresponding frame until the frame exits.
355     * JSSLOT_ARGS_LENGTH - the number of actual arguments and a flag indicating
356     * whether arguments.length was overwritten.
357     * JSSLOT_ARGS_CALLEE - the arguments.callee value or JSVAL_HOLE if that was
358     * overwritten.
359     * JSSLOT_ARGS_COPY_START .. - room to store the corresponding arguments after
360     * the frame exists. The slot's value will be JSVAL_HOLE
361     * if arguments[i] was deleted or overwritten.
362     */
363     const uint32 JSSLOT_ARGS_LENGTH = JSSLOT_PRIVATE + 1;
364     const uint32 JSSLOT_ARGS_CALLEE = JSSLOT_PRIVATE + 2;
365     const uint32 JSSLOT_ARGS_COPY_START = JSSLOT_PRIVATE + 3;
366    
367     /* Number of extra fixed slots besides JSSLOT_PRIVATE. */
368     const uint32 ARGS_CLASS_FIXED_RESERVED_SLOTS = JSSLOT_ARGS_COPY_START -
369     JSSLOT_ARGS_LENGTH;
370    
371     /*
372     * JSSLOT_ARGS_LENGTH stores ((argc << 1) | overwritten_flag) as int jsval.
373     * Thus (JS_ARGS_LENGTH_MAX << 1) | 1 must fit JSVAL_INT_MAX. To assert that
374     * we check first that the shift does not overflow uint32.
375     */
376     JS_STATIC_ASSERT(JS_ARGS_LENGTH_MAX <= JS_BIT(30));
377     JS_STATIC_ASSERT(jsval((JS_ARGS_LENGTH_MAX << 1) | 1) <= JSVAL_INT_MAX);
378    
379     JS_INLINE bool
380     js_IsOverriddenArgsLength(JSObject *obj)
381     {
382     JS_ASSERT(STOBJ_GET_CLASS(obj) == &js_ArgumentsClass);
383    
384     jsval v = obj->fslots[JSSLOT_ARGS_LENGTH];
385     return (JSVAL_TO_INT(v) & 1) != 0;
386     }
387    
388 siliconforks 332 extern JSBool
389 siliconforks 460 js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp);
390 siliconforks 332
391     typedef enum JSLocalKind {
392     JSLOCAL_NONE,
393     JSLOCAL_ARG,
394     JSLOCAL_VAR,
395     JSLOCAL_CONST,
396     JSLOCAL_UPVAR
397     } JSLocalKind;
398    
399     extern JSBool
400     js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind);
401    
402     /*
403     * Look up an argument or variable name returning its kind when found or
404     * JSLOCAL_NONE when no such name exists. When indexp is not null and the name
405     * exists, *indexp will receive the index of the corresponding argument or
406     * variable.
407     */
408     extern JSLocalKind
409     js_LookupLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, uintN *indexp);
410    
411     /*
412     * Functions to work with local names as an array of words.
413     *
414     * js_GetLocalNameArray returns the array, or null if we are out of memory.
415 siliconforks 460 * This function must be called only when fun->hasLocalNames().
416 siliconforks 332 *
417     * The supplied pool is used to allocate the returned array, so the caller is
418     * obligated to mark and release to free it.
419     *
420     * The elements of the array with index less than fun->nargs correspond to the
421     * names of function formal parameters. An index >= fun->nargs addresses a var
422     * binding. Use JS_LOCAL_NAME_TO_ATOM to convert array's element to an atom
423     * pointer. This pointer can be null when the element is for a formal parameter
424     * corresponding to a destructuring pattern.
425     *
426     * If nameWord does not name a formal parameter, use JS_LOCAL_NAME_IS_CONST to
427     * check if nameWord corresponds to the const declaration.
428     */
429 siliconforks 507 extern JS_FRIEND_API(jsuword *)
430 siliconforks 332 js_GetLocalNameArray(JSContext *cx, JSFunction *fun, struct JSArenaPool *pool);
431    
432     #define JS_LOCAL_NAME_TO_ATOM(nameWord) \
433     ((JSAtom *) ((nameWord) & ~(jsuword) 1))
434    
435     #define JS_LOCAL_NAME_IS_CONST(nameWord) \
436     ((((nameWord) & (jsuword) 1)) != 0)
437    
438     extern void
439     js_FreezeLocalNames(JSContext *cx, JSFunction *fun);
440    
441 siliconforks 507 extern JSBool
442 siliconforks 399 js_fun_apply(JSContext *cx, uintN argc, jsval *vp);
443    
444 siliconforks 507 extern JSBool
445 siliconforks 399 js_fun_call(JSContext *cx, uintN argc, jsval *vp);
446    
447    
448 siliconforks 332 JS_END_EXTERN_C
449    
450     #endif /* jsfun_h___ */

  ViewVC Help
Powered by ViewVC 1.1.24