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

Diff of /trunk/js/jsapi.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   * JavaScript API.   * JavaScript API.
43   */   */
 #include "jsstddef.h"  
44  #include <ctype.h>  #include <ctype.h>
45  #include <stdarg.h>  #include <stdarg.h>
46  #include <stdlib.h>  #include <stdlib.h>
47  #include <string.h>  #include <string.h>
48  #include "jstypes.h"  #include "jstypes.h"
49    #include "jsstdint.h"
50  #include "jsarena.h" /* Added by JSIFY */  #include "jsarena.h" /* Added by JSIFY */
51  #include "jsutil.h" /* Added by JSIFY */  #include "jsutil.h" /* Added by JSIFY */
52  #include "jsclist.h"  #include "jsclist.h"
# Line 79  Line 79 
79  #include "jsscope.h"  #include "jsscope.h"
80  #include "jsscript.h"  #include "jsscript.h"
81  #include "jsstr.h"  #include "jsstr.h"
82    #include "jstask.h"
83  #include "jstracer.h"  #include "jstracer.h"
84  #include "jsdbgapi.h"  #include "jsdbgapi.h"
85  #include "prmjtime.h"  #include "prmjtime.h"
86  #include "jsstaticcheck.h"  #include "jsstaticcheck.h"
87    #include "jsvector.h"
88    
89  #if JS_HAS_FILE_OBJECT  #if JS_HAS_FILE_OBJECT
90  #include "jsfile.h"  #include "jsfile.h"
# Line 92  Line 94 
94  #include "jsxml.h"  #include "jsxml.h"
95  #endif  #endif
96    
97    #include "jsatominlines.h"
98    
99  #ifdef HAVE_VA_LIST_AS_ARRAY  #ifdef HAVE_VA_LIST_AS_ARRAY
100  #define JS_ADDRESSOF_VA_LIST(ap) ((va_list *)(ap))  #define JS_ADDRESSOF_VA_LIST(ap) ((va_list *)(ap))
101  #else  #else
# Line 272  Line 276 
276              if (!obj)              if (!obj)
277                  return JS_FALSE;                  return JS_FALSE;
278              *sp = OBJECT_TO_JSVAL(obj);              *sp = OBJECT_TO_JSVAL(obj);
279              *va_arg(ap, JSFunction **) = (JSFunction *) JS_GetPrivate(cx, obj);              *va_arg(ap, JSFunction **) = GET_FUNCTION_PRIVATE(cx, obj);
280              break;              break;
281            case 'v':            case 'v':
282              *va_arg(ap, jsval *) = *sp;              *va_arg(ap, jsval *) = *sp;
# Line 446  Line 450 
450              goto out;              goto out;
451          mpp = &map->next;          mpp = &map->next;
452      }      }
453      map = (JSArgumentFormatMap *) JS_malloc(cx, sizeof *map);      map = (JSArgumentFormatMap *) cx->malloc(sizeof *map);
454      if (!map)      if (!map)
455          return JS_FALSE;          return JS_FALSE;
456      map->format = format;      map->format = format;
# Line 469  Line 473 
473      while ((map = *mpp) != NULL) {      while ((map = *mpp) != NULL) {
474          if (map->length == length && !strcmp(map->format, format)) {          if (map->length == length && !strcmp(map->format, format)) {
475              *mpp = map->next;              *mpp = map->next;
476              JS_free(cx, map);              cx->free(map);
477              return;              return;
478          }          }
479          mpp = &map->next;          mpp = &map->next;
# Line 568  Line 572 
572  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
573  JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)  JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
574  {  {
     JSTempValueRooter tvr;  
   
575      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
576      JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);  
577      *dp = js_ValueToNumber(cx, &tvr.u.value);      JSAutoTempValueRooter tvr(cx, v);
578      JS_POP_TEMP_ROOT(cx, &tvr);      *dp = js_ValueToNumber(cx, tvr.addr());
579      return !JSVAL_IS_NULL(tvr.u.value);      return !JSVAL_IS_NULL(tvr.value());
580  }  }
581    
582  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
583  JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)  JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
584  {  {
     JSTempValueRooter tvr;  
   
585      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
586      JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);  
587      *ip = js_ValueToECMAInt32(cx, &tvr.u.value);      JSAutoTempValueRooter tvr(cx, v);
588      JS_POP_TEMP_ROOT(cx, &tvr);      *ip = js_ValueToECMAInt32(cx, tvr.addr());
589      return !JSVAL_IS_NULL(tvr.u.value);      return !JSVAL_IS_NULL(tvr.value());
590  }  }
591    
592  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
593  JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip)  JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip)
594  {  {
     JSTempValueRooter tvr;  
   
595      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
596      JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);  
597      *ip = js_ValueToECMAUint32(cx, &tvr.u.value);      JSAutoTempValueRooter tvr(cx, v);
598      JS_POP_TEMP_ROOT(cx, &tvr);      *ip = js_ValueToECMAUint32(cx, tvr.addr());
599      return !JSVAL_IS_NULL(tvr.u.value);      return !JSVAL_IS_NULL(tvr.value());
600  }  }
601    
602  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
603  JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip)  JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
604  {  {
     JSTempValueRooter tvr;  
   
605      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
606      JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);  
607      *ip = js_ValueToInt32(cx, &tvr.u.value);      JSAutoTempValueRooter tvr(cx, v);
608      JS_POP_TEMP_ROOT(cx, &tvr);      *ip = js_ValueToInt32(cx, tvr.addr());
609      return !JSVAL_IS_NULL(tvr.u.value);      return !JSVAL_IS_NULL(tvr.value());
610  }  }
611    
612  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
613  JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)  JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)
614  {  {
     JSTempValueRooter tvr;  
   
615      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
616      JS_PUSH_SINGLE_TEMP_ROOT(cx, v, &tvr);  
617      *ip = js_ValueToUint16(cx, &tvr.u.value);      JSAutoTempValueRooter tvr(cx, v);
618      JS_POP_TEMP_ROOT(cx, &tvr);      *ip = js_ValueToUint16(cx, tvr.addr());
619      return !JSVAL_IS_NULL(tvr.u.value);      return !JSVAL_IS_NULL(tvr.value());
620  }  }
621    
622  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 638  Line 632 
632  {  {
633      JSType type;      JSType type;
634      JSObject *obj;      JSObject *obj;
635      JSObjectOps *ops;      const JSObjectOps *ops;
636      JSClass *clasp;      JSClass *clasp;
637    
638      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
# Line 671  Line 665 
665  #ifdef NARCISSUS  #ifdef NARCISSUS
666                      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);                      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
667    
668                      if (!OBJ_GET_PROPERTY(cx, obj,                      if (!obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.__call__Atom),
                                           ATOM_TO_JSID(cx->runtime->atomState  
                                                        .__call__Atom),  
669                                            &v)) {                                            &v)) {
670                          JS_ClearPendingException(cx);                          JS_ClearPendingException(cx);
671                      } else if (VALUE_IS_FUNCTION(cx, v)) {                      } else if (VALUE_IS_FUNCTION(cx, v)) {
# Line 703  Line 695 
695      return JS_TYPE_STR(type);      return JS_TYPE_STR(type);
696  }  }
697    
698    JS_PUBLIC_API(JSBool)
699    JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2)
700    {
701        return js_StrictlyEqual(cx, v1, v2);
702    }
703    
704    JS_PUBLIC_API(JSBool)
705    JS_SameValue(JSContext *cx, jsval v1, jsval v2)
706    {
707        return js_SameValue(v1, v2, cx);
708    }
709    
710  /************************************************************************/  /************************************************************************/
711    
712  /*  /*
# Line 757  Line 761 
761          JS_ASSERT(JSVAL_FALSE == BOOLEAN_TO_JSVAL(JS_FALSE));          JS_ASSERT(JSVAL_FALSE == BOOLEAN_TO_JSVAL(JS_FALSE));
762          JS_ASSERT(JSVAL_TRUE == BOOLEAN_TO_JSVAL(JS_TRUE));          JS_ASSERT(JSVAL_TRUE == BOOLEAN_TO_JSVAL(JS_TRUE));
763    
764          JS_ASSERT(JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_VOID) == 2);          JS_ASSERT(JSVAL_TO_SPECIAL(JSVAL_VOID) == 2);
765          JS_ASSERT(JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_HOLE) == (2 | (JSVAL_HOLE_FLAG >> JSVAL_TAGBITS)));          JS_ASSERT(JSVAL_TO_SPECIAL(JSVAL_HOLE) == (2 | (JSVAL_HOLE_FLAG >> JSVAL_TAGBITS)));
766          JS_ASSERT(JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_ARETURN) == 8);          JS_ASSERT(JSVAL_TO_SPECIAL(JSVAL_ARETURN) == 8);
767    
768          js_NewRuntimeWasCalled = JS_TRUE;          js_NewRuntimeWasCalled = JS_TRUE;
769      }      }
770  #endif /* DEBUG */  #endif /* DEBUG */
771    
772      rt = (JSRuntime *) malloc(sizeof(JSRuntime));      rt = (JSRuntime *) js_malloc(sizeof(JSRuntime));
773      if (!rt)      if (!rt)
774          return NULL;          return NULL;
775    
# Line 809  Line 813 
813      rt->debuggerLock = JS_NEW_LOCK();      rt->debuggerLock = JS_NEW_LOCK();
814      if (!rt->debuggerLock)      if (!rt->debuggerLock)
815          goto bad;          goto bad;
816        rt->deallocatorThread = new JSBackgroundThread();
817        if (!rt->deallocatorThread || !rt->deallocatorThread->init())
818            goto bad;
819  #endif  #endif
820      if (!js_InitPropertyTree(rt))      if (!js_InitPropertyTree(rt))
821          goto bad;          goto bad;
# Line 823  Line 830 
830  }  }
831    
832  JS_PUBLIC_API(void)  JS_PUBLIC_API(void)
833    JS_CommenceRuntimeShutDown(JSRuntime *rt)
834    {
835        rt->gcFlushCodeCaches = true;
836    }
837    
838    JS_PUBLIC_API(void)
839  JS_DestroyRuntime(JSRuntime *rt)  JS_DestroyRuntime(JSRuntime *rt)
840  {  {
841  #ifdef DEBUG  #ifdef DEBUG
# Line 847  Line 860 
860      js_FinishAtomState(rt);      js_FinishAtomState(rt);
861    
862      /*      /*
      * Free unit string storage only after all strings have been finalized, so  
      * that js_FinalizeString can detect unit strings and avoid calling free  
      * on their chars storage.  
      */  
     js_FinishUnitStrings(rt);  
   
     /*  
863       * Finish the deflated string cache after the last GC and after       * Finish the deflated string cache after the last GC and after
864       * calling js_FinishAtomState, which finalizes strings.       * calling js_FinishAtomState, which finalizes strings.
865       */       */
# Line 874  Line 880 
880          JS_DESTROY_CONDVAR(rt->titleSharingDone);          JS_DESTROY_CONDVAR(rt->titleSharingDone);
881      if (rt->debuggerLock)      if (rt->debuggerLock)
882          JS_DESTROY_LOCK(rt->debuggerLock);          JS_DESTROY_LOCK(rt->debuggerLock);
883        if (rt->deallocatorThread) {
884            rt->deallocatorThread->cancel();
885            delete rt->deallocatorThread;
886        }
887  #endif  #endif
888      js_FinishPropertyTree(rt);      js_FinishPropertyTree(rt);
889      free(rt);      js_free(rt);
890  }  }
891    
892  JS_PUBLIC_API(void)  JS_PUBLIC_API(void)
893  JS_ShutDown(void)  JS_ShutDown(void)
894  {  {
895    #ifdef MOZ_TRACEVIS
896        JS_StopTraceVis();
897    #endif
898    
899  #ifdef JS_OPMETER  #ifdef JS_OPMETER
900      extern void js_DumpOpMeters();      extern void js_DumpOpMeters();
901    
# Line 911  Line 925 
925  JS_BeginRequest(JSContext *cx)  JS_BeginRequest(JSContext *cx)
926  {  {
927  #ifdef JS_THREADSAFE  #ifdef JS_THREADSAFE
     JSRuntime *rt;  
   
928      JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread));      JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread));
929      if (!cx->requestDepth) {      if (!cx->requestDepth) {
930          JS_ASSERT(cx->gcLocalFreeLists == &js_GCEmptyFreeListSet);          JSRuntime *rt = cx->runtime;
   
         /* Wait until the GC is finished. */  
         rt = cx->runtime;  
931          JS_LOCK_GC(rt);          JS_LOCK_GC(rt);
932    
933            /* Wait until the GC is finished. */
934          if (rt->gcThread != cx->thread) {          if (rt->gcThread != cx->thread) {
935              while (rt->gcLevel > 0)              while (rt->gcLevel > 0)
936                  JS_AWAIT_GC_DONE(rt);                  JS_AWAIT_GC_DONE(rt);
# Line 958  Line 968 
968          cx->outstandingRequests--;          cx->outstandingRequests--;
969    
970          js_ShareWaitingTitles(cx);          js_ShareWaitingTitles(cx);
         js_RevokeGCLocalFreeLists(cx);  
971    
972          /* Give the GC a chance to run if this was the last request running. */          /* Give the GC a chance to run if this was the last request running. */
973          JS_ASSERT(rt->requestCount > 0);          JS_ASSERT(rt->requestCount > 0);
# Line 1160  Line 1169 
1169  JS_PUBLIC_API(uint32)  JS_PUBLIC_API(uint32)
1170  JS_SetOptions(JSContext *cx, uint32 options)  JS_SetOptions(JSContext *cx, uint32 options)
1171  {  {
1172        JS_LOCK_GC(cx->runtime);
1173      uint32 oldopts = cx->options;      uint32 oldopts = cx->options;
1174      cx->options = options;      cx->options = options;
1175      js_SyncOptionsToVersion(cx);      js_SyncOptionsToVersion(cx);
1176        cx->updateJITEnabled();
1177        JS_UNLOCK_GC(cx->runtime);
1178      return oldopts;      return oldopts;
1179  }  }
1180    
1181  JS_PUBLIC_API(uint32)  JS_PUBLIC_API(uint32)
1182  JS_ToggleOptions(JSContext *cx, uint32 options)  JS_ToggleOptions(JSContext *cx, uint32 options)
1183  {  {
1184        JS_LOCK_GC(cx->runtime);
1185      uint32 oldopts = cx->options;      uint32 oldopts = cx->options;
1186      cx->options ^= options;      cx->options ^= options;
1187      js_SyncOptionsToVersion(cx);      js_SyncOptionsToVersion(cx);
1188        cx->updateJITEnabled();
1189        JS_UNLOCK_GC(cx->runtime);
1190      return oldopts;      return oldopts;
1191  }  }
1192    
# Line 1191  Line 1206 
1206  JS_PUBLIC_API(void)  JS_PUBLIC_API(void)
1207  JS_SetGlobalObject(JSContext *cx, JSObject *obj)  JS_SetGlobalObject(JSContext *cx, JSObject *obj)
1208  {  {
1209        CHECK_REQUEST(cx);
1210      cx->globalObject = obj;      cx->globalObject = obj;
1211    
1212  #if JS_HAS_XML_SUPPORT  #if JS_HAS_XML_SUPPORT
# Line 1270  Line 1286 
1286              fun_proto = NULL;              fun_proto = NULL;
1287              goto out;              goto out;
1288          }          }
1289          OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(CLASS_ATOM(cx, Function)),          obj->defineProperty(cx, ATOM_TO_JSID(CLASS_ATOM(cx, Function)),
1290                              OBJECT_TO_JSVAL(ctor), 0, 0, 0, NULL);                              OBJECT_TO_JSVAL(ctor), 0, 0, 0);
1291      }      }
1292    
1293      /* Initialize the object class next so Object.prototype works. */      /* Initialize the object class next so Object.prototype works. */
# Line 1316  Line 1332 
1332    
1333      /* Define a top-level property 'undefined' with the undefined value. */      /* Define a top-level property 'undefined' with the undefined value. */
1334      atom = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];      atom = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
1335      if (!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), JSVAL_VOID,      if (!obj->defineProperty(cx, ATOM_TO_JSID(atom), JSVAL_VOID,
1336                               JS_PropertyStub, JS_PropertyStub, JSPROP_PERMANENT,                               JS_PropertyStub, JS_PropertyStub, JSPROP_PERMANENT)) {
                              NULL)) {  
1337          return JS_FALSE;          return JS_FALSE;
1338      }      }
1339    
# Line 1523  Line 1538 
1538      atom = rt->atomState.typeAtoms[JSTYPE_VOID];      atom = rt->atomState.typeAtoms[JSTYPE_VOID];
1539      if (idstr == ATOM_TO_STRING(atom)) {      if (idstr == ATOM_TO_STRING(atom)) {
1540          *resolved = JS_TRUE;          *resolved = JS_TRUE;
1541          return OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), JSVAL_VOID,          return obj->defineProperty(cx, ATOM_TO_JSID(atom), JSVAL_VOID,
1542                                     JS_PropertyStub, JS_PropertyStub,                                     JS_PropertyStub, JS_PropertyStub,
1543                                     JSPROP_PERMANENT, NULL);                                     JSPROP_PERMANENT);
1544      }      }
1545    
1546      /* Try for class constructors/prototypes named by well-known atoms. */      /* Try for class constructors/prototypes named by well-known atoms. */
# Line 1600  Line 1615 
1615      JS_ASSERT(OBJ_IS_NATIVE(obj));      JS_ASSERT(OBJ_IS_NATIVE(obj));
1616      JS_LOCK_OBJ(cx, obj);      JS_LOCK_OBJ(cx, obj);
1617      scope = OBJ_SCOPE(obj);      scope = OBJ_SCOPE(obj);
1618      sprop = SCOPE_GET_PROPERTY(scope, ATOM_TO_JSID(atom));      sprop = scope->lookup(ATOM_TO_JSID(atom));
1619      JS_UNLOCK_SCOPE(cx, scope);      JS_UNLOCK_SCOPE(cx, scope);
1620      return sprop != NULL;      return sprop != NULL;
1621  }  }
# Line 1618  Line 1633 
1633      /* Check whether we need to bind 'undefined' and define it if so. */      /* Check whether we need to bind 'undefined' and define it if so. */
1634      atom = rt->atomState.typeAtoms[JSTYPE_VOID];      atom = rt->atomState.typeAtoms[JSTYPE_VOID];
1635      if (!AlreadyHasOwnProperty(cx, obj, atom) &&      if (!AlreadyHasOwnProperty(cx, obj, atom) &&
1636          !OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), JSVAL_VOID,          !obj->defineProperty(cx, ATOM_TO_JSID(atom), JSVAL_VOID,
1637                               JS_PropertyStub, JS_PropertyStub, JSPROP_PERMANENT,                               JS_PropertyStub, JS_PropertyStub, JSPROP_PERMANENT)) {
                              NULL)) {  
1638          return JS_FALSE;          return JS_FALSE;
1639      }      }
1640    
# Line 1642  Line 1656 
1656      JSIdArray *ida;      JSIdArray *ida;
1657    
1658      ida = (JSIdArray *)      ida = (JSIdArray *)
1659            JS_malloc(cx, offsetof(JSIdArray, vector) + length * sizeof(jsval));          cx->malloc(offsetof(JSIdArray, vector) + length * sizeof(jsval));
1660      if (ida)      if (ida)
1661          ida->length = length;          ida->length = length;
1662      return ida;      return ida;
# Line 1820  Line 1834 
1834  JS_PUBLIC_API(void *)  JS_PUBLIC_API(void *)
1835  JS_malloc(JSContext *cx, size_t nbytes)  JS_malloc(JSContext *cx, size_t nbytes)
1836  {  {
1837      void *p;      return cx->malloc(nbytes);
   
     JS_ASSERT(nbytes != 0);  
     if (nbytes == 0)  
         nbytes = 1;  
   
     p = malloc(nbytes);  
     if (!p) {  
         JS_ReportOutOfMemory(cx);  
         return NULL;  
     }  
     js_UpdateMallocCounter(cx, nbytes);  
   
     return p;  
1838  }  }
1839    
1840  JS_PUBLIC_API(void *)  JS_PUBLIC_API(void *)
1841  JS_realloc(JSContext *cx, void *p, size_t nbytes)  JS_realloc(JSContext *cx, void *p, size_t nbytes)
1842  {  {
1843      void *orig = p;      return cx->realloc(p, nbytes);
     p = realloc(p, nbytes);  
     if (!p) {  
         JS_ReportOutOfMemory(cx);  
         return NULL;  
     }  
     if (!orig)  
         js_UpdateMallocCounter(cx, nbytes);  
     return p;  
1844  }  }
1845    
1846  JS_PUBLIC_API(void)  JS_PUBLIC_API(void)
1847  JS_free(JSContext *cx, void *p)  JS_free(JSContext *cx, void *p)
1848  {  {
1849      if (p)      return cx->free(p);
         free(p);  
1850  }  }
1851    
1852  JS_PUBLIC_API(char *)  JS_PUBLIC_API(char *)
# Line 1864  Line 1856 
1856      void *p;      void *p;
1857    
1858      n = strlen(s) + 1;      n = strlen(s) + 1;
1859      p = JS_malloc(cx, n);      p = cx->malloc(n);
1860      if (!p)      if (!p)
1861          return NULL;          return NULL;
1862      return (char *)memcpy(p, s, n);      return (char *)memcpy(p, s, n);
# Line 2060  Line 2052 
2052          name = clasp->name;          name = clasp->name;
2053  #ifdef HAVE_XPCONNECT  #ifdef HAVE_XPCONNECT
2054          if (clasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {          if (clasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
2055              jsval privateValue = STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE);              void *privateThing = obj->getPrivate();
2056                if (privateThing) {
             JS_ASSERT(clasp->flags & JSCLASS_HAS_PRIVATE);  
             if (!JSVAL_IS_VOID(privateValue)) {  
                 void  *privateThing = JSVAL_TO_PRIVATE(privateValue);  
2057                  const char *xpcClassName = GetXPCObjectClassName(privateThing);                  const char *xpcClassName = GetXPCObjectClassName(privateThing);
   
2058                  if (xpcClassName)                  if (xpcClassName)
2059                      name = xpcClassName;                      name = xpcClassName;
2060              }              }
# Line 2076  Line 2064 
2064        }        }
2065    
2066        case JSTRACE_STRING:        case JSTRACE_STRING:
2067          name = JSSTRING_IS_DEPENDENT((JSString *)thing)          name = ((JSString *)thing)->isDependent()
2068                 ? "substring"                 ? "substring"
2069                 : "string";                 : "string";
2070          break;          break;
# Line 2113  Line 2101 
2101              JSObject  *obj = (JSObject *)thing;              JSObject  *obj = (JSObject *)thing;
2102              JSClass *clasp = STOBJ_GET_CLASS(obj);              JSClass *clasp = STOBJ_GET_CLASS(obj);
2103              if (clasp == &js_FunctionClass) {              if (clasp == &js_FunctionClass) {
2104                  JSFunction *fun = (JSFunction *)                  JSFunction *fun = GET_FUNCTION_PRIVATE(trc->context, obj);
                                   JS_GetPrivate(trc->context, obj);  
   
2105                  if (!fun) {                  if (!fun) {
2106                      JS_snprintf(buf, bufsize, "<newborn>");                      JS_snprintf(buf, bufsize, "<newborn>");
2107                  } else if (FUN_OBJECT(fun) != obj) {                  } else if (FUN_OBJECT(fun) != obj) {
# Line 2126  Line 2112 
2112                                              ATOM_TO_STRING(fun->atom), 0);                                              ATOM_TO_STRING(fun->atom), 0);
2113                  }                  }
2114              } else if (clasp->flags & JSCLASS_HAS_PRIVATE) {              } else if (clasp->flags & JSCLASS_HAS_PRIVATE) {
2115                  jsval     privateValue = STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE);                  JS_snprintf(buf, bufsize, "%p", obj->getPrivate());
                 void      *privateThing = JSVAL_IS_VOID(privateValue)  
                                           ? NULL  
                                           : JSVAL_TO_PRIVATE(privateValue);  
   
                 JS_snprintf(buf, bufsize, "%p", privateThing);  
