/[jscoverage]/trunk/js/jsdbgapi.cpp
ViewVC logotype

Diff of /trunk/js/jsdbgapi.cpp

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

revision 506 by siliconforks, Sat Sep 26 23:15:22 2009 UTC revision 507 by siliconforks, Sun Jan 10 07:23:34 2010 UTC
# Line 1  Line 1 
1  /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-  /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2   * vim: set ts=8 sw=4 et tw=78:   * vim: set ts=8 sw=4 et tw=78:
3   *   *
4   * ***** BEGIN LICENSE BLOCK *****   * ***** BEGIN LICENSE BLOCK *****
# Line 41  Line 41 
41  /*  /*
42   * JS debugging API.   * JS debugging API.
43   */   */
 #include "jsstddef.h"  
44  #include <string.h>  #include <string.h>
45  #include "jstypes.h"  #include "jstypes.h"
46    #include "jsstdint.h"
47  #include "jsutil.h" /* Added by JSIFY */  #include "jsutil.h" /* Added by JSIFY */
48  #include "jsclist.h"  #include "jsclist.h"
49  #include "jsapi.h"  #include "jsapi.h"
# Line 63  Line 63 
63  #include "jsstaticcheck.h"  #include "jsstaticcheck.h"
64  #include "jsstr.h"  #include "jsstr.h"
65    
66    #include "jsatominlines.h"
67    
68  #include "jsautooplen.h"  #include "jsautooplen.h"
69    
70  typedef struct JSTrap {  typedef struct JSTrap {
# Line 116  Line 118 
118                  size_t nbytes;                  size_t nbytes;
119    
120                  nbytes = script->length * sizeof(jsbytecode);                  nbytes = script->length * sizeof(jsbytecode);
121                  notes = SCRIPT_NOTES(script);                  notes = script->notes();
122                  for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))                  for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
123                      continue;                      continue;
124                  nbytes += (sn - notes + 1) * sizeof *sn;                  nbytes += (sn - notes + 1) * sizeof *sn;
125    
126                  code = (jsbytecode *) JS_malloc(cx, nbytes);                  code = (jsbytecode *) cx->malloc(nbytes);
127                  if (!code)                  if (!code)
128                      break;                      break;
129                  memcpy(code, script->code, nbytes);                  memcpy(code, script->code, nbytes);
# Line 153  Line 155 
155      } else {      } else {
156          sample = rt->debuggerMutations;          sample = rt->debuggerMutations;
157          DBG_UNLOCK(rt);          DBG_UNLOCK(rt);
158          trap = (JSTrap *) JS_malloc(cx, sizeof *trap);          trap = (JSTrap *) cx->malloc(sizeof *trap);
159          if (!trap)          if (!trap)
160              return JS_FALSE;              return JS_FALSE;
161          trap->closure = NULL;          trap->closure = NULL;
162          if(!js_AddRoot(cx, &trap->closure, "trap->closure")) {          if(!js_AddRoot(cx, &trap->closure, "trap->closure")) {
163              JS_free(cx, trap);              cx->free(trap);
164              return JS_FALSE;              return JS_FALSE;
165          }          }
166          DBG_LOCK(rt);          DBG_LOCK(rt);
# Line 182  Line 184 
184      DBG_UNLOCK(rt);      DBG_UNLOCK(rt);
185      if (junk) {      if (junk) {
186          js_RemoveRoot(rt, &junk->closure);          js_RemoveRoot(rt, &junk->closure);
187          JS_free(cx, junk);          cx->free(junk);
188      }      }
189      return JS_TRUE;      return JS_TRUE;
190  }  }
# Line 211  Line 213 
213      DBG_UNLOCK(cx->runtime);      DBG_UNLOCK(cx->runtime);
214    
215      js_RemoveRoot(cx->runtime, &trap->closure);      js_RemoveRoot(cx->runtime, &trap->closure);
216      JS_free(cx, trap);      cx->free(trap);
217  }  }
218    
219  JS_PUBLIC_API(void)  JS_PUBLIC_API(void)
# Line 323  Line 325 
325      return status;      return status;
326  }  }
327    
328    #ifdef JS_TRACER
329    static void
330    JITInhibitingHookChange(JSRuntime *rt, bool wasInhibited)
331    {
332        if (wasInhibited) {
333            if (!rt->debuggerInhibitsJIT()) {
334                for (JSCList *cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next)
335                    js_ContextFromLinkField(cl)->updateJITEnabled();
336            }
337        } else if (rt->debuggerInhibitsJIT()) {
338            for (JSCList *cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next)
339                js_ContextFromLinkField(cl)->jitEnabled = false;
340        }
341    }
342    
343    static void
344    LeaveTraceRT(JSRuntime *rt)
345    {
346        JSThreadData *data = js_CurrentThreadData(rt);
347        JSContext *cx = data ? data->traceMonitor.tracecx : NULL;
348        JS_UNLOCK_GC(rt);
349    
350        if (cx)
351            js_LeaveTrace(cx);
352    }
353    #endif
354    
355  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
356  JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure)  JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure)
357  {  {
358    #ifdef JS_TRACER
359        JS_LOCK_GC(rt);
360        bool wasInhibited = rt->debuggerInhibitsJIT();
361    #endif
362      rt->globalDebugHooks.interruptHandler = handler;      rt->globalDebugHooks.interruptHandler = handler;
363      rt->globalDebugHooks.interruptHandlerData = closure;      rt->globalDebugHooks.interruptHandlerData = closure;
364    #ifdef JS_TRACER
365        JITInhibitingHookChange(rt, wasInhibited);
366        JS_UNLOCK_GC(rt);
367        LeaveTraceRT(rt);
368    #endif
369      return JS_TRUE;      return JS_TRUE;
370  }  }
371    
372  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
373  JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep)  JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep)
374  {  {
375    #ifdef JS_TRACER
376        JS_LOCK_GC(rt);
377        bool wasInhibited = rt->debuggerInhibitsJIT();
378    #endif
379      if (handlerp)      if (handlerp)
380          *handlerp = (JSTrapHandler)rt->globalDebugHooks.interruptHandler;          *handlerp = rt->globalDebugHooks.interruptHandler;
381      if (closurep)      if (closurep)
382          *closurep = rt->globalDebugHooks.interruptHandlerData;          *closurep = rt->globalDebugHooks.interruptHandlerData;
383      rt->globalDebugHooks.interruptHandler = 0;      rt->globalDebugHooks.interruptHandler = 0;
384      rt->globalDebugHooks.interruptHandlerData = 0;      rt->globalDebugHooks.interruptHandlerData = 0;
385    #ifdef JS_TRACER
386        JITInhibitingHookChange(rt, wasInhibited);
387        JS_UNLOCK_GC(rt);
388    #endif
389      return JS_TRUE;      return JS_TRUE;
390  }  }
391    
# Line 351  Line 397 
397      JSScopeProperty     *sprop;      JSScopeProperty     *sprop;
398      JSPropertyOp        setter;      JSPropertyOp        setter;
399      JSWatchPointHandler handler;      JSWatchPointHandler handler;
400      void                *closure;      JSObject            *closure;
401      uintN               flags;      uintN               flags;
402  } JSWatchPoint;  } JSWatchPoint;
403    
# Line 395  Line 441 
441      if (!setter) {      if (!setter) {
442          JS_LOCK_OBJ(cx, wp->object);          JS_LOCK_OBJ(cx, wp->object);
443          scope = OBJ_SCOPE(wp->object);          scope = OBJ_SCOPE(wp->object);
444          found = (scope->object == wp->object &&          found = (scope->lookup(sprop->id) != NULL);
                  SCOPE_GET_PROPERTY(scope, sprop->id));  
445          JS_UNLOCK_SCOPE(cx, scope);          JS_UNLOCK_SCOPE(cx, scope);
446    
447          /*          /*
# Line 405  Line 450 
450           * the property attributes.           * the property attributes.
451           */           */
452          if (found) {          if (found) {
453              sprop = js_ChangeScopePropertyAttrs(cx, scope, sprop,              sprop = scope->change(cx, sprop, 0, sprop->attrs,
454                                                  0, sprop->attrs,                                    sprop->getter, wp->setter);
                                                 sprop->getter,  
                                                 wp->setter);  
455              if (!sprop)              if (!sprop)
456                  ok = JS_FALSE;                  ok = JS_FALSE;
457          }          }
458      }      }
459    
460      JS_free(cx, wp);      cx->free(wp);
461      return ok;      return ok;
462  }  }
463    
# Line 435  Line 478 
478           &wp->links != &rt->watchPointList;           &wp->links != &rt->watchPointList;
479           wp = (JSWatchPoint *)wp->links.next) {           wp = (JSWatchPoint *)wp->links.next) {
480          if (wp->object == obj) {          if (wp->object == obj) {
481              TRACE_SCOPE_PROPERTY(trc, wp->sprop);              wp->sprop->trace(trc);
482              if ((wp->sprop->attrs & JSPROP_SETTER) && wp->setter) {              if ((wp->sprop->attrs & JSPROP_SETTER) && wp->setter) {
483                  JS_CALL_OBJECT_TRACER(trc, js_CastAsObject(wp->setter),                  JS_CALL_OBJECT_TRACER(trc, js_CastAsObject(wp->setter),
484                                        "wp->setter");                                        "wp->setter");
485              }              }
486              JS_SET_TRACING_NAME(trc, "wp->closure");              JS_SET_TRACING_NAME(trc, "wp->closure");
487              js_CallValueTracerIfGCThing(trc, (jsval) wp->closure);              js_CallValueTracerIfGCThing(trc, OBJECT_TO_JSVAL(wp->closure));
488          }          }
489      }      }
490  }  }
# Line 485  Line 528 
528      for (wp = (JSWatchPoint *)rt->watchPointList.next;      for (wp = (JSWatchPoint *)rt->watchPointList.next;
529           &wp->links != &rt->watchPointList;           &wp->links != &rt->watchPointList;
530           wp = (JSWatchPoint *)wp->links.next) {           wp = (JSWatchPoint *)wp->links.next) {
531          if (wp->object == scope->object && wp->sprop->id == id)          if (OBJ_SCOPE(wp->object) == scope && wp->sprop->id == id)
532              return wp;              return wp;
533      }      }
534      return NULL;      return NULL;
# Line 521  Line 564 
564      for (wp = (JSWatchPoint *)rt->watchPointList.next;      for (wp = (JSWatchPoint *)rt->watchPointList.next;
565           &wp->links != &rt->watchPointList;           &wp->links != &rt->watchPointList;
566           wp = (JSWatchPoint *)wp->links.next) {           wp = (JSWatchPoint *)wp->links.next) {
567          if ((!scope || wp->object == scope->object) && wp->sprop == sprop) {          if ((!scope || OBJ_SCOPE(wp->object) == scope) && wp->sprop == sprop) {
568              setter = wp->setter;              setter = wp->setter;
569              break;              break;
570          }          }
# Line 589  Line 632 
632                  JSStackFrame frame;                  JSStackFrame frame;
633                  JSFrameRegs regs;                  JSFrameRegs regs;
634    
635                  closure = (JSObject *) wp->closure;                  closure = wp->closure;
636                  clasp = OBJ_GET_CLASS(cx, closure);                  clasp = OBJ_GET_CLASS(cx, closure);
637                  if (clasp == &js_FunctionClass) {                  if (clasp == &js_FunctionClass) {
638                      fun = GET_FUNCTION_PRIVATE(cx, closure);                      fun = GET_FUNCTION_PRIVATE(cx, closure);
639                      script = FUN_SCRIPT(fun);                      script = FUN_SCRIPT(fun);
640                  } else if (clasp == &js_ScriptClass) {                  } else if (clasp == &js_ScriptClass) {
641                      fun = NULL;                      fun = NULL;
642                      script = (JSScript *) JS_GetPrivate(cx, closure);                      script = (JSScript *) closure->getPrivate();
643                  } else {                  } else {
644                      fun = NULL;                      fun = NULL;
645                      script = NULL;                      script = NULL;
# Line 620  Line 663 
663                      if (nslots <= JS_ARRAY_LENGTH(smallv)) {                      if (nslots <= JS_ARRAY_LENGTH(smallv)) {
664                          argv = smallv;                          argv = smallv;
665                      } else {                      } else {
666                          argv = (jsval *) JS_malloc(cx, nslots * sizeof(jsval));                          argv = (jsval *) cx->malloc(nslots * sizeof(jsval));
667                          if (!argv) {                          if (!argv) {
668                              DBG_LOCK(rt);                              DBG_LOCK(rt);
669                              DropWatchPointAndUnlock(cx, wp, JSWP_HELD);                              DropWatchPointAndUnlock(cx, wp, JSWP_HELD);
# Line 635  Line 678 
678                      memset(&frame, 0, sizeof(frame));                      memset(&frame, 0, sizeof(frame));
679                      frame.script = script;                      frame.script = script;
680                      frame.regs = NULL;                      frame.regs = NULL;
                     frame.callee = closure;  
681                      frame.fun = fun;                      frame.fun = fun;
682                      frame.argv = argv + 2;                      frame.argv = argv + 2;
683                      frame.down = js_GetTopStackFrame(cx);                      frame.down = js_GetTopStackFrame(cx);
# Line 652  Line 694 
694                              JSFUN_HEAVYWEIGHT_TEST(fun->flags) &&                              JSFUN_HEAVYWEIGHT_TEST(fun->flags) &&
695                              !js_GetCallObject(cx, &frame)) {                              !js_GetCallObject(cx, &frame)) {
696                              if (argv != smallv)                              if (argv != smallv)
697                                  JS_free(cx, argv);                                  cx->free(argv);
698                              DBG_LOCK(rt);                              DBG_LOCK(rt);
699                              DropWatchPointAndUnlock(cx, wp, JSWP_HELD);                              DropWatchPointAndUnlock(cx, wp, JSWP_HELD);
700                              return JS_FALSE;                              return JS_FALSE;
# Line 673  Line 715 
715                        : wp->setter(cx, obj, userid, vp));                        : wp->setter(cx, obj, userid, vp));
716                  if (injectFrame) {                  if (injectFrame) {
717                      /* Evil code can cause us to have an arguments object. */                      /* Evil code can cause us to have an arguments object. */
718                      if (frame.callobj)                      frame.putActivationObjects(cx);
                         ok &= js_PutCallObject(cx, &frame);  
                     if (frame.argsobj)  
                         ok &= js_PutArgsObject(cx, &frame);  
   
719                      cx->fp = frame.down;                      cx->fp = frame.down;
720                      if (argv != smallv)                      if (argv != smallv)
721                          JS_free(cx, argv);                          cx->free(argv);
722                  }                  }
723              }              }
724              DBG_LOCK(rt);              DBG_LOCK(rt);
# Line 691  Line 729 
729      return JS_TRUE;      return JS_TRUE;
730  }  }
731    
732  JS_REQUIRES_STACK JSBool  JSBool
733  js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,  js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
734                       jsval *rval)                       jsval *rval)
735  {  {
# Line 736  Line 774 
774  JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval,  JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval idval,
775                   JSWatchPointHandler handler, void *closure)                   JSWatchPointHandler handler, void *closure)
776  {  {
777        JSObject *origobj;
778        jsval v;
779        uintN attrs;
780      jsid propid;      jsid propid;
781      JSObject *pobj;      JSObject *pobj;
782      JSProperty *prop;      JSProperty *prop;
# Line 745  Line 786 
786      JSWatchPoint *wp;      JSWatchPoint *wp;
787      JSPropertyOp watcher;      JSPropertyOp watcher;
788    
789      if (!OBJ_IS_NATIVE(obj)) {      origobj = obj;
790          JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH,      obj = js_GetWrappedObject(cx, obj);
791                               OBJ_GET_CLASS(cx, obj)->name);      OBJ_TO_INNER_OBJECT(cx, obj);
792        if (!obj)
793          return JS_FALSE;          return JS_FALSE;
     }  
794    
795      if (JSVAL_IS_INT(idval)) {      if (JSVAL_IS_INT(idval)) {
796          propid = INT_JSVAL_TO_JSID(idval);          propid = INT_JSVAL_TO_JSID(idval);
797      } else {      } else {
798          if (!js_ValueToStringId(cx, idval, &propid))          if (!js_ValueToStringId(cx, idval, &propid))
799              return JS_FALSE;              return JS_FALSE;
800          CHECK_FOR_STRING_INDEX(propid);          propid = js_CheckForStringIndex(propid);
801        }
802    
803        /*
804         * If, by unwrapping and innerizing, we changed the object, check
805         * again to make sure that we're allowed to set a watch point.
806         */
807        if (origobj != obj && !obj->checkAccess(cx, propid, JSACC_WATCH, &v, &attrs))
808            return JS_FALSE;
809    
810        if (!OBJ_IS_NATIVE(obj)) {
811            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH,
812                                 OBJ_GET_CLASS(cx, obj)->name);
813            return JS_FALSE;
814      }      }
815    
816      if (!js_LookupProperty(cx, obj, propid, &pobj, &prop))      if (!js_LookupProperty(cx, obj, propid, &pobj, &prop))
# Line 768  Line 822 
822          sprop = js_FindWatchPoint(rt, OBJ_SCOPE(obj), propid);          sprop = js_FindWatchPoint(rt, OBJ_SCOPE(obj), propid);
823          if (!sprop) {          if (!sprop) {
824              /* Make a new property in obj so we can watch for the first set. */              /* Make a new property in obj so we can watch for the first set. */
825              if (!js_DefineProperty(cx, obj, propid, JSVAL_VOID,              if (!js_DefineNativeProperty(cx, obj, propid, JSVAL_VOID, NULL, NULL,
826                                     NULL, NULL, JSPROP_ENUMERATE,                                           JSPROP_ENUMERATE, 0, 0, &prop)) {
                                    &prop)) {  
827                  return JS_FALSE;                  return JS_FALSE;
828              }              }
829              sprop = (JSScopeProperty *) prop;              sprop = (JSScopeProperty *) prop;
# Line 792  Line 845 
845              flags = sprop->flags;              flags = sprop->flags;
846              shortid = sprop->shortid;              shortid = sprop->shortid;
847          } else {          } else {
848              if (!OBJ_GET_PROPERTY(cx, pobj, propid, &value) ||              if (!pobj->getProperty(cx, propid, &value) ||
849                  !OBJ_GET_ATTRIBUTES(cx, pobj, propid, prop, &attrs)) {                  !pobj->getAttributes(cx, propid, prop, &attrs)) {
850                  OBJ_DROP_PROPERTY(cx, pobj, prop);                  pobj->dropProperty(cx, prop);
851                  return JS_FALSE;                  return JS_FALSE;
852              }              }
853              getter = setter = NULL;              getter = setter = NULL;
854              flags = 0;              flags = 0;
855              shortid = 0;              shortid = 0;
856          }          }
857          OBJ_DROP_PROPERTY(cx, pobj, prop);          pobj->dropProperty(cx, prop);
858    
859          /* Recall that obj is native, whether or not pobj is native. */          /* Recall that obj is native, whether or not pobj is native. */
860          if (!js_DefineNativeProperty(cx, obj, propid, value, getter, setter,          if (!js_DefineNativeProperty(cx, obj, propid, value, getter, setter,
# Line 813  Line 866 
866    
867      /*      /*
868       * At this point, prop/sprop exists in obj, obj is locked, and we must       * At this point, prop/sprop exists in obj, obj is locked, and we must
869       * OBJ_DROP_PROPERTY(cx, obj, prop) before returning.       * obj->dropProperty(cx, prop) before returning.
870       */       */
871      ok = JS_TRUE;      ok = JS_TRUE;
872      DBG_LOCK(rt);      DBG_LOCK(rt);
# Line 826  Line 879 
879              goto out;              goto out;
880          }          }
881    
882          wp = (JSWatchPoint *) JS_malloc(cx, sizeof *wp);          wp = (JSWatchPoint *) cx->malloc(sizeof *wp);
883          if (!wp) {          if (!wp) {
884              ok = JS_FALSE;              ok = JS_FALSE;
885              goto out;              goto out;
# Line 862  Line 915 
915          ++rt->debuggerMutations;          ++rt->debuggerMutations;
916      }      }
917      wp->handler = handler;      wp->handler = handler;
918      wp->closure = closure;      wp->closure = reinterpret_cast<JSObject*>(closure);
919      DBG_UNLOCK(rt);      DBG_UNLOCK(rt);
920    
921  out:  out:
922      OBJ_DROP_PROPERTY(cx, obj, prop);      obj->dropProperty(cx, prop);
923      return ok;      return ok;
924  }  }
925    
# Line 1024  Line 1077 
1077      if (fp->fun) {      if (fp->fun) {
1078          callbacks = JS_GetSecurityCallbacks(cx);          callbacks = JS_GetSecurityCallbacks(cx);
1079          if (callbacks && callbacks->findObjectPrincipals) {          if (callbacks && callbacks->findObjectPrincipals) {
1080              if (FUN_OBJECT(fp->fun) != fp->callee)              if (FUN_OBJECT(fp->fun) != fp->callee())
1081                  return callbacks->findObjectPrincipals(cx, fp->callee);                  return callbacks->findObjectPrincipals(cx, fp->callee());
1082              /* FALL THROUGH */              /* FALL THROUGH */
1083          }          }
1084      }      }
# Line 1042  Line 1095 
1095    
1096      callbacks = JS_GetSecurityCallbacks(cx);      callbacks = JS_GetSecurityCallbacks(cx);
1097      if (callbacks && callbacks->findObjectPrincipals) {      if (callbacks && callbacks->findObjectPrincipals) {
1098          principals = callbacks->findObjectPrincipals(cx, fp->callee);          principals = callbacks->findObjectPrincipals(cx, fp->callee());
1099      } else {      } else {
1100          principals = NULL;          principals = NULL;
1101      }      }
# Line 1147  Line 1200 
1200          afp = NULL;          afp = NULL;
1201      }      }
1202    
1203      if (!fp->thisp && fp->argv)      if (fp->argv)
1204          fp->thisp = js_ComputeThis(cx, JS_TRUE, fp->argv);          fp->thisp = js_ComputeThis(cx, JS_TRUE, fp->argv);
1205    
1206      if (afp) {      if (afp) {
# Line 1171  Line 1224 
1224      if (!fp->fun)      if (!fp->fun)
1225          return NULL;          return NULL;
1226    
1227      JS_ASSERT(HAS_FUNCTION_CLASS(fp->callee));      JS_ASSERT(HAS_FUNCTION_CLASS(fp->callee()));
1228      JS_ASSERT(OBJ_GET_PRIVATE(cx, fp->callee) == fp->fun);      JS_ASSERT(fp->callee()->getPrivate() == fp->fun);
1229      return fp->callee;      return fp->callee();
1230  }  }
1231    
1232  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 1185  Line 1238 
1238  JS_PUBLIC_API(JSObject *)  JS_PUBLIC_API(JSObject *)
1239  JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp)  JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp)
1240  {  {
1241      return fp->callee;      return fp->callee();
1242  }  }
1243    
1244  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 1344  Line 1397 
1397      length = (uintN) len;      length = (uintN) len;
1398      ok = JS_EvaluateUCInStackFrame(cx, fp, chars, length, filename, lineno,      ok = JS_EvaluateUCInStackFrame(cx, fp, chars, length, filename, lineno,
1399                                     rval);                                     rval);
1400      JS_free(cx, chars);      cx->free(chars);
1401    
1402      return ok;      return ok;
1403  }  }
# Line 1367  Line 1420 
1420          sprop = SCOPE_LAST_PROP(scope);          sprop = SCOPE_LAST_PROP(scope);
1421      } else {      } else {
1422          while ((sprop = sprop->parent) != NULL) {          while ((sprop = sprop->parent) != NULL) {
1423              if (!SCOPE_HAD_MIDDLE_DELETE(scope))              if (!scope->hadMiddleDelete())
1424                  break;                  break;
1425              if (SCOPE_HAS_PROPERTY(scope, sprop))              if (scope->has(sprop))
1426                  break;                  break;
1427          }          }
1428      }      }
# Line 1463  Line 1516 
1516    
1517      /* have no props, or object's scope has not mutated from that of proto */      /* have no props, or object's scope has not mutated from that of proto */
1518      scope = OBJ_SCOPE(obj);      scope = OBJ_SCOPE(obj);
1519      if (scope->object != obj || scope->entryCount == 0) {      if (scope->entryCount == 0) {
1520          pda->length = 0;          pda->length = 0;
1521          pda->array = NULL;          pda->array = NULL;
1522          return JS_TRUE;          return JS_TRUE;
1523      }      }
1524    
1525      n = scope->entryCount;      n = scope->entryCount;
1526      pd = (JSPropertyDesc *) JS_malloc(cx, (size_t)n * sizeof(JSPropertyDesc));      pd = (JSPropertyDesc *) cx->malloc((size_t)n * sizeof(JSPropertyDesc));
1527      if (!pd)      if (!pd)
1528          return JS_FALSE;          return JS_FALSE;
1529      i = 0;      i = 0;
1530      for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {      for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
1531          if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop))          if (scope->hadMiddleDelete() && !scope->has(sprop))
1532              continue;              continue;
1533          if (!js_AddRoot(cx, &pd[i].id, NULL))          if (!js_AddRoot(cx, &pd[i].id, NULL))
1534              goto bad;              goto bad;
# Line 1512  Line 1565 
1565          if (pd[i].flags & JSPD_ALIAS)          if (pd[i].flags & JSPD_ALIAS)
1566              js_RemoveRoot(cx->runtime, &pd[i].alias);              js_RemoveRoot(cx->runtime, &pd[i].alias);
1567      }      }
1568      JS_free(cx, pd);      cx->free(pd);
1569  }  }
1570    
1571  /************************************************************************/  /************************************************************************/
# Line 1544  Line 1597 
1597  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
1598  JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)  JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
1599  {  {
1600    #ifdef JS_TRACER
1601        JS_LOCK_GC(rt);
1602        bool wasInhibited = rt->debuggerInhibitsJIT();
1603    #endif
1604      rt->globalDebugHooks.callHook = hook;      rt->globalDebugHooks.callHook = hook;
1605      rt->globalDebugHooks.callHookData = closure;      rt->globalDebugHooks.callHookData = closure;
1606    #ifdef JS_TRACER
1607        JITInhibitingHookChange(rt, wasInhibited);
1608        JS_UNLOCK_GC(rt);
1609        if (hook)
1610            LeaveTraceRT(rt);
1611    #endif
1612      return JS_TRUE;      return JS_TRUE;
1613  }  }
1614    
1615  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
1616  JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure)  JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure)
1617  {  {
1618    #ifdef JS_TRACER
1619        JS_LOCK_GC(rt);
1620        bool wasInhibited = rt->debuggerInhibitsJIT();
1621    #endif
1622      rt->globalDebugHooks.objectHook = hook;      rt->globalDebugHooks.objectHook = hook;
1623      rt->globalDebugHooks.objectHookData = closure;      rt->globalDebugHooks.objectHookData = closure;
1624    #ifdef JS_TRACER
1625        JITInhibitingHookChange(rt, wasInhibited);
1626        JS_UNLOCK_GC(rt);
1627        if (hook)
1628            LeaveTraceRT(rt);
1629    #endif
1630      return JS_TRUE;      return JS_TRUE;
1631  }  }
1632    
# Line 1588  Line 1661 
1661      }      }
1662      if (OBJ_IS_NATIVE(obj)) {      if (OBJ_IS_NATIVE(obj)) {
1663          scope = OBJ_SCOPE(obj);          scope = OBJ_SCOPE(obj);
1664          if (scope->object == obj) {          if (scope->owned()) {
1665              nbytes += sizeof *scope;              nbytes += sizeof *scope;
1666              nbytes += SCOPE_CAPACITY(scope) * sizeof(JSScopeProperty *);              nbytes += SCOPE_CAPACITY(scope) * sizeof(JSScopeProperty *);
1667          }          }
# Line 1604  Line 1677 
1677      nbytes = sizeof(JSAtom *) + sizeof(JSDHashEntryStub);      nbytes = sizeof(JSAtom *) + sizeof(JSDHashEntryStub);
1678      if (ATOM_IS_STRING(atom)) {      if (ATOM_IS_STRING(atom)) {
1679          nbytes += sizeof(JSString);          nbytes += sizeof(JSString);
1680          nbytes += (JSFLATSTR_LENGTH(ATOM_TO_STRING(atom)) + 1) * sizeof(jschar);          nbytes += (ATOM_TO_STRING(atom)->flatLength() + 1) * sizeof(jschar);
1681      } else if (ATOM_IS_DOUBLE(atom)) {      } else if (ATOM_IS_DOUBLE(atom)) {
1682          nbytes += sizeof(jsdouble);          nbytes += sizeof(jsdouble);
1683      }      }
# Line 1648  Line 1721 
1721      if (script->filename)      if (script->filename)
1722          nbytes += strlen(script->filename) + 1;          nbytes += strlen(script->filename) + 1;
1723    
1724      notes = SCRIPT_NOTES(script);      notes = script->notes();
1725      for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))      for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
1726          continue;          continue;
1727      nbytes += (sn - notes + 1) * sizeof *sn;      nbytes += (sn - notes + 1) * sizeof *sn;
1728    
1729      if (script->objectsOffset != 0) {      if (script->objectsOffset != 0) {
1730          objarray = JS_SCRIPT_OBJECTS(script);          objarray = script->objects();
1731          i = objarray->length;          i = objarray->length;
1732          nbytes += sizeof *objarray + i * sizeof objarray->vector[0];          nbytes += sizeof *objarray + i * sizeof objarray->vector[0];
1733          do {          do {
# Line 1663  Line 1736 
1736      }      }
1737    
1738      if (script->regexpsOffset != 0) {      if (script->regexpsOffset != 0) {
1739          objarray = JS_SCRIPT_REGEXPS(script);          objarray = script->regexps();
1740          i = objarray->length;          i = objarray->length;
1741          nbytes += sizeof *objarray + i * sizeof objarray->vector[0];          nbytes += sizeof *objarray + i * sizeof objarray->vector[0];
1742          do {          do {
# Line 1673  Line 1746 
1746    
1747      if (script->trynotesOffset != 0) {      if (script->trynotesOffset != 0) {
1748          nbytes += sizeof(JSTryNoteArray) +          nbytes += sizeof(JSTryNoteArray) +
1749              JS_SCRIPT_TRYNOTES(script)->length * sizeof(JSTryNote);              script->trynotes()->length * sizeof(JSTryNote);
1750      }      }
1751    
1752      principals = script->principals;      principals = script->principals;
# Line 1721  Line 1794 
1794  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
1795  JS_IsSystemObject(JSContext *cx, JSObject *obj)  JS_IsSystemObject(JSContext *cx, JSObject *obj)
1796  {  {
1797      return STOBJ_IS_SYSTEM(obj);      return obj->isSystem();
1798  }  }
1799    
1800  JS_PUBLIC_API(JSObject *)  JS_PUBLIC_API(JSObject *)
# Line 1730  Line 1803 
1803  {  {
1804      JSObject *obj;      JSObject *obj;
1805    
1806      obj = js_NewObject(cx, clasp, proto, parent, 0);      obj = js_NewObject(cx, clasp, proto, parent);
1807      if (obj && system)      if (obj && system)
1808          STOBJ_SET_SYSTEM(obj);          obj->setSystem();
1809      return obj;      return obj;
1810  }  }
1811    
1812  /************************************************************************/  /************************************************************************/
1813    
1814  JS_PUBLIC_API(JSDebugHooks *)  JS_PUBLIC_API(const JSDebugHooks *)
1815  JS_GetGlobalDebugHooks(JSRuntime *rt)  JS_GetGlobalDebugHooks(JSRuntime *rt)
1816  {  {
1817      return &rt->globalDebugHooks;      return &rt->globalDebugHooks;
1818  }  }
1819    
1820  JS_PUBLIC_API(JSDebugHooks *)  JS_PUBLIC_API(JSDebugHooks *)
1821  JS_SetContextDebugHooks(JSContext *cx, JSDebugHooks *hooks)  JS_SetContextDebugHooks(JSContext *cx, const JSDebugHooks *hooks)
1822  {  {
     JSDebugHooks *old;  
   
1823      JS_ASSERT(hooks);      JS_ASSERT(hooks);
1824      old = cx->debugHooks;      if (hooks != &cx->runtime->globalDebugHooks)
1825            js_LeaveTrace(cx);
1826    
1827    #ifdef JS_TRACER
1828        JS_LOCK_GC(cx->runtime);
1829    #endif
1830        JSDebugHooks *old = const_cast<JSDebugHooks *>(cx->debugHooks);
1831      cx->debugHooks = hooks;      cx->debugHooks = hooks;
1832    #ifdef JS_TRACER
1833        cx->updateJITEnabled();
1834        JS_UNLOCK_GC(cx->runtime);
1835    #endif
1836      return old;      return old;
1837  }  }
1838    
# Line 1882  Line 1963 
1963    
1964      if (argc > 0 && JSVAL_IS_STRING(argv[0])) {      if (argc > 0 && JSVAL_IS_STRING(argv[0])) {
1965          str = JSVAL_TO_STRING(argv[0]);          str = JSVAL_TO_STRING(argv[0]);
1966          cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));          cstr = js_DeflateString(cx, str->chars(), str->length());
1967          if (cstr) {          if (cstr) {
1968              CALLGRIND_DUMP_STATS_AT(cstr);              CALLGRIND_DUMP_STATS_AT(cstr);
1969              JS_free(cx, cstr);              cx->free(cstr);
1970              return JS_TRUE;              return JS_TRUE;
1971          }          }
1972      }      }
# Line 1957  Line 2038 
2038    
2039      if (argc > 0 && JSVAL_IS_STRING(argv[0])) {      if (argc > 0 && JSVAL_IS_STRING(argv[0])) {
2040          str = JSVAL_TO_STRING(argv[0]);          str = JSVAL_TO_STRING(argv[0]);
2041          params.tb5Filename = js_DeflateString(cx,          params.tb5Filename = js_DeflateString(cx, str->chars(), str->length());
                                               JSSTRING_CHARS(str),  
                                               JSSTRING_LENGTH(str));  
2042      }      }
2043    
2044      status = VTStartSampling(&params);      status = VTStartSampling(&params);
2045    
2046      if (params.tb5Filename != default_filename)      if (params.tb5Filename != default_filename)
2047          JS_free(cx, params.tb5Filename);          cx->free(params.tb5Filename);
2048    
2049      if (status != 0) {      if (status != 0) {
2050          if (status == VTAPI_MULTIPLE_RUNS)          if (status == VTAPI_MULTIPLE_RUNS)
# Line 2015  Line 2094 
2094  }  }
2095    
2096  #endif /* MOZ_VTUNE */  #endif /* MOZ_VTUNE */
2097    
2098    #ifdef MOZ_TRACEVIS
2099    /*
2100     * Ethogram - Javascript wrapper for TraceVis state
2101     *
2102     * ethology: The scientific study of animal behavior,
2103     *           especially as it occurs in a natural environment.
2104     * ethogram: A pictorial catalog of the behavioral patterns of
2105     *           an organism or a species.
2106     *
2107     */
2108    #if defined(XP_WIN)
2109    #include <windows.h>
2110    #else
2111    #include <sys/time.h>
2112    #endif
2113    #include "jstracer.h"
2114    
2115    #define ETHOGRAM_BUF_SIZE 65536
2116    
2117    static JSBool
2118    ethogram_construct(JSContext *cx, JSObject *obj,
2119                       uintN argc, jsval *argv, jsval *rval);
2120    static void
2121    ethogram_finalize(JSContext *cx, JSObject *obj);
2122    
2123    static JSClass ethogram_class = {
2124        "Ethogram",
2125        JSCLASS_HAS_PRIVATE,
2126        JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
2127        JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, ethogram_finalize,
2128        JSCLASS_NO_OPTIONAL_MEMBERS
2129    };
2130    
2131    struct EthogramEvent {
2132        TraceVisState s;
2133        TraceVisExitReason r;
2134        int ts;
2135        int tus;
2136        JSString *filename;
2137        int lineno;
2138    };
2139    
2140    static int
2141    compare_strings(const void *k1, const void *k2)
2142    {
2143        return strcmp((const char *) k1, (const char *) k2) == 0;
2144    }
2145    
2146    class EthogramEventBuffer {
2147    private:
2148        EthogramEvent mBuf[ETHOGRAM_BUF_SIZE];
2149        int mReadPos;
2150        int mWritePos;
2151        JSObject *mFilenames;
2152        int mStartSecond;
2153    
2154        struct EthogramScriptEntry {
2155            char *filename;
2156            JSString *jsfilename;
2157    
2158            EthogramScriptEntry *next;
2159        };
2160        EthogramScriptEntry *mScripts;
2161    
2162    public:
2163        friend JSBool
2164        ethogram_construct(JSContext *cx, JSObject *obj,
2165                           uintN argc, jsval *argv, jsval *rval);
2166    
2167        inline void push(TraceVisState s, TraceVisExitReason r, char *filename, int lineno) {
2168            mBuf[mWritePos].s = s;
2169            mBuf[mWritePos].r = r;
2170    #if defined(XP_WIN)
2171            FILETIME now;
2172            GetSystemTimeAsFileTime(&now);
2173            unsigned long long raw_us = 0.1 *
2174                (((unsigned long long) now.dwHighDateTime << 32ULL) |
2175                 (unsigned long long) now.dwLowDateTime);
2176            unsigned int sec = raw_us / 1000000L;
2177            unsigned int usec = raw_us % 1000000L;
2178            mBuf[mWritePos].ts = sec - mStartSecond;
2179            mBuf[mWritePos].tus = usec;
2180    #else
2181            struct timeval tv;
2182            gettimeofday(&tv, NULL);
2183            mBuf[mWritePos].ts = tv.tv_sec - mStartSecond;
2184            mBuf[mWritePos].tus = tv.tv_usec;
2185    #endif
2186    
2187            JSString *jsfilename = findScript(filename);
2188            mBuf[mWritePos].filename = jsfilename;
2189            mBuf[mWritePos].lineno = lineno;
2190    
2191            mWritePos = (mWritePos + 1) % ETHOGRAM_BUF_SIZE;
2192            if (mWritePos == mReadPos) {
2193                mReadPos = (mWritePos + 1) % ETHOGRAM_BUF_SIZE;
2194            }
2195        }
2196    
2197        inline EthogramEvent *pop() {
2198            EthogramEvent *e = &mBuf[mReadPos];
2199            mReadPos = (mReadPos + 1) % ETHOGRAM_BUF_SIZE;
2200            return e;
2201        }
2202    
2203        bool isEmpty() {
2204            return (mReadPos == mWritePos);
2205        }
2206    
2207        EthogramScriptEntry *addScript(JSContext *cx, JSObject *obj, char *filename, JSString *jsfilename) {
2208            JSHashNumber hash = JS_HashString(filename);
2209            JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, filename);
2210            if (*hep != NULL)
2211                return JS_FALSE;
2212    
2213            JS_HashTableRawAdd(traceVisScriptTable, hep, hash, filename, this);
2214    
2215            EthogramScriptEntry * entry = (EthogramScriptEntry *) JS_malloc(cx, sizeof(EthogramScriptEntry));
2216            if (entry == NULL)
2217                return NULL;
2218    
2219            entry->next = mScripts;
2220            mScripts = entry;
2221            entry->filename = filename;
2222            entry->jsfilename = jsfilename;
2223    
2224            return mScripts;
2225        }
2226    
2227        void removeScripts(JSContext *cx) {
2228            EthogramScriptEntry *se = mScripts;
2229            while (se != NULL) {
2230                char *filename = se->filename;
2231    
2232                JSHashNumber hash = JS_HashString(filename);
2233                JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, filename);
2234                JSHashEntry *he = *hep;
2235                if (he) {
2236                    /* we hardly knew he */
2237                    JS_HashTableRawRemove(traceVisScriptTable, hep, he);
2238                }
2239    
2240                EthogramScriptEntry *se_head = se;
2241                se = se->next;
2242                JS_free(cx, se_head);
2243            }
2244        }
2245    
2246        JSString *findScript(char *filename) {
2247            EthogramScriptEntry *se = mScripts;
2248            while (se != NULL) {
2249                if (compare_strings(se->filename, filename))
2250                    return (se->jsfilename);
2251                se = se->next;
2252            }
2253            return NULL;
2254        }
2255    
2256        JSObject *filenames() {
2257            return mFilenames;
2258        }
2259    
2260        int length() {
2261            if (mWritePos < mReadPos)
2262                return (mWritePos + ETHOGRAM_BUF_SIZE) - mReadPos;
2263            else
2264                return mWritePos - mReadPos;
2265        }
2266    };
2267    
2268    static char jstv_empty[] = "<null>";
2269    
2270    inline char *
2271    jstv_Filename(JSStackFrame *fp)
2272    {
2273        while (fp && fp->script == NULL)
2274            fp = fp->down;
2275        return (fp && fp->script && fp->script->filename)
2276               ? (char *)fp->script->filename
2277               : jstv_empty;
2278    }
2279    inline uintN
2280    jstv_Lineno(JSContext *cx, JSStackFrame *fp)
2281    {
2282        while (fp && fp->regs == NULL)
2283            fp = fp->down;
2284        return (fp && fp->regs) ? js_FramePCToLineNumber(cx, fp) : 0;
2285    }
2286    
2287    /* Collect states here and distribute to a matching buffer, if any */
2288    JS_FRIEND_API(void)
2289    js_StoreTraceVisState(JSContext *cx, TraceVisState s, TraceVisExitReason r)
2290    {
2291        JSStackFrame *fp = cx->fp;
2292    
2293        char *script_file = jstv_Filename(fp);
2294        JSHashNumber hash = JS_HashString(script_file);
2295    
2296        JSHashEntry **hep = JS_HashTableRawLookup(traceVisScriptTable, hash, script_file);
2297        /* update event buffer, flag if overflowed */
2298        JSHashEntry *he = *hep;
2299        if (he) {
2300            EthogramEventBuffer *p;
2301            p = (EthogramEventBuffer *) he->value;
2302    
2303            p->push(s, r, script_file, jstv_Lineno(cx, fp));
2304        }
2305    }
2306    
2307    static JSBool
2308    ethogram_construct(JSContext *cx, JSObject *obj,
2309                       uintN argc, jsval *argv, jsval *rval)
2310    {
2311        EthogramEventBuffer *p;
2312    
2313        p = (EthogramEventBuffer *) JS_malloc(cx, sizeof(EthogramEventBuffer));
2314    
2315        p->mReadPos = p->mWritePos = 0;
2316        p->mScripts = NULL;
2317        p->mFilenames = JS_NewArrayObject(cx, 0, NULL);
2318    
2319    #if defined(XP_WIN)
2320        FILETIME now;
2321        GetSystemTimeAsFileTime(&now);
2322        unsigned long long raw_us = 0.1 *
2323            (((unsigned long long) now.dwHighDateTime << 32ULL) |
2324             (unsigned long long) now.dwLowDateTime);
2325        unsigned int s = raw_us / 1000000L;
2326        p->mStartSecond = s;
2327    #else
2328        struct timeval tv;
2329        gettimeofday(&tv, NULL);
2330        p->mStartSecond = tv.tv_sec;
2331    #endif
2332        jsval filenames = OBJECT_TO_JSVAL(p->filenames());
2333        if (!JS_DefineProperty(cx, obj, "filenames", filenames,
2334                               NULL, NULL, JSPROP_READONLY|JSPROP_PERMANENT))
2335            return JS_FALSE;
2336    
2337        if (!JS_IsConstructing(cx)) {
2338            obj = JS_NewObject(cx, &ethogram_class, NULL, NULL);
2339            if (!obj)
2340                return JS_FALSE;
2341            *rval = OBJECT_TO_JSVAL(obj);
2342        }
2343        JS_SetPrivate(cx, obj, p);
2344        return JS_TRUE;
2345    }
2346    
2347    static void
2348    ethogram_finalize(JSContext *cx, JSObject *obj)
2349    {
2350        EthogramEventBuffer *p;
2351        p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, &ethogram_class, NULL);
2352        if (!p)
2353            return;
2354    
2355        p->removeScripts(cx);
2356    
2357        JS_free(cx, p);
2358    }
2359    
2360    static JSBool
2361    ethogram_addScript(JSContext *cx, JSObject *obj,
2362                       uintN argc, jsval *argv, jsval *rval)
2363    {
2364        JSString *str;
2365        char *filename = NULL;
2366        if (argc > 0 && JSVAL_IS_STRING(argv[0])) {
2367            str = JSVAL_TO_STRING(argv[0]);
2368            filename = js_DeflateString(cx,
2369                                        str->chars(),
2370                                        str->length());
2371        }
2372    
2373        /* silently ignore no args */
2374        if (!filename)
2375            return JS_TRUE;
2376    
2377        EthogramEventBuffer *p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, &ethogram_class, argv);
2378    
2379        p->addScript(cx, obj, filename, str);
2380        JS_CallFunctionName(cx, p->filenames(), "push", 1, argv, rval);
2381        return JS_TRUE;
2382    }
2383    
2384    static JSBool
2385    ethogram_getAllEvents(JSContext *cx, JSObject *obj,
2386                          uintN argc, jsval *argv, jsval *rval)
2387    {
2388        EthogramEventBuffer *p;
2389    
2390        p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, &ethogram_class, argv);
2391        if (!p)
2392            return JS_FALSE;
2393    
2394        if (p->isEmpty()) {
2395            *rval = JSVAL_NULL;
2396            return JS_TRUE;
2397        }
2398    
2399        JSObject *rarray = JS_NewArrayObject(cx, 0, NULL);
2400        if (rarray == NULL) {
2401            *rval = JSVAL_NULL;
2402            return JS_TRUE;
2403        }
2404    
2405        *rval = OBJECT_TO_JSVAL(rarray);
2406    
2407        for (int i = 0; !p->isEmpty(); i++) {
2408    
2409            JSObject *x = JS_NewObject(cx, NULL, NULL, NULL);
2410            if (x == NULL)
2411                return JS_FALSE;
2412    
2413            EthogramEvent *e = p->pop();
2414    
2415            jsval state = INT_TO_JSVAL(e->s);
2416            jsval reason = INT_TO_JSVAL(e->r);
2417            jsval ts = INT_TO_JSVAL(e->ts);
2418            jsval tus = INT_TO_JSVAL(e->tus);
2419    
2420            jsval filename = STRING_TO_JSVAL(e->filename);
2421            jsval lineno = INT_TO_JSVAL(e->lineno);
2422    
2423            if (!JS_SetProperty(cx, x, "state", &state))
2424                return JS_FALSE;
2425            if (!JS_SetProperty(cx, x, "reason", &reason))
2426                return JS_FALSE;
2427            if (!JS_SetProperty(cx, x, "ts", &ts))
2428                return JS_FALSE;
2429            if (!JS_SetProperty(cx, x, "tus", &tus))
2430                return JS_FALSE;
2431    
2432            if (!JS_SetProperty(cx, x, "filename", &filename))
2433                return JS_FALSE;
2434            if (!JS_SetProperty(cx, x, "lineno", &lineno))
2435                return JS_FALSE;
2436    
2437            jsval element = OBJECT_TO_JSVAL(x);
2438            JS_SetElement(cx, rarray, i, &element);
2439        }
2440    
2441        return JS_TRUE;
2442    }
2443    
2444    static JSBool
2445    ethogram_getNextEvent(JSContext *cx, JSObject *obj,
2446                          uintN argc, jsval *argv, jsval *rval)
2447    {
2448        EthogramEventBuffer *p;
2449    
2450        p = (EthogramEventBuffer *) JS_GetInstancePrivate(cx, obj, &ethogram_class, argv);
2451        if (!p)
2452            return JS_FALSE;
2453    
2454        JSObject *x = JS_NewObject(cx, NULL, NULL, NULL);
2455        if (x == NULL)
2456            return JS_FALSE;
2457    
2458        if (p->isEmpty()) {
2459            *rval = JSVAL_NULL;
2460            return JS_TRUE;
2461        }
2462    
2463        EthogramEvent *e = p->pop();
2464        jsval state = INT_TO_JSVAL(e->s);
2465        jsval reason = INT_TO_JSVAL(e->r);
2466        jsval ts = INT_TO_JSVAL(e->ts);
2467        jsval tus = INT_TO_JSVAL(e->tus);
2468    
2469        jsval filename = STRING_TO_JSVAL(e->filename);
2470        jsval lineno = INT_TO_JSVAL(e->lineno);
2471    
2472        if (!JS_SetProperty(cx, x, "state", &state))
2473            return JS_FALSE;
2474        if (!JS_SetProperty(cx, x, "reason", &reason))
2475            return JS_FALSE;
2476        if (!JS_SetProperty(cx, x, "ts", &ts))
2477            return JS_FALSE;
2478        if (!JS_SetProperty(cx, x, "tus", &tus))
2479            return JS_FALSE;
2480        if (!JS_SetProperty(cx, x, "filename", &filename))
2481            return JS_FALSE;
2482    
2483        if (!JS_SetProperty(cx, x, "lineno", &lineno))
2484            return JS_FALSE;
2485    
2486        *rval = OBJECT_TO_JSVAL(x);
2487    
2488        return JS_TRUE;
2489    }
2490    
2491    static JSFunctionSpec ethogram_methods[] = {
2492        {"addScript",    ethogram_addScript,    1},
2493        {"getAllEvents", ethogram_getAllEvents, 0},
2494        {"getNextEvent", ethogram_getNextEvent, 0},
2495        {0}
2496    };
2497    
2498    /*
2499     * An |Ethogram| organizes the output of a collection of files that should be
2500     * monitored together. A single object gets events for the group.
2501     */
2502    JS_FRIEND_API(JSBool)
2503    js_InitEthogram(JSContext *cx, JSObject *obj,
2504                    uintN argc, jsval *argv, jsval *rval)
2505    {
2506        if (!traceVisScriptTable) {
2507            traceVisScriptTable = JS_NewHashTable(8, JS_HashString, compare_strings,
2508                                             NULL, NULL, NULL);
2509        }
2510    
2511        JS_InitClass(cx, JS_GetGlobalObject(cx), NULL, &ethogram_class,
2512                     ethogram_construct, 0, NULL, ethogram_methods,
2513                     NULL, NULL);
2514    
2515        return JS_TRUE;
2516    }
2517    
2518    JS_FRIEND_API(JSBool)
2519    js_ShutdownEthogram(JSContext *cx, JSObject *obj,
2520                        uintN argc, jsval *argv, jsval *rval)
2521    {
2522        if (traceVisScriptTable)
2523            JS_HashTableDestroy(traceVisScriptTable);
2524    
2525        return JS_TRUE;
2526    }
2527    
2528    #endif /* MOZ_TRACEVIS */

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

  ViewVC Help
Powered by ViewVC 1.1.24