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

Diff of /trunk/js/jsfun.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 399 by siliconforks, Tue Dec 9 03:37:47 2008 UTC revision 507 by siliconforks, Sun Jan 10 07:23:34 2010 UTC
# Line 63  Line 63 
63      JSLocalNameMap  *map;      JSLocalNameMap  *map;
64  } JSLocalNames;  } 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_TRCINFO       0x2000  /* when set, u.n.trcinfo is non-null,
102                                           JSFunctionSpec::call points to a
103                                           JSNativeTraceInfo. */
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_TRCINFO),        \
129                                  fun->u.n.trcinfo)
130    
131  struct JSFunction {  struct JSFunction {
132      JSObject        object;       /* GC'ed object header */      JSObject        object;       /* GC'ed object header */
133      uint16          nargs;        /* maximum number of specified arguments,      uint16          nargs;        /* maximum number of specified arguments,
# Line 73  Line 138 
138              uint16      extra;    /* number of arg slots for local GC roots */              uint16      extra;    /* number of arg slots for local GC roots */
139              uint16      spare;    /* reserved for future use */              uint16      spare;    /* reserved for future use */
140              JSNative    native;   /* native method pointer or null */              JSNative    native;   /* native method pointer or null */
141              union {              JSClass     *clasp;   /* class of objects constructed
142                  JSClass             *clasp;    /* class of objects constructed                                       by this function */
143                                                    by this function */              JSNativeTraceInfo *trcinfo;
                 JSTraceableNative   *trcinfo;  /* tracer metadata; can be first  
                                                   element of array */  
             } u;  
144          } n;          } n;
145          struct {          struct {
146              uint16      nvars;    /* number of local variables */              uint16      nvars;    /* number of local variables */
147              uint16      nupvars;  /* number of upvars (computable from script              uint16      nupvars;  /* number of upvars (computable from script
148                                       but here for faster access) */                                       but here for faster access) */
149                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              JSScript    *script;  /* interpreted bytecode descriptor or null */              JSScript    *script;  /* interpreted bytecode descriptor or null */
159              JSLocalNames names;   /* argument and variable names */              JSLocalNames names;   /* argument and variable names */
160          } i;          } i;
161      } u;      } u;
162      JSAtom          *atom;        /* name for diagnostics and decompiling */      JSAtom          *atom;        /* name for diagnostics and decompiling */
 };  
   
 #define JSFUN_TRACEABLE      0x2000 /* can trace across calls to this native  
                                        function; use FUN_TRCINFO if set,  
                                        FUN_CLASP if unset */  
 #define JSFUN_EXPR_CLOSURE   0x4000 /* expression closure: function(x)x*x */  
 #define JSFUN_INTERPRETED    0x8000 /* use u.i if set, u.n if unset */  
163    
164  #define JSFUN_SCRIPT_OR_FAST_NATIVE (JSFUN_INTERPRETED | JSFUN_FAST_NATIVE)  #ifdef __cplusplus /* Allow inclusion from LiveConnect C files. */
165        bool optimizedClosure() { return FUN_KIND(this) > JSFUN_INTERPRETED; }
166        bool needsWrapper()     { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; }
167    
168        uintN countArgsAndVars() const {
169            JS_ASSERT(FUN_INTERPRETED(this));
170            return nargs + u.i.nvars;
171        }
172    
173        uintN countLocalNames() const {
174            JS_ASSERT(FUN_INTERPRETED(this));
175            return countArgsAndVars() + u.i.nupvars;
176        }
177    
178        bool hasLocalNames() const {
179            JS_ASSERT(FUN_INTERPRETED(this));
180            return countLocalNames() != 0;
181        }
182    
183  #define FUN_OBJECT(fun)      (&(fun)->object)      uint32 countInterpretedReservedSlots() const;
184  #define FUN_INTERPRETED(fun) ((fun)->flags & JSFUN_INTERPRETED)  #endif /* __cplusplus */
185  #define FUN_SLOW_NATIVE(fun) (!((fun)->flags & JSFUN_SCRIPT_OR_FAST_NATIVE))  };
 #define FUN_SCRIPT(fun)      (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NULL)  
 #define FUN_NATIVE(fun)      (FUN_SLOW_NATIVE(fun) ? (fun)->u.n.native : NULL)  
 #define FUN_FAST_NATIVE(fun) (((fun)->flags & JSFUN_FAST_NATIVE)              \  
                               ? (JSFastNative) (fun)->u.n.native              \  
                               : NULL)  
 #define FUN_MINARGS(fun)     (((fun)->flags & JSFUN_FAST_NATIVE)              \  
                               ? 0                                             \  
                               : (fun)->nargs)  
 #define FUN_CLASP(fun)       (JS_ASSERT(!FUN_INTERPRETED(fun)),               \  
                               JS_ASSERT(!((fun)->flags & JSFUN_TRACEABLE)),   \  
                               fun->u.n.u.clasp)  
 #define FUN_TRCINFO(fun)     (JS_ASSERT(!FUN_INTERPRETED(fun)),               \  
                               JS_ASSERT((fun)->flags & JSFUN_TRACEABLE),      \  
                               fun->u.n.u.trcinfo)  