2116              } else {              } else {
2117                  JS_snprintf(buf, bufsize, "<no private>");                  JS_snprintf(buf, bufsize, "<no private>");
2118              }              }
# Line 2249  Line 2230 
2230    
2231      edgeNameSize = strlen(edgeName) + 1;      edgeNameSize = strlen(edgeName) + 1;
2232      node = (JSHeapDumpNode *)      node = (JSHeapDumpNode *)
2233          JS_malloc(cx, offsetof(JSHeapDumpNode, edgeName) + edgeNameSize);          cx->malloc(offsetof(JSHeapDumpNode, edgeName) + edgeNameSize);
2234      if (!node) {      if (!node) {
2235          dtrc->ok = JS_FALSE;          dtrc->ok = JS_FALSE;
2236          return;          return;
# Line 2401  Line 2382 
2382          for (;;) {          for (;;) {
2383              next = node->next;              next = node->next;
2384              parent = node->parent;              parent = node->parent;
2385              JS_free(cx, node);              cx->free(node);
2386              node = next;              node = next;
2387              if (node)              if (node)
2388                  break;                  break;
# Line 2569  Line 2550 
2550        default:        default:
2551          JS_ASSERT(key == JSGC_TRIGGER_FACTOR);          JS_ASSERT(key == JSGC_TRIGGER_FACTOR);
2552          JS_ASSERT(value >= 100);          JS_ASSERT(value >= 100);
2553          rt->gcTriggerFactor = value;          rt->setGCTriggerFactor(value);
2554          return;          return;
2555      }      }
2556  }  }
# Line 2614  Line 2595 
2595  #endif  #endif
2596  }  }
2597    
2598    JS_PUBLIC_API(void)
2599    JS_FlushCaches(JSContext *cx)
2600    {
2601    #ifdef JS_TRACER
2602        js_FlushJITCache(cx);
2603    #endif
2604    }
2605    
2606  JS_PUBLIC_API(intN)  JS_PUBLIC_API(intN)
2607  JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer)  JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer)
2608  {  {
# Line 2634  Line 2623 
2623      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
2624      JS_ASSERT((uintN) type < (uintN) (GCX_NTYPES - GCX_EXTERNAL_STRING));      JS_ASSERT((uintN) type < (uintN) (GCX_NTYPES - GCX_EXTERNAL_STRING));
2625    
2626      str = (JSString *) js_NewGCThing(cx, (uintN) type + GCX_EXTERNAL_STRING,      str = js_NewGCString(cx, (uintN) type + GCX_EXTERNAL_STRING);
                                      sizeof(JSString));  
2627      if (!str)      if (!str)
2628          return NULL;          return NULL;
2629      JSFLATSTR_INIT(str, chars, length);      str->initFlat(chars, length);
2630        cx->updateMallocCounter((length + 1) * sizeof(jschar));
2631      return str;      return str;
2632  }  }
2633    
2634  JS_PUBLIC_API(intN)  JS_PUBLIC_API(intN)
2635  JS_GetExternalStringGCType(JSRuntime *rt, JSString *str)  JS_GetExternalStringGCType(JSRuntime *rt, JSString *str)
2636  {  {
2637        /*
2638         * No need to test this in js_GetExternalStringGCType, which asserts its
2639         * inverse instead of wasting cycles on testing a condition we can ensure
2640         * by auditing in-VM calls to the js_... helper.
2641         */
2642        if (JSString::isStatic(str))
2643            return -1;
2644    
2645      return js_GetExternalStringGCType(str);      return js_GetExternalStringGCType(str);
2646  }  }
2647    
# Line 2669  Line 2666 
2666  JS_PUBLIC_API(void)  JS_PUBLIC_API(void)
2667  JS_DestroyIdArray(JSContext *cx, JSIdArray *ida)  JS_DestroyIdArray(JSContext *cx, JSIdArray *ida)
2668  {  {
2669      JS_free(cx, ida);      cx->free(ida);
2670  }  }
2671    
2672  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
2673  JS_ValueToId(JSContext *cx, jsval v, jsid *idp)  JS_ValueToId(JSContext *cx, jsval v, jsid *idp)
2674  {  {
2675      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
2676      if (JSVAL_IS_INT(v))      if (JSVAL_IS_INT(v)) {
2677          *idp = INT_JSVAL_TO_JSID(v);          *idp = INT_JSVAL_TO_JSID(v);
2678            return JS_TRUE;
2679        }
2680    
2681  #if JS_HAS_XML_SUPPORT  #if JS_HAS_XML_SUPPORT
2682      else if (!JSVAL_IS_PRIMITIVE(v))      if (!JSVAL_IS_PRIMITIVE(v)) {
2683          *idp = OBJECT_JSVAL_TO_JSID(v);          JSClass *clasp = JSVAL_TO_OBJECT(v)->getClass();
2684            if (JS_UNLIKELY(clasp == &js_QNameClass.base ||
2685                            clasp == &js_AttributeNameClass ||
2686                            clasp == &js_AnyNameClass)) {
2687                *idp = OBJECT_JSVAL_TO_JSID(v);
2688                return JS_TRUE;
2689            }
2690        }
2691  #endif  #endif
2692      else  
2693          return js_ValueToStringId(cx, v, idp);      return js_ValueToStringId(cx, v, idp);
     return JS_TRUE;  
2694  }  }
2695    
2696  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 2739  Line 2745 
2745  JS_PUBLIC_API(JSClass *)  JS_PUBLIC_API(JSClass *)
2746  JS_GetClass(JSContext *cx, JSObject *obj)  JS_GetClass(JSContext *cx, JSObject *obj)
2747  {  {
2748      return OBJ_GET_CLASS(cx, obj);      return obj->getClass();
2749  }  }
2750  #else  #else
2751  JS_PUBLIC_API(JSClass *)  JS_PUBLIC_API(JSClass *)
2752  JS_GetClass(JSObject *obj)  JS_GetClass(JSObject *obj)
2753  {  {
2754      return LOCKED_OBJ_GET_CLASS(obj);      return obj->getClass();
2755  }  }
2756  #endif  #endif
2757    
# Line 2780  Line 2786 
2786  JS_PUBLIC_API(void *)  JS_PUBLIC_API(void *)
2787  JS_GetPrivate(JSContext *cx, JSObject *obj)  JS_GetPrivate(JSContext *cx, JSObject *obj)
2788  {  {
2789      jsval v;      return obj->getPrivate();
   
     JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE);  
     v = obj->fslots[JSSLOT_PRIVATE];  
     if (!JSVAL_IS_INT(v))  
         return NULL;  
     return JSVAL_TO_PRIVATE(v);  
2790  }  }
2791    
2792  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
2793  JS_SetPrivate(JSContext *cx, JSObject *obj, void *data)  JS_SetPrivate(JSContext *cx, JSObject *obj, void *data)
2794  {  {
2795      JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE);      obj->setPrivate(data);
2796      obj->fslots[JSSLOT_PRIVATE] = PRIVATE_TO_JSVAL(data);      return true;
     return JS_TRUE;  
2797  }  }
2798    
2799  JS_PUBLIC_API(void *)  JS_PUBLIC_API(void *)
# Line 2803  Line 2802 
2802  {  {
2803      if (!JS_InstanceOf(cx, obj, clasp, argv))      if (!JS_InstanceOf(cx, obj, clasp, argv))
2804          return NULL;          return NULL;
2805      return JS_GetPrivate(cx, obj);      return obj->getPrivate();
2806  }  }
2807    
2808  JS_PUBLIC_API(JSObject *)  JS_PUBLIC_API(JSObject *)
# Line 2852  Line 2851 
2851      {      {
2852          JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);          JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
2853    
2854          if (!OBJ_GET_PROPERTY(cx, proto,          if (!proto->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.constructorAtom), &cval))
                               ATOM_TO_JSID(cx->runtime->atomState.constructorAtom),  
                               &cval)) {  
2855              return NULL;              return NULL;
         }  
