/[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 460 by siliconforks, Sat Sep 26 23:15:22 2009 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_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 {  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 */              JSTraceableNative *trcinfo;  /* tracer metadata; can be first
144                  JSTraceableNative   *trcinfo;  /* tracer metadata; can be first                                              element of array */
                                                   element of array */  
             } u;  
145          } n;          } n;
146          struct {          struct {
147              uint16      nvars;    /* number of local variables */              uint16      nvars;    /* number of local variables */
148              uint16      nupvars;  /* number of upvars (computable from script              uint16      nupvars;  /* number of upvars (computable from script
149                                       but here for faster access) */                                       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 */              JSScript    *script;  /* interpreted bytecode descriptor or null */
160              JSLocalNames names;   /* argument and variable names */              JSLocalNames names;   /* argument and variable names */
161          } i;          } i;
162      } u;      } u;
163      JSAtom          *atom;        /* name for diagnostics and decompiling */      JSAtom          *atom;        /* name for diagnostics and decompiling */
 };  
164    
165  #define JSFUN_TRACEABLE      0x2000 /* can trace across calls to this native  #ifdef __cplusplus
166                                         function; use FUN_TRCINFO if set,      bool optimizedClosure() { return FUN_KIND(this) > JSFUN_INTERPRETED; }
167                                         FUN_CLASP if unset */      bool needsWrapper()     { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; }
168  #define JSFUN_EXPR_CLOSURE   0x4000 /* expression closure: function(x)x*x */  
169  #define JSFUN_INTERPRETED    0x8000 /* use u.i if set, u.n if unset */      uintN countArgsAndVars() const {
170            JS_ASSERT(FUN_INTERPRETED(this));
171  #define JSFUN_SCRIPT_OR_FAST_NATIVE (JSFUN_INTERPRETED | JSFUN_FAST_NATIVE)          return nargs + u.i.nvars;
172        }
173  #define FUN_OBJECT(fun)      (&(fun)->object)  
174  #define FUN_INTERPRETED(fun) ((fun)->flags & JSFUN_INTERPRETED)      uintN countLocalNames() const {
175  #define FUN_SLOW_NATIVE(fun) (!((fun)->flags & JSFUN_SCRIPT_OR_FAST_NATIVE))          JS_ASSERT(FUN_INTERPRETED(this));
176  #define FUN_SCRIPT(fun)      (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NULL)          return countArgsAndVars() + u.i.nupvars;
177  #define FUN_NATIVE(fun)      (FUN_SLOW_NATIVE(fun) ? (fun)->u.n.native : NULL)      }
178  #define FUN_FAST_NATIVE(fun) (((fun)->flags & JSFUN_FAST_NATIVE)              \  
179                                ? (JSFastNative) (fun)->u.n.native              \      bool hasLocalNames() const {
180                                : NULL)          JS_ASSERT(FUN_INTERPRETED(this));
181  #define FUN_MINARGS(fun)     (((fun)->flags & JSFUN_FAST_NATIVE)              \          return countLocalNames() != 0;
182                                ? 0                                             \      }
183                                : (fun)->nargs)  #endif
184  #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)  
185    
186  /*  /*
187   * Traceable native.  This expands to a JSFunctionSpec initializer (like JS_FN   * Traceable native.  This expands to a JSFunctionSpec initializer (like JS_FN
# Line 124  Line 190 
190  #ifdef JS_TRACER  #ifdef JS_TRACER
191  /* MSVC demands the intermediate (void *) cast here. */  /* MSVC demands the intermediate (void *) cast here. */
192  # define JS_TN(name,fastcall,nargs,flags,trcinfo)                             \  # define JS_TN(name,fastcall,nargs,flags,trcinfo)                             \
193      {name, (JSNative)(void *)(trcinfo), nargs,                                \      JS_FN(name, JS_DATA_TO_FUNC_PTR(JSNative, trcinfo), nargs,                \
194       (flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | JSFUN_TRACEABLE, 0}            (flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | JSFUN_TRACEABLE)
195  #else  #else
196  # define JS_TN(name,fastcall,nargs,flags,trcinfo)                             \  # define JS_TN(name,fastcall,nargs,flags,trcinfo)                             \
197      JS_FN(name, fastcall, nargs, flags)      JS_FN(name, fastcall, nargs, flags)
# Line 133  Line 199 
199    
200  extern JSClass js_ArgumentsClass;  extern JSClass js_ArgumentsClass;
201  extern JS_FRIEND_DATA(JSClass) js_CallClass;  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. */  /* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */
205  extern JS_FRIEND_DATA(JSClass) js_FunctionClass;  extern JS_FRIEND_DATA(JSClass) js_FunctionClass;
# Line 159  Line 226 
226  extern JSObject *  extern JSObject *
227  js_InitArgumentsClass(JSContext *cx, JSObject *obj);  js_InitArgumentsClass(JSContext *cx, JSObject *obj);
228    
 extern JSObject *  
 js_InitCallClass(JSContext *cx, JSObject *obj);  
   
229  extern JSFunction *  extern JSFunction *
230  js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,  js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
231                 uintN flags, JSObject *parent, JSAtom *atom);                 uintN flags, JSObject *parent, JSAtom *atom);
# Line 175  Line 239 
239  extern JSObject *  extern JSObject *
240  js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent);  js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent);
241    
242  extern JSBool  extern JS_REQUIRES_STACK JSObject *
243  js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *object);  js_NewFlatClosure(JSContext *cx, JSFunction *fun);
244    
245    extern JS_REQUIRES_STACK JSObject *
246    js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun);
247    
248  extern JSFunction *  extern JSFunction *
249  js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,  js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
# Line 204  Line 271 
271  js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags);  js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags);
272    
273  extern JSObject *  extern JSObject *
274  js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent);  js_GetCallObject(JSContext *cx, JSStackFrame *fp);
275    
276  extern JS_FRIEND_API(JSBool)  extern JS_FRIEND_API(JSBool)
277  js_PutCallObject(JSContext *cx, JSStackFrame *fp);  js_PutCallObject(JSContext *cx, JSStackFrame *fp);
# Line 212  Line 279 
279  extern JSBool  extern JSBool
280  js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp);  js_GetCallArg(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
281    
282  extern JSBool  extern JS_REQUIRES_STACK JSBool
283  js_GetCallVar(JSContext *cx, JSObject *obj, jsval id, jsval *vp);  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  extern JSBool
293  js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp);  js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp);
294    
# Line 228  Line 302 
302  js_PutArgsObject(JSContext *cx, JSStackFrame *fp);  js_PutArgsObject(JSContext *cx, JSStackFrame *fp);
303    
304  extern JSBool  extern JSBool
305  js_XDRFunction(JSXDRState *xdr, JSObject **objp);  js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp);
306    
307  typedef enum JSLocalKind {  typedef enum JSLocalKind {
308      JSLOCAL_NONE,      JSLOCAL_NONE,
# Line 238  Line 312 
312      JSLOCAL_UPVAR      JSLOCAL_UPVAR
313  } JSLocalKind;  } JSLocalKind;
314    
 #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)  
   
315  extern JSBool  extern JSBool
316  js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind);  js_AddLocal(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind kind);
317    
# Line 258  Line 328 
328   * Functions to work with local names as an array of words.   * 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.   * js_GetLocalNameArray returns the array, or null if we are out of memory.
331   * This function must not be called when JS_GET_LOCAL_NAME_COUNT(fun) is zero.   * 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   * The supplied pool is used to allocate the returned array, so the caller is
334   * obligated to mark and release to free it.   * obligated to mark and release to free it.
# Line 284  Line 354 
354  extern void  extern void
355  js_FreezeLocalNames(JSContext *cx, JSFunction *fun);  js_FreezeLocalNames(JSContext *cx, JSFunction *fun);
356    
357  extern JSBool  extern JS_REQUIRES_STACK JSBool
358  js_fun_apply(JSContext *cx, uintN argc, jsval *vp);  js_fun_apply(JSContext *cx, uintN argc, jsval *vp);
359    
360  extern JSBool  extern JS_REQUIRES_STACK JSBool
361  js_fun_call(JSContext *cx, uintN argc, jsval *vp);  js_fun_call(JSContext *cx, uintN argc, jsval *vp);
362    
363    

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

  ViewVC Help
Powered by ViewVC 1.1.24