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

Diff of /trunk/js/jsinterp.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 82  Line 82 
82      jsval           rval;           /* function return value */      jsval           rval;           /* function return value */
83      JSStackFrame    *down;          /* previous frame */      JSStackFrame    *down;          /* previous frame */
84      void            *annotation;    /* used by Java security */      void            *annotation;    /* used by Java security */
85      JSObject        *scopeChain;    /* scope chain */  
86        /*
87         * We can't determine in advance which local variables can live on
88         * the stack and be freed when their dynamic scope ends, and which
89         * will be closed over and need to live in the heap.  So we place
90         * variables on the stack initially, note when they are closed
91         * over, and copy those that are out to the heap when we leave
92         * their dynamic scope.
93         *
94         * The bytecode compiler produces a tree of block objects
95         * accompanying each JSScript representing those lexical blocks in
96         * the script that have let-bound variables associated with them.
97         * These block objects are never modified, and never become part
98         * of any function's scope chain.  Their parent slots point to the
99         * innermost block that encloses them, or are NULL in the
100         * outermost blocks within a function or in eval or global code.
101         *
102         * When we are in the static scope of such a block, blockChain
103         * points to its compiler-allocated block object; otherwise, it is
104         * NULL.
105         *
106         * scopeChain is the current scope chain, including 'call' and
107         * 'block' objects for those function calls and lexical blocks
108         * whose static scope we are currently executing in, and 'with'
109         * objects for with statements; the chain is typically terminated
110         * by a global object.  However, as an optimization, the young end
111         * of the chain omits block objects we have not yet cloned.  To
112         * create a closure, we clone the missing blocks from blockChain
113         * (which is always current), place them at the head of
114         * scopeChain, and use that for the closure's scope chain.  If we
115         * never close over a lexical block, we never place a mutable
116         * clone of it on scopeChain.
117         *
118         * This lazy cloning is implemented in js_GetScopeChain, which is
119         * also used in some other cases --- entering 'with' blocks, for
120         * example.
121         */
122        JSObject        *scopeChain;
123        JSObject        *blockChain;
124    
125      uintN           sharpDepth;     /* array/object initializer depth */      uintN           sharpDepth;     /* array/object initializer depth */
126      JSObject        *sharpArray;    /* scope for #n= initializer vars */      JSObject        *sharpArray;    /* scope for #n= initializer vars */
127      uint32          flags;          /* frame flags -- see below */      uint32          flags;          /* frame flags -- see below */
128      JSStackFrame    *dormantNext;   /* next dormant frame chain */      JSStackFrame    *dormantNext;   /* next dormant frame chain */
129      JSObject        *xmlNamespace;  /* null or default xml namespace in E4X */      JSObject        *xmlNamespace;  /* null or default xml namespace in E4X */
     JSObject        *blockChain;    /* active compile-time block scopes */  
130      JSStackFrame    *displaySave;   /* previous value of display entry for      JSStackFrame    *displaySave;   /* previous value of display entry for
131                                         script->staticDepth */                                         script->staticLevel */
132  #ifdef DEBUG  
133      jsrefcount      pcDisabledSave; /* for balanced property cache control */  #ifdef __cplusplus /* Aargh, LiveConnect, bug 442399. */
134        inline void assertValidStackDepth(uintN depth);
135  #endif  #endif
136  };  };
137    
 #ifdef DEBUG  
138  #ifdef __cplusplus  #ifdef __cplusplus
139  static JS_INLINE uintN  static JS_INLINE uintN
140  FramePCOffset(JSStackFrame* fp)  FramePCOffset(JSStackFrame* fp)
# Line 104  Line 142 
142      return uintN((fp->imacpc ? fp->imacpc : fp->regs->pc) - fp->script->code);      return uintN((fp->imacpc ? fp->imacpc : fp->regs->pc) - fp->script->code);
143  }  }
144  #endif  #endif
 #endif  