186    
187  /*  /*
188   * Traceable native.  This expands to a JSFunctionSpec initializer (like JS_FN   * Trace-annotated native. This expands to a JSFunctionSpec initializer (like
189   * in jsapi.h).  fastcall is a JSFastNative; trcinfo is a JSTraceableNative *.   * JS_FN in jsapi.h). fastcall is a JSFastNative; trcinfo is a
190     * JSNativeTraceInfo*.
191   */   */
192  #ifdef JS_TRACER  #ifdef JS_TRACER
193  /* MSVC demands the intermediate (void *) cast here. */  /* MSVC demands the intermediate (void *) cast here. */
194  # define JS_TN(name,fastcall,nargs,flags,trcinfo)                             \  # define JS_TN(name,fastcall,nargs,flags,trcinfo)                             \
195      {name, (JSNative)(void *)(trcinfo), nargs,                                \      JS_FN(name, JS_DATA_TO_FUNC_PTR(JSNative, trcinfo), nargs,                \
196       (flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | JSFUN_TRACEABLE, 0}            (flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | JSFUN_TRCINFO)
197  #else  #else
198  # define JS_TN(name,fastcall,nargs,flags,trcinfo)                             \  # define JS_TN(name,fastcall,nargs,flags,trcinfo)                             \
199      JS_FN(name, fastcall, nargs, flags)      JS_FN(name, fastcall, nargs, flags)
# Line 133  Line 201 
201    
202  extern JSClass js_ArgumentsClass;  extern JSClass js_ArgumentsClass;
203  extern JS_FRIEND_DATA(JSClass) js_CallClass;  extern JS_FRIEND_DATA(JSClass) js_CallClass;
204    extern JSClass js_DeclEnvClass;
205    
206  /* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */  /* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */
207  extern JS_FRIEND_DATA(JSClass) js_FunctionClass;  extern JS_FRIEND_DATA(JSClass) js_FunctionClass;
# Line 151  Line 220 
220   */   */
221  #define GET_FUNCTION_PRIVATE(cx, funobj)                                      \  #define GET_FUNCTION_PRIVATE(cx, funobj)                                      \
222      (JS_ASSERT(HAS_FUNCTION_CLASS(funobj)),                                   \      (JS_ASSERT(HAS_FUNCTION_CLASS(funobj)),                                   \
223       (JSFunction *) OBJ_GET_PRIVATE(cx, funobj))       (JSFunction *) (funobj)->getPrivate())
224    
225    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  extern JSObject *  extern JSObject *
238  js_InitFunctionClass(JSContext *cx, JSObject *obj);  js_InitFunctionClass(JSContext *cx, JSObject *obj);
# Line 159  Line 240 
240  extern JSObject *  extern JSObject *
241  js_InitArgumentsClass(JSContext *cx, JSObject *obj);  js_InitArgumentsClass(JSContext *cx, JSObject *obj);
242    
 extern JSObject *  
 js_InitCallClass(JSContext *cx, JSObject *obj);  
   
243  extern JSFunction *  extern JSFunction *
244  js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,  js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
245                 uintN flags, JSObject *parent, JSAtom *atom);                 uintN flags, JSObject *parent, JSAtom *atom);
# Line 175  Line 253 
253  extern JSObject *  extern JSObject *
254  js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent);  js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent);
255    
256  extern JSBool  extern JS_REQUIRES_STACK JSObject *
257  js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *object);  js_NewFlatClosure(JSContext *cx, JSFunction *fun);
258    
259    extern JS_REQUIRES_STACK JSObject *
260    js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun);
261    
262  extern JSFunction *  extern JSFunction *
263  js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,  js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
# Line 204  Line 285 
285  js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags);  js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags);
286    
287  extern JSObject *  extern JSObject *
288  js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent);  js_GetCallObject(JSContext *cx, JSStackFrame *fp);
289    
290  extern JS_FRIEND_API(JSBool)  #ifdef OJI
291    JS_EXTERN_API(void)
292    #else
293    extern void
294    #endif
295  js_PutCallObject(JSContext *cx, JSStackFrame *fp);  js_PutCallObject(JSContext *cx, JSStackFrame *fp);
296    
297    extern JSFunction *
298    js_GetCallObjectFunction(JSObject *obj);
299    
300  extern JSBool  extern JSBool
301  js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp);  js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
302    
303  extern JSBool  extern JSBool
304  js_GetCallVar(JSContext *cx, JSObject *obj, jsval id, jsval *vp);  js_GetCallVar(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
305    
306    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    /*
313     * 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     * 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    extern JSBool
329    js_GetCallVarChecked(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
330    
331  extern JSBool  extern JSBool
332  js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp);  js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp);
# Line 221  Line 334 
334  extern JSBool  extern JSBool
335  js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, jsval *vp);  js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, jsval *vp);
336    
337    #ifdef OJI
338    JS_EXTERN_API(JSObject *)
339    #else
340  extern JSObject *  extern JSObject *
341    #endif
342  js_GetArgsObject(JSContext *cx, JSStackFrame *fp);  js_GetArgsObject(JSContext *cx, JSStackFrame *fp);
343    
344  extern JS_FRIEND_API(JSBool)  #ifdef OJI
345    JS_EXTERN_API(void)
346    #else
347    extern void
348    #endif
349  js_PutArgsObject(JSContext *cx, JSStackFrame *fp);  js_PutArgsObject(JSContext *cx, JSStackFrame *fp);
350    
351    /*
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  extern JSBool  extern JSBool
389  js_XDRFunction(JSXDRState *xdr, JSObject **objp);  js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp);
390    
391  typedef enum JSLocalKind {  typedef enum JSLocalKind {
392      JSLOCAL_NONE,      JSLOCAL_NONE,
# Line 238  Line 396 
396      JSLOCAL_UPVAR      JSLOCAL_UPVAR
397  } JSLocalKind;  } JSLocalKind;
398    
 #define JS_UPVAR_LOCAL_NAME_START(fun)  ((fun)->nargs + (fun)->u.i.nvars)  
 #define JS_GET_LOCAL_NAME_COUNT(fun)    (JS_UPVAR_LOCAL_NAME_START(fun) +     \  
                                          (fun)->u.i.nupvars)  
   
399  extern JSBool  extern JSBool
400  js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind);  js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind);
401    
# Line 258  Line 412 
412   * Functions to work with local names as an array of words.   * 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.   * js_GetLocalNameArray returns the array, or null if we are out of memory.
415   * This function must not be called when JS_GET_LOCAL_NAME_COUNT(fun) is zero.   * This function must be called only when fun->hasLocalNames().
416   *   *
417   * The supplied pool is used to allocate the returned array, so the caller is   * The supplied pool is used to allocate the returned array, so the caller is
418   * obligated to mark and release to free it.   * obligated to mark and release to free it.
# Line 272  Line 426 
426   * If nameWord does not name a formal parameter, use JS_LOCAL_NAME_IS_CONST to   * If nameWord does not name a formal parameter, use JS_LOCAL_NAME_IS_CONST to
427   * check if nameWord corresponds to the const declaration.   * check if nameWord corresponds to the const declaration.
428   */   */
429  extern jsuword *  extern JS_FRIEND_API(jsuword *)
430  js_GetLocalNameArray(JSContext *cx, JSFunction *fun, struct JSArenaPool *pool);  js_GetLocalNameArray(JSContext *cx, JSFunction *fun, struct JSArenaPool *pool);
431    
432  #define JS_LOCAL_NAME_TO_ATOM(nameWord)                                       \  #define JS_LOCAL_NAME_TO_ATOM(nameWord)                                       \

Legend:
Removed from v.399  
changed lines
  Added in v.507

  ViewVC Help
Powered by ViewVC 1.1.24