2856      }      }
2857      if (!VALUE_IS_FUNCTION(cx, cval)) {      if (!VALUE_IS_FUNCTION(cx, cval)) {
2858          JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR,          JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR,
# Line 2880  Line 2876 
2876      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
2877      if (!clasp)      if (!clasp)
2878          clasp = &js_ObjectClass;    /* default class is Object */          clasp = &js_ObjectClass;    /* default class is Object */
2879      return js_NewObject(cx, clasp, proto, parent, 0);      return js_NewObject(cx, clasp, proto, parent);
2880  }  }
2881    
2882  JS_PUBLIC_API(JSObject *)  JS_PUBLIC_API(JSObject *)
# Line 2890  Line 2886 
2886      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
2887      if (!clasp)      if (!clasp)
2888          clasp = &js_ObjectClass;    /* default class is Object */          clasp = &js_ObjectClass;    /* default class is Object */
2889      return js_NewObjectWithGivenProto(cx, clasp, proto, parent, 0);      return js_NewObjectWithGivenProto(cx, clasp, proto, parent);
2890  }  }
2891    
2892  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 2924  Line 2920 
2920  #endif  #endif
2921    
2922      /* Nothing to do if obj's scope is already sealed. */      /* Nothing to do if obj's scope is already sealed. */
2923      if (SCOPE_IS_SEALED(scope))      if (scope->sealed())
2924          return JS_TRUE;          return JS_TRUE;
2925    
2926      /* XXX Enumerate lazy properties now, as they can't be added later. */      /* XXX Enumerate lazy properties now, as they can't be added later. */
# Line 2937  Line 2933 
2933      JS_LOCK_OBJ(cx, obj);      JS_LOCK_OBJ(cx, obj);
2934      scope = js_GetMutableScope(cx, obj);      scope = js_GetMutableScope(cx, obj);
2935      if (scope) {      if (scope) {
2936          SCOPE_SET_SEALED(scope);          scope->sealingShapeChange(cx);
2937          js_MakeScopeShapeUnique(cx, scope);          scope->setSealed();
2938      }      }
2939      JS_UNLOCK_OBJ(cx, obj);      JS_UNLOCK_OBJ(cx, obj);
2940      if (!scope)      if (!scope)
# Line 2990  Line 2986 
2986          return !!js_DefineNativeProperty(cx, obj, id, value, getter, setter,          return !!js_DefineNativeProperty(cx, obj, id, value, getter, setter,
2987                                           attrs, flags, tinyid, NULL);                                           attrs, flags, tinyid, NULL);
2988      }      }
2989      return OBJ_DEFINE_PROPERTY(cx, obj, id, value, getter, setter, attrs,      return obj->defineProperty(cx, id, value, getter, setter, attrs);
                                NULL);    