145    
146  static JS_INLINE jsval *  static JS_INLINE jsval *
147  StackBase(JSStackFrame *fp)  StackBase(JSStackFrame *fp)
# Line 112  Line 149 
149      return fp->slots + fp->script->nfixed;      return fp->slots + fp->script->nfixed;
150  }  }
151    
152    #ifdef __cplusplus /* Aargh, LiveConnect, bug 442399. */
153    void
154    JSStackFrame::assertValidStackDepth(uintN depth)
155    {
156        JS_ASSERT(0 <= regs->sp - StackBase(this));
157        JS_ASSERT(depth <= uintptr_t(regs->sp - StackBase(this)));
158    }
159    #endif
160    
161  static JS_INLINE uintN  static JS_INLINE uintN
162  GlobalVarCount(JSStackFrame *fp)  GlobalVarCount(JSStackFrame *fp)
163  {  {
# Line 142  Line 188 
188  #define JSFRAME_ROOTED_ARGV    0x20 /* frame.argv is rooted by the caller */  #define JSFRAME_ROOTED_ARGV    0x20 /* frame.argv is rooted by the caller */
189  #define JSFRAME_YIELDING       0x40 /* js_Interpret dispatched JSOP_YIELD */  #define JSFRAME_YIELDING       0x40 /* js_Interpret dispatched JSOP_YIELD */
190  #define JSFRAME_ITERATOR       0x80 /* trying to get an iterator for for-in */  #define JSFRAME_ITERATOR       0x80 /* trying to get an iterator for for-in */
 #define JSFRAME_POP_BLOCKS    0x100 /* scope chain contains blocks to pop */  
191  #define JSFRAME_GENERATOR     0x200 /* frame belongs to generator-iterator */  #define JSFRAME_GENERATOR     0x200 /* frame belongs to generator-iterator */
 #define JSFRAME_IMACRO_START  0x400 /* imacro starting -- see jstracer.h */  
192    
193  #define JSFRAME_OVERRIDE_SHIFT 24   /* override bit-set params; see jsfun.c */  #define JSFRAME_OVERRIDE_SHIFT 24   /* override bit-set params; see jsfun.c */
194  #define JSFRAME_OVERRIDE_BITS  8  #define JSFRAME_OVERRIDE_BITS  8
# Line 191  Line 235 
235  #define PCVCAP_TAGMASK          JS_BITMASK(PCVCAP_TAGBITS)  #define PCVCAP_TAGMASK          JS_BITMASK(PCVCAP_TAGBITS)
236  #define PCVCAP_TAG(t)           ((t) & PCVCAP_TAGMASK)  #define PCVCAP_TAG(t)           ((t) & PCVCAP_TAGMASK)
237    
238  #define PCVCAP_MAKE(t,s,p)      (((t) << PCVCAP_TAGBITS) |                    \  #define PCVCAP_MAKE(t,s,p)      ((uint32(t) << PCVCAP_TAGBITS) |              \
239                                   ((s) << PCVCAP_PROTOBITS) |                  \                                   ((s) << PCVCAP_PROTOBITS) |                  \
240                                   (p))                                   (p))
241  #define PCVCAP_SHAPE(t)         ((t) >> PCVCAP_TAGBITS)  #define PCVCAP_SHAPE(t)         ((t) >> PCVCAP_TAGBITS)
242    
243  #define SHAPE_OVERFLOW_BIT      JS_BIT(32 - PCVCAP_TAGBITS)  #define SHAPE_OVERFLOW_BIT      JS_BIT(32 - PCVCAP_TAGBITS)
244    
245  /*  #ifndef JS_THREADSAFE
246   * When sprop is not null and the shape generation triggers the GC due to a  # define js_GenerateShape(cx, gcLocked)    js_GenerateShape (cx)
247   * shape overflow, the functions roots sprop.  #endif
248   */  
249  extern uint32  extern uint32
250  js_GenerateShape(JSContext *cx, JSBool gcLocked, JSScopeProperty *sprop);  js_GenerateShape(JSContext *cx, JSBool gcLocked);
251    
252  struct JSPropCacheEntry {  struct JSPropCacheEntry {
253      jsbytecode          *kpc;           /* pc if vcap tag is <= 1, else atom */      jsbytecode          *kpc;           /* pc if vcap tag is <= 1, else atom */
# Line 212  Line 256 
256      jsuword             vword;          /* value word, see PCVAL_* below */      jsuword             vword;          /* value word, see PCVAL_* below */
257  };  };
258    
259    /*
260     * Special value for functions returning JSPropCacheEntry * to distinguish
261     * between failure and no no-cache-fill cases.
262     */
263    #define JS_NO_PROP_CACHE_FILL ((JSPropCacheEntry *) NULL + 1)
264    
265  #if defined DEBUG_brendan || defined DEBUG_brendaneich  #if defined DEBUG_brendan || defined DEBUG_brendaneich
266  #define JS_PROPERTY_CACHE_METERING 1  #define JS_PROPERTY_CACHE_METERING 1
267  #endif  #endif
# Line 219  Line 269 
269  typedef struct JSPropertyCache {  typedef struct JSPropertyCache {
270      JSPropCacheEntry    table[PROPERTY_CACHE_SIZE];      JSPropCacheEntry    table[PROPERTY_CACHE_SIZE];
271      JSBool              empty;      JSBool              empty;
     jsrefcount          disabled;       /* signed for anti-underflow asserts */  
272  #ifdef JS_PROPERTY_CACHE_METERING  #ifdef JS_PROPERTY_CACHE_METERING
273        JSPropCacheEntry    *pctestentry;   /* entry of the last PC-based test */
274      uint32              fills;          /* number of cache entry fills */      uint32              fills;          /* number of cache entry fills */
275      uint32              nofills;        /* couldn't fill (e.g. default get) */      uint32              nofills;        /* couldn't fill (e.g. default get) */
276      uint32              rofills;        /* set on read-only prop can't fill */      uint32              rofills;        /* set on read-only prop can't fill */
# Line 294  Line 344 
344   * Fill property cache entry for key cx->fp->pc, optimized value word computed   * Fill property cache entry for key cx->fp->pc, optimized value word computed
345   * from obj and sprop, and entry capability forged from 24-bit OBJ_SHAPE(obj),   * from obj and sprop, and entry capability forged from 24-bit OBJ_SHAPE(obj),
346   * 4-bit scopeIndex, and 4-bit protoIndex.   * 4-bit scopeIndex, and 4-bit protoIndex.
347     *
348     * Return the filled cache entry or JS_NO_PROP_CACHE_FILL if caching was not
349     * possible.
350   */   */
351  extern void  extern JS_REQUIRES_STACK JSPropCacheEntry *
352  js_FillPropertyCache(JSContext *cx, JSObject *obj, jsuword kshape,  js_FillPropertyCache(JSContext *cx, JSObject *obj,
353                       uintN scopeIndex, uintN protoIndex,                       uintN scopeIndex, uintN protoIndex, JSObject *pobj,
354                       JSObject *pobj, JSScopeProperty *sprop,                       JSScopeProperty *sprop, JSBool adding);
                      JSPropCacheEntry **entryp);  
355    
356  /*  /*
357   * Property cache lookup macros. PROPERTY_CACHE_TEST is designed to inline the   * Property cache lookup macros. PROPERTY_CACHE_TEST is designed to inline the
# Line 322  Line 374 
374          JSPropertyCache *cache_ = &JS_PROPERTY_CACHE(cx);                     \          JSPropertyCache *cache_ = &JS_PROPERTY_CACHE(cx);                     \
375          uint32 kshape_ = (JS_ASSERT(OBJ_IS_NATIVE(obj)), OBJ_SHAPE(obj));     \          uint32 kshape_ = (JS_ASSERT(OBJ_IS_NATIVE(obj)), OBJ_SHAPE(obj));     \
376          entry = &cache_->table[PROPERTY_CACHE_HASH_PC(pc, kshape_)];          \          entry = &cache_->table[PROPERTY_CACHE_HASH_PC(pc, kshape_)];          \
377            PCMETER(cache_->pctestentry = entry);                                 \
378          PCMETER(cache_->tests++);                                             \          PCMETER(cache_->tests++);                                             \
379          JS_ASSERT(&obj != &pobj);                                             \          JS_ASSERT(&obj != &pobj);                                             \
380          if (entry->kpc == pc && entry->kshape == kshape_) {                   \          if (entry->kpc == pc && entry->kshape == kshape_) {                   \
# Line 350  Line 403 
403              PCMETER(cache_->misses++);                                        \              PCMETER(cache_->misses++);                                        \
404      } while (0)      } while (0)
405    
406  extern JSAtom *  extern JS_REQUIRES_STACK JSAtom *
407  js_FullTestPropertyCache(JSContext *cx, jsbytecode *pc,  js_FullTestPropertyCache(JSContext *cx, jsbytecode *pc,
408                           JSObject **objp, JSObject **pobjp,                           JSObject **objp, JSObject **pobjp,
409                           JSPropCacheEntry **entryp);                           JSPropCacheEntry **entryp);
410    
411  extern void  /* The property cache does not need a destructor. */
412  js_FlushPropertyCache(JSContext *cx);  #define js_FinishPropertyCache(cache) ((void) 0)
413    
414  extern void  extern void
415  js_FlushPropertyCacheForScript(JSContext *cx, JSScript *script);  js_PurgePropertyCache(JSContext *cx, JSPropertyCache *cache);
416    
417  extern void  extern void
418  js_DisablePropertyCache(JSContext *cx);  js_PurgePropertyCacheForScript(JSContext *cx, JSScript *script);
   
 extern void  
 js_EnablePropertyCache(JSContext *cx);  
419    
420  /*  /*
421   * Interpreter stack arena-pool alloc and free functions.   * Interpreter stack arena-pool alloc and free functions.
422   */   */
423  extern JS_FRIEND_API(jsval *)  extern JS_REQUIRES_STACK JS_FRIEND_API(jsval *)
424  js_AllocStack(JSContext *cx, uintN nslots, void **markp);  js_AllocStack(JSContext *cx, uintN nslots, void **markp);
425    
426  extern JS_FRIEND_API(void)  extern JS_REQUIRES_STACK JS_FRIEND_API(void)
427  js_FreeStack(JSContext *cx, void *mark);  js_FreeStack(JSContext *cx, void *mark);
428    
429  /*  /*
# Line 415  Line 465 
465       JSFUN_THISP_TEST(JSFUN_THISP_FLAGS((fun)->flags),                        \       JSFUN_THISP_TEST(JSFUN_THISP_FLAGS((fun)->flags),                        \
466                        js_PrimitiveTestFlags[JSVAL_TAG(thisv) - 1]))                        js_PrimitiveTestFlags[JSVAL_TAG(thisv) - 1]))
467    
468    #ifdef __cplusplus /* Aargh, libgjs, bug 492720. */
469    static JS_INLINE JSObject *
470    js_ComputeThisForFrame(JSContext *cx, JSStackFrame *fp)
471    {
472        JSObject* obj;
473        if (fp->flags & JSFRAME_COMPUTED_THIS)
474            return fp->thisp;
475        obj = js_ComputeThis(cx, JS_TRUE, fp->argv);
476        if (!obj)
477            return NULL;
478        fp->thisp = obj;
479        fp->flags |= JSFRAME_COMPUTED_THIS;
480        return obj;
481    }
482    #endif
483    
484  /*  /*
485   * NB: js_Invoke requires that cx is currently running JS (i.e., that cx->fp   * NB: js_Invoke requires that cx is currently running JS (i.e., that cx->fp
486   * is non-null), and that vp points to the callee, |this| parameter, and   * is non-null), and that vp points to the callee, |this| parameter, and
# Line 424  Line 490 
490   * so the caller should not use that space for values that must be preserved   * so the caller should not use that space for values that must be preserved
491   * across the call.   * across the call.
492   */   */
493  extern JS_FRIEND_API(JSBool)  extern JS_REQUIRES_STACK JS_FRIEND_API(JSBool)
494  js_Invoke(JSContext *cx, uintN argc, jsval *vp, uintN flags);  js_Invoke(JSContext *cx, uintN argc, jsval *vp, uintN flags);
495    
496  /*  /*
# Line 466  Line 532 
532  js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval,  js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval,
533                      JSAccessMode mode, uintN argc, jsval *argv, jsval *rval);                      JSAccessMode mode, uintN argc, jsval *argv, jsval *rval);
534    
535  extern JSBool  extern JS_FORCES_STACK JSBool
536  js_Execute(JSContext *cx, JSObject *chain, JSScript *script,  js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
537             JSStackFrame *down, uintN flags, jsval *result);             JSStackFrame *down, uintN flags, jsval *result);
538    
539  extern JSBool  extern JS_REQUIRES_STACK JSBool
540  js_InvokeConstructor(JSContext *cx, uintN argc, JSBool clampReturn, jsval *vp);  js_InvokeConstructor(JSContext *cx, uintN argc, JSBool clampReturn, jsval *vp);
541    
542  extern JSBool  extern JS_REQUIRES_STACK JSBool
543  js_Interpret(JSContext *cx);  js_Interpret(JSContext *cx);
544    
545  #define JSPROP_INITIALIZER 0x100   /* NB: Not a valid property attribute. */  #define JSPROP_INITIALIZER 0x100   /* NB: Not a valid property attribute. */
# Line 485  Line 551 
551  extern JSBool  extern JSBool
552  js_StrictlyEqual(JSContext *cx, jsval lval, jsval rval);  js_StrictlyEqual(JSContext *cx, jsval lval, jsval rval);
553    
554    extern JSBool
555    js_InternNonIntElementId(JSContext *cx, JSObject *obj, jsval idval, jsid *idp);
556    
557    /* Work around liveconnect building this file as C on 1.9.1 branch */
558    #ifdef __cplusplus
559    
560    /*
561     * Given an active context, a static scope level, and an upvar cookie, return
562     * the value of the upvar.
563     */
564    extern jsval&
565    js_GetUpvar(JSContext *cx, uintN level, uintN cookie);
566    
567    #endif
568    
569  /*  /*
570   * JS_LONE_INTERPRET indicates that the compiler should see just the code for   * JS_LONE_INTERPRET indicates that the compiler should see just the code for
571   * the js_Interpret function when compiling jsinterp.cpp. The rest of the code   * the js_Interpret function when compiling jsinterp.cpp. The rest of the code
# Line 509  Line 590 
590  #else  #else
591  # define JS_STATIC_INTERPRET  # define JS_STATIC_INTERPRET
592    
593  extern jsval *  extern JS_REQUIRES_STACK jsval *
594  js_AllocRawStack(JSContext *cx, uintN nslots, void **markp);  js_AllocRawStack(JSContext *cx, uintN nslots, void **markp);
595    
596  extern void  extern JS_REQUIRES_STACK void
597  js_FreeRawStack(JSContext *cx, void *mark);  js_FreeRawStack(JSContext *cx, void *mark);
598    
599  /*  /*
# Line 533  Line 614 
614  extern JSObject *  extern JSObject *
615  js_ComputeGlobalThis(JSContext *cx, JSBool lazy, jsval *argv);  js_ComputeGlobalThis(JSContext *cx, JSBool lazy, jsval *argv);
616    
617  extern JSBool  extern JS_REQUIRES_STACK JSBool
618  js_EnterWith(JSContext *cx, jsint stackIndex);  js_EnterWith(JSContext *cx, jsint stackIndex);
619    
620  extern void  extern JS_REQUIRES_STACK void
621  js_LeaveWith(JSContext *cx);  js_LeaveWith(JSContext *cx);
622    
623  extern JSClass *  extern JS_REQUIRES_STACK JSClass *
624  js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth);  js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth);
625    
 extern jsint  
 js_CountWithBlocks(JSContext *cx, JSStackFrame *fp);  
   
626  /*  /*
627   * Unwind block and scope chains to match the given depth. The function sets   * Unwind block and scope chains to match the given depth. The function sets
628   * fp->sp on return to stackDepth.   * fp->sp on return to stackDepth.
629   */   */
630  extern JSBool  extern JS_REQUIRES_STACK JSBool
631  js_UnwindScope(JSContext *cx, JSStackFrame *fp, jsint stackDepth,  js_UnwindScope(JSContext *cx, JSStackFrame *fp, jsint stackDepth,
632                 JSBool normalUnwind);                 JSBool normalUnwind);
633    
634  extern JSBool  extern JSBool
 js_InternNonIntElementId(JSContext *cx, JSObject *obj, jsval idval, jsid *idp);  
   
 extern JSBool  
635  js_OnUnknownMethod(JSContext *cx, jsval *vp);  js_OnUnknownMethod(JSContext *cx, jsval *vp);
636    
637  /*  /*
# Line 572  Line 647 
647   * Opcode tracing helper. When len is not 0, cx->fp->regs->pc[-len] gives the   * Opcode tracing helper. When len is not 0, cx->fp->regs->pc[-len] gives the
648   * previous opcode.   * previous opcode.
649   */   */
650  extern void  extern JS_REQUIRES_STACK void
651  js_TraceOpcode(JSContext *cx, jsint len);  js_TraceOpcode(JSContext *cx);
652    
653  /*  /*
654   * JS_OPMETER helper functions.   * JS_OPMETER helper functions.

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

  ViewVC Help
Powered by ViewVC 1.1.24