2990  }  }
2991    
2992  static JSBool  static JSBool
# Line 3035  Line 3030 
3030                                           getter, setter, attrs, flags, tinyid,                                           getter, setter, attrs, flags, tinyid,
3031                                           NULL);                                           NULL);
3032      }      }
3033      return OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), value,      return obj->defineProperty(cx, ATOM_TO_JSID(atom), value, getter, setter, attrs);
                                getter, setter, attrs, NULL);  
3034  }  }
3035    
3036  JS_PUBLIC_API(JSObject *)  JS_PUBLIC_API(JSObject *)
# Line 3048  Line 3042 
3042      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
3043      if (!clasp)      if (!clasp)
3044          clasp = &js_ObjectClass;    /* default class is Object */          clasp = &js_ObjectClass;    /* default class is Object */
3045      nobj = js_NewObject(cx, clasp, proto, obj, 0);      nobj = js_NewObject(cx, clasp, proto, obj);
3046      if (!nobj)      if (!nobj)
3047          return NULL;          return NULL;
3048      if (!DefineProperty(cx, obj, name, OBJECT_TO_JSVAL(nobj), NULL, NULL, attrs,      if (!DefineProperty(cx, obj, name, OBJECT_TO_JSVAL(nobj), NULL, NULL, attrs,
3049                          0, 0)) {                          0, 0)) {
         cx->weakRoots.newborn[GCX_OBJECT] = NULL;  
3050          return NULL;          return NULL;
3051      }      }
3052      return nobj;      return nobj;
# Line 3129  Line 3122 
3122                     JSObject **objp, JSProperty **propp)                     JSObject **objp, JSProperty **propp)
3123  {  {
3124      JSAutoResolveFlags rf(cx, flags);      JSAutoResolveFlags rf(cx, flags);
3125      CHECK_FOR_STRING_INDEX(id);      id = js_CheckForStringIndex(id);
3126      return OBJ_LOOKUP_PROPERTY(cx, obj, id, objp, propp);      return obj->lookupProperty(cx, id, objp, propp);
3127  }  }
3128    
3129  static JSBool  static JSBool
# Line 3176  Line 3169 
3169          return JS_FALSE;          return JS_FALSE;
3170      }      }
3171      if (obj2 != obj || !OBJ_IS_NATIVE(obj)) {      if (obj2 != obj || !OBJ_IS_NATIVE(obj)) {
3172          OBJ_DROP_PROPERTY(cx, obj2, prop);          obj2->dropProperty(cx, prop);
3173          JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,          JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,
3174                               alias, name, OBJ_GET_CLASS(cx, obj2)->name);                               alias, name, OBJ_GET_CLASS(cx, obj2)->name);
3175          return JS_FALSE;          return JS_FALSE;
# Line 3192  Line 3185 
3185                                     sprop->shortid)                                     sprop->shortid)
3186                != NULL);                != NULL);
3187      }      }
3188      OBJ_DROP_PROPERTY(cx, obj, prop);      obj->dropProperty(cx, prop);
3189      return ok;      return ok;
3190  }  }
3191    
# Line 3220  Line 3213 
3213          /* XXX bad API: no way to return "defined but value unknown" */          /* XXX bad API: no way to return "defined but value unknown" */
3214          *vp = JSVAL_TRUE;          *vp = JSVAL_TRUE;
3215      }      }
3216      OBJ_DROP_PROPERTY(cx, obj2, prop);      obj2->dropProperty(cx, prop);
3217      return ok;      return ok;
3218  }  }
3219    
# Line 3242  Line 3235 
3235          desc->setter = NULL;          desc->setter = NULL;
3236          desc->value = JSVAL_VOID;          desc->value = JSVAL_VOID;
3237          if (prop)          if (prop)
3238              OBJ_DROP_PROPERTY(cx, obj2, prop);              obj2->dropProperty(cx, prop);
3239          return JS_TRUE;          return JS_TRUE;
3240      }      }
3241    
3242      desc->obj = obj2;      desc->obj = obj2;
3243    
3244      ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &desc->attrs);      ok = obj2->getAttributes(cx, id, prop, &desc->attrs);
3245      if (ok) {      if (ok) {
3246          if (OBJ_IS_NATIVE(obj2)) {          if (OBJ_IS_NATIVE(obj2)) {
3247              JSScopeProperty *sprop = (JSScopeProperty *) prop;              JSScopeProperty *sprop = (JSScopeProperty *) prop;
# Line 3264  Line 3257 
3257              desc->value = JSVAL_VOID;              desc->value = JSVAL_VOID;
3258          }          }
3259      }      }
3260      OBJ_DROP_PROPERTY(cx, obj2, prop);      obj2->dropProperty(cx, prop);
3261      return ok;      return ok;
3262  }  }
3263    
# Line 3309  Line 3302 
3302      if (!prop || obj != obj2) {      if (!prop || obj != obj2) {
3303          *foundp = JS_FALSE;          *foundp = JS_FALSE;
3304          if (prop)          if (prop)
3305              OBJ_DROP_PROPERTY(cx, obj2, prop);              obj2->dropProperty(cx, prop);
3306          return JS_TRUE;          return JS_TRUE;
3307      }      }
3308    
3309      *foundp = JS_TRUE;      *foundp = JS_TRUE;
3310      ok = OBJ_SET_ATTRIBUTES(cx, obj, ATOM_TO_JSID(atom), prop, &attrs);      ok = obj->setAttributes(cx, ATOM_TO_JSID(atom), prop, &attrs);
3311      OBJ_DROP_PROPERTY(cx, obj, prop);      obj->dropProperty(cx, prop);
3312      return ok;      return ok;
3313  }  }
3314    
# Line 3391  Line 3384 
3384          }          }
3385          *foundp = (obj == obj2);          *foundp = (obj == obj2);
3386          if (prop)          if (prop)
3387              OBJ_DROP_PROPERTY(cx, obj2, prop);              obj2->dropProperty(cx, prop);
3388          return JS_TRUE;          return JS_TRUE;
3389      }      }
3390    
3391      JS_LOCK_OBJ(cx, obj);      JS_LOCK_OBJ(cx, obj);
3392      scope = OBJ_SCOPE(obj);      scope = OBJ_SCOPE(obj);
3393      *foundp = (scope->object == obj && SCOPE_GET_PROPERTY(scope, id));      *foundp = (scope->lookup(id) != NULL);
3394      JS_UNLOCK_SCOPE(cx, scope);      JS_UNLOCK_SCOPE(cx, scope);
3395      return JS_TRUE;      return JS_TRUE;
3396  }  }
# Line 3437  Line 3430 
3430      if (ok) {      if (ok) {
3431          *foundp = (prop != NULL);          *foundp = (prop != NULL);
3432          if (prop)          if (prop)
3433              OBJ_DROP_PROPERTY(cx, obj2, prop);              obj2->dropProperty(cx, prop);
3434      }      }
3435      return ok;      return ok;
3436  }  }
# Line 3456  Line 3449 
3449      if (ok) {      if (ok) {
3450         *foundp = (prop != NULL);         *foundp = (prop != NULL);
3451         if (prop)         if (prop)
3452             OBJ_DROP_PROPERTY(cx, obj2, prop);             obj2->dropProperty(cx, prop);
3453      }      }
3454      return ok;      return ok;
3455  }  }
# Line 3506  Line 3499 
3499      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
3500      ok = OBJ_IS_NATIVE(obj)      ok = OBJ_IS_NATIVE(obj)
3501           ? js_LookupPropertyWithFlags(cx, obj, id, flags, objp, &prop) >= 0           ? js_LookupPropertyWithFlags(cx, obj, id, flags, objp, &prop) >= 0
3502           : OBJ_LOOKUP_PROPERTY(cx, obj, id, objp, &prop);           : obj->lookupProperty(cx, id, objp, &prop);
3503      if (ok)      if (ok)
3504          ok = LookupResult(cx, obj, *objp, prop, vp);          ok = LookupResult(cx, obj, *objp, prop, vp);
3505      return ok;      return ok;
# Line 3532  Line 3525 
3525          return JS_FALSE;          return JS_FALSE;
3526    
3527      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
3528      return OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);      return obj->getProperty(cx, ATOM_TO_JSID(atom), vp);
3529  }  }
3530    
3531  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 3540  Line 3533 
3533  {  {
3534      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
3535      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
3536      return OBJ_GET_PROPERTY(cx, obj, id, vp);      return obj->getProperty(cx, id, vp);
3537  }  }
3538    
3539  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
3540  JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,  JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
3541                   jsval *vp)                   jsval *vp)
3542  {  {
     JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);  
   
3543      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
3544      if (!js_GetMethod(cx, obj, id, false, vp))      if (!js_GetMethod(cx, obj, id, false, vp))
3545          return JS_FALSE;          return JS_FALSE;
# Line 3580  Line 3571 
3571          return JS_FALSE;          return JS_FALSE;
3572    
3573      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);
3574      return OBJ_SET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);      return obj->setProperty(cx, ATOM_TO_JSID(atom), vp);
3575  }  }
3576    
3577  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 3588  Line 3579 
3579  {  {
3580      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
3581      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);
3582      return OBJ_SET_PROPERTY(cx, obj, id, vp);      return obj->setProperty(cx, id, vp);
3583  }  }
3584    
3585  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 3611  Line 3602 
3602          return JS_FALSE;          return JS_FALSE;
3603    
3604      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
3605      return OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), rval);      return obj->deleteProperty(cx, ATOM_TO_JSID(atom), rval);
3606  }  }
3607    
3608  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 3627  Line 3618 
3618  {  {
3619      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
3620      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
3621      return OBJ_DELETE_PROPERTY(cx, obj, id, rval);      return obj->deleteProperty(cx, id, rval);
3622  }  }
3623    
3624  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 3712  Line 3703 
3703      JSProperty *prop;      JSProperty *prop;
3704    
3705      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
3706      ok = LookupUCProperty(cx, obj, name, namelen,      ok = LookupUCProperty(cx, obj, name, namelen,
3707                            JSRESOLVE_QUALIFIED | JSRESOLVE_DETECTING,                            JSRESOLVE_QUALIFIED | JSRESOLVE_DETECTING,
3708                            &obj2, &prop);                            &obj2, &prop);
3709      if (ok) {      if (ok) {
3710          *vp = (prop != NULL);          *vp = (prop != NULL);
3711          if (prop)          if (prop)
3712              OBJ_DROP_PROPERTY(cx, obj2, prop);              obj2->dropProperty(cx, prop);
3713      }      }
3714      return ok;      return ok;
3715  }  }
# Line 3750  Line 3741 
3741          return JS_FALSE;          return JS_FALSE;
3742    
3743      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
3744      return OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);      return obj->getProperty(cx, ATOM_TO_JSID(atom), vp);
3745  }  }
3746    
3747  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 3766  Line 3757 
3757          return JS_FALSE;          return JS_FALSE;
3758    
3759      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);
3760      return OBJ_SET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);      return obj->setProperty(cx, ATOM_TO_JSID(atom), vp);
3761  }  }
3762    
3763  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 3782  Line 3773 
3773          return JS_FALSE;          return JS_FALSE;
3774    
3775      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
3776      return OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), rval);      return obj->deleteProperty(cx, ATOM_TO_JSID(atom), rval);
3777  }  }
3778    
3779  JS_PUBLIC_API(JSObject *)  JS_PUBLIC_API(JSObject *)
# Line 3796  Line 3787 
3787  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
3788  JS_IsArrayObject(JSContext *cx, JSObject *obj)  JS_IsArrayObject(JSContext *cx, JSObject *obj)
3789  {  {
3790      return OBJ_IS_ARRAY(cx, obj);      return OBJ_IS_ARRAY(cx, js_GetWrappedObject(cx, obj));
3791  }  }
3792    
3793  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 3827  Line 3818 
3818      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_DECLARING);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_DECLARING);
3819    
3820      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
3821      return OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSID(index), value,      return obj->defineProperty(cx, INT_TO_JSID(index), value, getter, setter, attrs);
                                getter, setter, attrs, NULL);  
3822  }  }
3823    
3824  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 3848  Line 3838 
3838      }      }
3839      if (obj2 != obj || !OBJ_IS_NATIVE(obj)) {      if (obj2 != obj || !OBJ_IS_NATIVE(obj)) {
3840          char numBuf[12];          char numBuf[12];
3841          OBJ_DROP_PROPERTY(cx, obj2, prop);          obj2->dropProperty(cx, prop);
3842          JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)alias);          JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)alias);
3843          JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,          JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,
3844                               numBuf, name, OBJ_GET_CLASS(cx, obj2)->name);                               numBuf, name, OBJ_GET_CLASS(cx, obj2)->name);
# Line 3860  Line 3850 
3850                                 sprop->attrs, sprop->flags | SPROP_IS_ALIAS,                                 sprop->attrs, sprop->flags | SPROP_IS_ALIAS,
3851                                 sprop->shortid)                                 sprop->shortid)
3852            != NULL);            != NULL);
3853      OBJ_DROP_PROPERTY(cx, obj, prop);      obj->dropProperty(cx, prop);
3854      return ok;      return ok;
3855  }  }
3856    
# Line 3885  Line 3875 
3875      if (ok) {      if (ok) {
3876          *foundp = (prop != NULL);          *foundp = (prop != NULL);
3877          if (prop)          if (prop)
3878              OBJ_DROP_PROPERTY(cx, obj2, prop);              obj2->dropProperty(cx, prop);
3879      }      }
3880      return ok;      return ok;
3881  }  }
# Line 3908  Line 3898 
3898      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
3899    
3900      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
3901      return OBJ_GET_PROPERTY(cx, obj, INT_TO_JSID(index), vp);      return obj->getProperty(cx, INT_TO_JSID(index), vp);
3902  }  }
3903    
3904  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 3917  Line 3907 
3907      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);
3908    
3909      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
3910      return OBJ_SET_PROPERTY(cx, obj, INT_TO_JSID(index), vp);      return obj->setProperty(cx, INT_TO_JSID(index), vp);
3911  }  }
3912    
3913  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 3934  Line 3924 
3924      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);      JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
3925    
3926      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
3927      return OBJ_DELETE_PROPERTY(cx, obj, INT_TO_JSID(index), rval);      return obj->deleteProperty(cx, INT_TO_JSID(index), rval);
3928  }  }
3929    
3930  JS_PUBLIC_API(void)  JS_PUBLIC_API(void)
# Line 3967  Line 3957 
3957    
3958      ida = NULL;      ida = NULL;
3959      iter_state = JSVAL_NULL;      iter_state = JSVAL_NULL;
3960        JSAutoEnumStateRooter tvr(cx, obj, &iter_state);
3961    
3962      /* Get the number of properties to enumerate. */      /* Get the number of properties to enumerate. */
3963      if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, &num_properties))      if (!obj->enumerate(cx, JSENUMERATE_INIT, &iter_state, &num_properties))
3964          goto error;          goto error;
3965      if (!JSVAL_IS_INT(num_properties)) {      if (!JSVAL_IS_INT(num_properties)) {
3966          JS_ASSERT(0);          JS_ASSERT(0);
# Line 3989  Line 3980 
3980      i = 0;      i = 0;
3981      vector = &ida->vector[0];      vector = &ida->vector[0];
3982      for (;;) {      for (;;) {
3983          if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_NEXT, &iter_state, &id))          if (!obj->enumerate(cx, JSENUMERATE_NEXT, &iter_state, &id))
3984              goto error;              goto error;
3985    
3986          /* No more jsid's to enumerate ? */          /* No more jsid's to enumerate ? */
# Line 4007  Line 3998 
3998      return SetIdArrayLength(cx, ida, i);      return SetIdArrayLength(cx, ida, i);
3999    
4000  error:  error:
4001      if (iter_state != JSVAL_NULL)      if (!JSVAL_IS_NULL(iter_state))
4002          OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0);          obj->enumerate(cx, JSENUMERATE_DESTROY, &iter_state, 0);
4003      if (ida)      if (ida)
4004          JS_DestroyIdArray(cx, ida);          JS_DestroyIdArray(cx, ida);
4005      return NULL;      return NULL;
# Line 4017  Line 4008 
4008  /*  /*
4009   * XXX reverse iterator for properties, unreverse and meld with jsinterp.c's   * XXX reverse iterator for properties, unreverse and meld with jsinterp.c's
4010   *     prop_iterator_class somehow...   *     prop_iterator_class somehow...
4011   * + preserve the OBJ_ENUMERATE API while optimizing the native object case   * + preserve the obj->enumerate API while optimizing the native object case
4012   * + native case here uses a JSScopeProperty *, but that iterates in reverse!   * + native case here uses a JSScopeProperty *, but that iterates in reverse!
4013   * + so we make non-native match, by reverse-iterating after JS_Enumerating   * + so we make non-native match, by reverse-iterating after JS_Enumerating
4014   */   */
4015  #define JSSLOT_ITER_INDEX       (JSSLOT_PRIVATE + 1)  const uint32 JSSLOT_ITER_INDEX = JSSLOT_PRIVATE + 1;
4016    JS_STATIC_ASSERT(JSSLOT_ITER_INDEX < JS_INITIAL_NSLOTS);
 #if JSSLOT_ITER_INDEX >= JS_INITIAL_NSLOTS  
 # error "JSSLOT_ITER_INDEX botch!"  
 #endif  
4017    
4018  static void  static void
4019  prop_iter_finalize(JSContext *cx, JSObject *obj)  prop_iter_finalize(JSContext *cx, JSObject *obj)
4020  {  {
4021      jsval v;      void *pdata = obj->getPrivate();
4022      jsint i;      if (!pdata)
     JSIdArray *ida;  
   
     v = obj->fslots[JSSLOT_ITER_INDEX];  
     if (JSVAL_IS_VOID(v))  
4023          return;          return;
4024    
4025      i = JSVAL_TO_INT(v);      if (JSVAL_TO_INT(obj->fslots[JSSLOT_ITER_INDEX]) >= 0) {
     if (i >= 0) {  
4026          /* Non-native case: destroy the ida enumerated when obj was created. */          /* Non-native case: destroy the ida enumerated when obj was created. */
4027          ida = (JSIdArray *) JS_GetPrivate(cx, obj);          JSIdArray *ida = (JSIdArray *) pdata;
4028          if (ida)          JS_DestroyIdArray(cx, ida);
             JS_DestroyIdArray(cx, ida);  
4029      }      }
4030  }  }
4031    
4032  static void  static void
4033  prop_iter_trace(JSTracer *trc, JSObject *obj)  prop_iter_trace(JSTracer *trc, JSObject *obj)
4034  {  {
4035      jsval v;      void *pdata = obj->getPrivate();
4036      jsint i, n;      if (!pdata)
4037      JSScopeProperty *sprop;          return;
     JSIdArray *ida;  
     jsid id;  
   
     v = obj->fslots[JSSLOT_PRIVATE];  
     JS_ASSERT(!JSVAL_IS_VOID(v));  
4038    
4039      i = JSVAL_TO_INT(obj->fslots[JSSLOT_ITER_INDEX]);      if (JSVAL_TO_INT(obj->fslots[JSSLOT_ITER_INDEX]) < 0) {
     if (i < 0) {  
4040          /* Native case: just mark the next property to visit. */          /* Native case: just mark the next property to visit. */
4041          sprop = (JSScopeProperty *) JSVAL_TO_PRIVATE(v);          ((JSScopeProperty *) pdata)->trace(trc);
         if (sprop)  
             TRACE_SCOPE_PROPERTY(trc, sprop);  
4042      } else {      } else {
4043          /* Non-native case: mark each id in the JSIdArray private. */          /* Non-native case: mark each id in the JSIdArray private. */
4044          ida = (JSIdArray *) JSVAL_TO_PRIVATE(v);          JSIdArray *ida = (JSIdArray *) pdata;
4045          for (i = 0, n = ida->length; i < n; i++) {          for (jsint i = 0, n = ida->length; i < n; i++)
4046              id = ida->vector[i];              js_TraceId(trc, ida->vector[i]);
             TRACE_ID(trc, id);  
         }  
4047      }      }
4048  }  }
4049    
# Line 4095  Line 4067 
4067      JSIdArray *ida;      JSIdArray *ida;
4068    
4069      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
4070      iterobj = js_NewObject(cx, &prop_iter_class, NULL, obj, 0);      iterobj = js_NewObject(cx, &prop_iter_class, NULL, obj);
4071      if (!iterobj)      if (!iterobj)
4072          return NULL;          return NULL;
4073    
4074      if (OBJ_IS_NATIVE(obj)) {      if (OBJ_IS_NATIVE(obj)) {
4075          /* Native case: start with the last property in obj's own scope. */          /* Native case: start with the last property in obj's own scope. */
4076          scope = OBJ_SCOPE(obj);          scope = OBJ_SCOPE(obj);
4077          pdata = (scope->object == obj) ? scope->lastProp : NULL;          pdata = scope->lastProp;
4078          index = -1;          index = -1;
4079      } else {      } else {
         JSTempValueRooter tvr;  
   
4080          /*          /*
4081           * Non-native case: enumerate a JSIdArray and keep it via private.           * Non-native case: enumerate a JSIdArray and keep it via private.
4082           *           *
4083           * Note: we have to make sure that we root obj around the call to           * Note: we have to make sure that we root obj around the call to
4084           * JS_Enumerate to protect against multiple allocations under it.           * JS_Enumerate to protect against multiple allocations under it.
4085           */           */
4086          JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(iterobj), &tvr);          JSAutoTempValueRooter tvr(cx, iterobj);
4087          ida = JS_Enumerate(cx, obj);          ida = JS_Enumerate(cx, obj);
         JS_POP_TEMP_ROOT(cx, &tvr);  
4088          if (!ida)          if (!ida)
4089              goto bad;              return NULL;
4090          pdata = ida;          pdata = ida;
4091          index = ida->length;          index = ida->length;
4092      }      }
4093    
4094      /* iterobj cannot escape to other threads here. */      /* iterobj cannot escape to other threads here. */
4095      STOBJ_SET_SLOT(iterobj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(pdata));      iterobj->setPrivate(pdata);
4096      STOBJ_SET_SLOT(iterobj, JSSLOT_ITER_INDEX, INT_TO_JSVAL(index));      iterobj->fslots[JSSLOT_ITER_INDEX] = INT_TO_JSVAL(index);
4097      return iterobj;      return iterobj;
   
 bad:  
     cx->weakRoots.newborn[GCX_OBJECT] = NULL;  
     return NULL;  
4098  }  }
4099    
4100  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 4142  Line 4107 
4107      JSIdArray *ida;      JSIdArray *ida;
4108    
4109      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
4110      i = JSVAL_TO_INT(OBJ_GET_SLOT(cx, iterobj, JSSLOT_ITER_INDEX));      i = JSVAL_TO_INT(iterobj->fslots[JSSLOT_ITER_INDEX]);
4111      if (i < 0) {      if (i < 0) {
4112          /* Native case: private data is a property tree node pointer. */          /* Native case: private data is a property tree node pointer. */
4113          obj = OBJ_GET_PARENT(cx, iterobj);          obj = OBJ_GET_PARENT(cx, iterobj);
4114          JS_ASSERT(OBJ_IS_NATIVE(obj));          JS_ASSERT(OBJ_IS_NATIVE(obj));
4115          scope = OBJ_SCOPE(obj);          scope = OBJ_SCOPE(obj);
4116          JS_ASSERT(scope->object == obj);          sprop = (JSScopeProperty *) iterobj->getPrivate();
         sprop = (JSScopeProperty *) JS_GetPrivate(cx, iterobj);  
4117    
4118          /*          /*
4119           * If the next property mapped by scope in the property tree ancestor           * If the next property mapped by scope in the property tree ancestor
# Line 4161  Line 4125 
4125          while (sprop &&          while (sprop &&
4126                 (!(sprop->attrs & JSPROP_ENUMERATE) ||                 (!(sprop->attrs & JSPROP_ENUMERATE) ||
4127                  (sprop->flags & SPROP_IS_ALIAS) ||                  (sprop->flags & SPROP_IS_ALIAS) ||
4128                  (SCOPE_HAD_MIDDLE_DELETE(scope) &&                  (scope->hadMiddleDelete() && !scope->has(sprop)))) {
                  !SCOPE_HAS_PROPERTY(scope, sprop)))) {  
4129              sprop = sprop->parent;              sprop = sprop->parent;
4130          }          }
4131    
4132          if (!sprop) {          if (!sprop) {
4133              *idp = JSVAL_VOID;              *idp = JSVAL_VOID;
4134          } else {          } else {
4135              if (!JS_SetPrivate(cx, iterobj, sprop->parent))              iterobj->setPrivate(sprop->parent);
                 return JS_FALSE;  
4136              *idp = sprop->id;              *idp = sprop->id;
4137          }          }
4138      } else {      } else {
4139          /* Non-native case: use the ida enumerated when iterobj was created. */          /* Non-native case: use the ida enumerated when iterobj was created. */
4140          ida = (JSIdArray *) JS_GetPrivate(cx, iterobj);          ida = (JSIdArray *) iterobj->getPrivate();
4141          JS_ASSERT(i <= ida->length);          JS_ASSERT(i <= ida->length);
4142          if (i == 0) {          if (i == 0) {
4143              *idp = JSVAL_VOID;              *idp = JSVAL_VOID;
# Line 4192  Line 4154 
4154                 jsval *vp, uintN *attrsp)                 jsval *vp, uintN *attrsp)
4155  {  {
4156      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
4157      return OBJ_CHECK_ACCESS(cx, obj, id, mode, vp, attrsp);      return obj->checkAccess(cx, id, mode, vp, attrsp);
 }  
   
 static JSBool  
 ReservedSlotIndexOK(JSContext *cx, JSObject *obj, JSClass *clasp,  
                     uint32 index, uint32 limit)  
 {  
     /* Check the computed, possibly per-instance, upper bound. */  
     if (clasp->reserveSlots)  
         JS_LOCK_OBJ_VOID(cx, obj, limit += clasp->reserveSlots(cx, obj));  
     if (index >= limit) {  
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,  
                              JSMSG_RESERVED_SLOT_RANGE);  
         return JS_FALSE;  
     }  
     return JS_TRUE;  
4158  }  }
4159    
4160  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
4161  JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp)  JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp)
4162  {  {
     JSClass *clasp;  
     uint32 limit, slot;  
   
4163      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
4164      clasp = OBJ_GET_CLASS(cx, obj);      return js_GetReservedSlot(cx, obj, index, vp);
     limit = JSCLASS_RESERVED_SLOTS(clasp);  
     if (index >= limit && !ReservedSlotIndexOK(cx, obj, clasp, index, limit))  
         return JS_FALSE;  
     slot = JSSLOT_START(clasp) + index;  
     *vp = OBJ_GET_REQUIRED_SLOT(cx, obj, slot);  
     return JS_TRUE;  
4165  }  }
4166    
4167  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
4168  JS_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v)  JS_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v)
4169  {  {
     JSClass *clasp;  
     uint32 limit, slot;  
   
4170      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
4171      clasp = OBJ_GET_CLASS(cx, obj);      return js_SetReservedSlot(cx, obj, index, v);
     limit = JSCLASS_RESERVED_SLOTS(clasp);  
     if (index >= limit && !ReservedSlotIndexOK(cx, obj, clasp, index, limit))  
         return JS_FALSE;  
     slot = JSSLOT_START(clasp) + index;  
     return OBJ_SET_REQUIRED_SLOT(cx, obj, slot, v);  
4172  }  }
4173    
4174  #ifdef JS_THREADSAFE  #ifdef JS_THREADSAFE
# Line 4343  Line 4273 
4273       */       */
4274      if (FUN_FLAT_CLOSURE(fun)) {      if (FUN_FLAT_CLOSURE(fun)) {
4275          JS_ASSERT(funobj->dslots);          JS_ASSERT(funobj->dslots);
4276          JS_ASSERT(JSSLOT_FREE(&js_FunctionClass) == JS_INITIAL_NSLOTS);          if (!js_EnsureReservedSlots(cx, clone,
4277                                        fun->countInterpretedReservedSlots())) {
         uint32 nslots = JSSLOT_FREE(&js_FunctionClass);  
         JS_ASSERT(nslots == JS_INITIAL_NSLOTS);  
         nslots += js_FunctionClass.reserveSlots(cx, clone);  
         if (!js_ReallocSlots(cx, clone, nslots, JS_TRUE))  
4278              return NULL;              return NULL;
4279            }
4280    
4281          JSUpvarArray *uva = JS_SCRIPT_UPVARS(fun->u.i.script);          JSUpvarArray *uva = fun->u.i.script->upvars();
4282          JS_ASSERT(uva->length <= size_t(clone->dslots[-1]));          JS_ASSERT(uva->length <= size_t(clone->dslots[-1]));
4283    
4284          void *mark = JS_ARENA_MARK(&cx->tempPool);          void *mark = JS_ARENA_MARK(&cx->tempPool);
# Line 4373  Line 4300 
4300              }              }
4301    
4302              JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(names[i]);              JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(names[i]);
4303              if (!OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &clone->dslots[i]))              if (!obj->getProperty(cx, ATOM_TO_JSID(atom), &clone->dslots[i]))
4304                  break;                  break;
4305          }          }
4306    
# Line 4480  Line 4407 
4407    
4408      native =      native =
4409  #ifdef JS_TRACER  #ifdef JS_TRACER
4410               (fs->flags & JSFUN_TRACEABLE)               (fs->flags & JSFUN_TRCINFO)
4411               ? JS_FUNC_TO_DATA_PTR(JSTraceableNative *, fs->call)->native               ? JS_FUNC_TO_DATA_PTR(JSNativeTraceInfo *, fs->call)->native
4412               :               :
4413  #endif  #endif
4414                 (JSFastNative) fs->call;                 (JSFastNative) fs->call;
# Line 4579  Line 4506 
4506                                        js_generic_fast_native_method_dispatcher                                        js_generic_fast_native_method_dispatcher
4507                                      : js_generic_native_method_dispatcher,                                      : js_generic_native_method_dispatcher,
4508                                      fs->nargs + 1,                                      fs->nargs + 1,
4509                                      flags & ~JSFUN_TRACEABLE);                                      flags & ~JSFUN_TRCINFO);
4510              if (!fun)              if (!fun)
4511                  return JS_FALSE;                  return JS_FALSE;
4512              fun->u.n.extra = (uint16)fs->extra;              fun->u.n.extra = (uint16)fs->extra;
# Line 4641  Line 4568 
4568      if (!chars)      if (!chars)
4569          return NULL;          return NULL;
4570      script = JS_CompileUCScript(cx, obj, chars, length, filename, lineno);      script = JS_CompileUCScript(cx, obj, chars, length, filename, lineno);
4571      JS_free(cx, chars);      cx->free(chars);
4572      return script;      return script;
4573  }  }
4574    
# Line 4660  Line 4587 
4587          return NULL;          return NULL;
4588      script = JS_CompileUCScriptForPrincipals(cx, obj, principals,      script = JS_CompileUCScriptForPrincipals(cx, obj, principals,
4589                                               chars, length, filename, lineno);                                               chars, length, filename, lineno);
4590      JS_free(cx, chars);      cx->free(chars);
4591      return script;      return script;
4592  }  }
4593    
# Line 4745  Line 4672 
4672              JS_SetErrorReporter(cx, older);              JS_SetErrorReporter(cx, older);
4673          }          }
4674      }      }
4675      JS_free(cx, chars);      cx->free(chars);
4676      JS_RestoreExceptionState(cx, exnState);      JS_RestoreExceptionState(cx, exnState);
4677      return result;      return result;
4678  }  }
# Line 4809  Line 4736 
4736    
4737      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
4738      if (!script)      if (!script)
4739          return js_NewObject(cx, &js_ScriptClass, NULL, NULL, 0);          return js_NewObject(cx, &js_ScriptClass, NULL, NULL);
4740    
4741      JS_ASSERT(!script->u.object);      JS_ASSERT(!script->u.object);
4742    
4743      JS_PUSH_TEMP_ROOT_SCRIPT(cx, script, &tvr);      JS_PUSH_TEMP_ROOT_SCRIPT(cx, script, &tvr);
4744      obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL, 0);      obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
4745      if (obj) {      if (obj) {
4746          JS_SetPrivate(cx, obj, script);          obj->setPrivate(script);
4747          script->u.object = obj;          script->u.object = obj;
4748  #ifdef CHECK_SCRIPT_OWNER  #ifdef CHECK_SCRIPT_OWNER
4749          script->owner = NULL;          script->owner = NULL;
# Line 4854  Line 4781 
4781          return NULL;          return NULL;
4782      fun = JS_CompileUCFunction(cx, obj, name, nargs, argnames, chars, length,      fun = JS_CompileUCFunction(cx, obj, name, nargs, argnames, chars, length,
4783                                 filename, lineno);                                 filename, lineno);
4784      JS_free(cx, chars);      cx->free(chars);
4785      return fun;      return fun;
4786  }  }
4787    
# Line 4875  Line 4802 
4802      fun = JS_CompileUCFunctionForPrincipals(cx, obj, principals, name,      fun = JS_CompileUCFunctionForPrincipals(cx, obj, principals, name,
4803                                              nargs, argnames, chars, length,                                              nargs, argnames, chars, length,
4804                                              filename, lineno);                                              filename, lineno);
4805      JS_free(cx, chars);      cx->free(chars);
4806      return fun;      return fun;
4807  }  }
4808    
# Line 4940  Line 4867 
4867    
4868      if (obj &&      if (obj &&
4869          funAtom &&          funAtom &&
4870          !OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(funAtom),          !obj->defineProperty(cx, ATOM_TO_JSID(funAtom), OBJECT_TO_JSVAL(FUN_OBJECT(fun)),
4871                               OBJECT_TO_JSVAL(FUN_OBJECT(fun)),                               NULL, NULL, JSPROP_ENUMERATE)) {
                              NULL, NULL, JSPROP_ENUMERATE, NULL)) {  
4872          fun = NULL;          fun = NULL;
4873      }      }
4874    
# Line 5043  Line 4969 
4969                       JSExecPart part, jsval *rval)                       JSExecPart part, jsval *rval)
4970  {  {
4971      JSScript tmp;      JSScript tmp;
     JSDebugHooks *hooks;  
4972      JSBool ok;      JSBool ok;
4973    
4974      /* Make a temporary copy of the JSScript structure and farble it a bit. */      /* Make a temporary copy of the JSScript structure and farble it a bit. */
4975      tmp = *script;      tmp = *script;
4976      if (part == JSEXEC_PROLOG) {      if (part == JSEXEC_PROLOG) {
4977          tmp.length = PTRDIFF(tmp.main, tmp.code, jsbytecode);          tmp.length = tmp.main - tmp.code;
4978      } else {      } else {
4979          tmp.length -= PTRDIFF(tmp.main, tmp.code, jsbytecode);          tmp.length -= tmp.main - tmp.code;
4980          tmp.code = tmp.main;          tmp.code = tmp.main;
4981      }      }
4982    
4983      /* Tell the debugger about our temporary copy of the script structure. */      /* Tell the debugger about our temporary copy of the script structure. */
4984      hooks = cx->debugHooks;      const JSDebugHooks *hooks = cx->debugHooks;
4985      if (hooks->newScriptHook) {      if (hooks->newScriptHook) {
4986          hooks->newScriptHook(cx, tmp.filename, tmp.lineno, &tmp, NULL,          hooks->newScriptHook(cx, tmp.filename, tmp.lineno, &tmp, NULL,
4987                               hooks->newScriptHookData);                               hooks->newScriptHookData);
# Line 5085  Line 5010 
5010      if (!chars)      if (!chars)
5011          return JS_FALSE;          return JS_FALSE;
5012      ok = JS_EvaluateUCScript(cx, obj, chars, length, filename, lineno, rval);      ok = JS_EvaluateUCScript(cx, obj, chars, length, filename, lineno, rval);
5013      JS_free(cx, chars);      cx->free(chars);
5014      return ok;      return ok;
5015  }  }
5016    
# Line 5107  Line 5032 
5032          return JS_FALSE;          return JS_FALSE;
5033      ok = JS_EvaluateUCScriptForPrincipals(cx, obj, principals, chars, length,      ok = JS_EvaluateUCScriptForPrincipals(cx, obj, principals, chars, length,
5034                                            filename, lineno, rval);                                            filename, lineno, rval);
5035      JS_free(cx, chars);      cx->free(chars);
5036      return ok;      return ok;
5037  }  }
5038    
# Line 5194  Line 5119 
5119  {  {
5120  #ifdef JS_THREADSAFE  #ifdef JS_THREADSAFE
5121      JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread));      JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread));
5122  #endif      #endif
5123      JSOperationCallback old = cx->operationCallback;      JSOperationCallback old = cx->operationCallback;
5124      cx->operationCallback = callback;      cx->operationCallback = callback;
5125      return old;      return old;
# Line 5316  Line 5241 
5241      /* Free chars (but not bytes, which caller frees on error) if we fail. */      /* Free chars (but not bytes, which caller frees on error) if we fail. */
5242      str = js_NewString(cx, chars, length);      str = js_NewString(cx, chars, length);
5243      if (!str) {      if (!str) {
5244          JS_free(cx, chars);          cx->free(chars);
5245          return NULL;          return NULL;
5246      }      }
5247    
5248      /* Hand off bytes to the deflated string cache, if possible. */      /* Hand off bytes to the deflated string cache, if possible. */
5249      if (!js_SetStringBytes(cx, str, bytes, nbytes))      if (!js_SetStringBytes(cx, str, bytes, nbytes))
5250          JS_free(cx, bytes);          cx->free(bytes);
5251      return str;      return str;
5252  }  }
5253    
# Line 5338  Line 5263 
5263          return NULL;          return NULL;
5264      str = js_NewString(cx, js, n);      str = js_NewString(cx, js, n);
5265      if (!str)      if (!str)
5266          JS_free(cx, js);          cx->free(js);
5267      return str;      return str;
5268  }  }
5269    
# Line 5358  Line 5283 
5283          return NULL;          return NULL;
5284      str = js_NewString(cx, js, n);      str = js_NewString(cx, js, n);
5285      if (!str)      if (!str)
5286          JS_free(cx, js);          cx->free(js);
5287      return str;      return str;
5288  }  }
5289    
# Line 5443  Line 5368 
5368       * rate bugs in string concatenation, is worth this slight loss in API       * rate bugs in string concatenation, is worth this slight loss in API
5369       * compatibility.       * compatibility.
5370       */       */
5371      if (JSSTRING_IS_DEPENDENT(str)) {      if (str->isDependent()) {
5372          n = JSSTRDEP_LENGTH(str);          n = str->dependentLength();
5373          size = (n + 1) * sizeof(jschar);          size = (n + 1) * sizeof(jschar);
5374          s = (jschar *) malloc(size);          s = (jschar *) js_malloc(size);
5375          if (s) {          if (s) {
5376              memcpy(s, JSSTRDEP_CHARS(str), n * sizeof *s);              memcpy(s, str->dependentChars(), n * sizeof *s);
5377              s[n] = 0;              s[n] = 0;
5378              JSFLATSTR_REINIT(str, s, n);              str->reinitFlat(s, n);
5379          } else {          } else {
5380              s = JSSTRDEP_CHARS(str);              s = str->dependentChars();
5381          }          }
5382      } else {      } else {
5383          JSFLATSTR_CLEAR_MUTABLE(str);          str->flatClearMutable();
5384          s = JSFLATSTR_CHARS(str);          s = str->flatChars();
5385      }      }
5386      return s;      return s;
5387  }  }
# Line 5464  Line 5389 
5389  JS_PUBLIC_API(size_t)  JS_PUBLIC_API(size_t)
5390  JS_GetStringLength(JSString *str)  JS_GetStringLength(JSString *str)
5391  {  {
5392      return JSSTRING_LENGTH(str);      return str->length();
5393  }  }
5394    
5395  JS_PUBLIC_API(intN)  JS_PUBLIC_API(intN)
# Line 5482  Line 5407 
5407      str = js_NewString(cx, chars, length);      str = js_NewString(cx, chars, length);
5408      if (!str)      if (!str)
5409          return str;          return str;
5410      JSFLATSTR_SET_MUTABLE(str);      str->flatSetMutable();
5411      return str;      return str;
5412  }  }
5413    
# Line 5544  Line 5469 
5469  JS_PUBLIC_API(char *)  JS_PUBLIC_API(char *)
5470  JS_EncodeString(JSContext *cx, JSString *str)  JS_EncodeString(JSContext *cx, JSString *str)
5471  {  {
5472      return js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str));      return js_DeflateString(cx, str->chars(), str->length());
5473  }  }
5474    
5475  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 5552  Line 5477 
5477               JSONWriteCallback callback, void *data)               JSONWriteCallback callback, void *data)
5478  {  {
5479      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
5480      return js_Stringify(cx, vp, replacer, space, callback, data);      JSCharBuffer cb(cx);
5481        if (!js_Stringify(cx, vp, replacer, space, cb))
5482            return false;
5483        return callback(cb.begin(), cb.length(), data);
5484  }  }
5485    
5486  JS_PUBLIC_API(JSBool)  JS_PUBLIC_API(JSBool)
# Line 5724  Line 5652 
5652      if (!chars)      if (!chars)
5653          return NULL;          return NULL;
5654      obj = js_NewRegExpObject(cx, NULL, chars, length, flags);      obj = js_NewRegExpObject(cx, NULL, chars, length, flags);
5655      JS_free(cx, chars);      cx->free(chars);
5656      return obj;      return obj;
5657  }  }
5658    
# Line 5760  Line 5688 
5688      res->parenCount = 0;      res->parenCount = 0;
5689      res->lastMatch = res->lastParen = js_EmptySubString;      res->lastMatch = res->lastParen = js_EmptySubString;
5690      res->leftContext = res->rightContext = js_EmptySubString;      res->leftContext = res->rightContext = js_EmptySubString;
5691        if (res->moreParens) {
5692            cx->free(res->moreParens);
5693            res->moreParens = NULL;
5694        }
5695      cx->runtime->gcPoke = JS_TRUE;      cx->runtime->gcPoke = JS_TRUE;
5696  }  }
5697    
# Line 5854  Line 5786 
5786      JSExceptionState *state;      JSExceptionState *state;
5787    
5788      CHECK_REQUEST(cx);      CHECK_REQUEST(cx);
5789      state = (JSExceptionState *) JS_malloc(cx, sizeof(JSExceptionState));      state = (JSExceptionState *) cx->malloc(sizeof(JSExceptionState));
5790      if (state) {      if (state) {
5791          state->throwing = JS_GetPendingException(cx, &state->exception);          state->throwing = JS_GetPendingException(cx, &state->exception);
5792          if (state->throwing && JSVAL_IS_GCTHING(state->exception))          if (state->throwing && JSVAL_IS_GCTHING(state->exception))
# Line 5883  Line 5815 
5815      if (state) {      if (state) {
5816          if (state->throwing && JSVAL_IS_GCTHING(state->exception))          if (state->throwing && JSVAL_IS_GCTHING(state->exception))
5817              JS_RemoveRoot(cx, &state->exception);              JS_RemoveRoot(cx, &state->exception);
5818          JS_free(cx, state);          cx->free(state);
5819      }      }
5820  }  }
5821    

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

  ViewVC Help
Powered by ViewVC 1.1.24