Bug 332648 - Part g: Move AutoIdArray to jsapi.h; r=evilpie
authorMs2ger <ms2ger@gmail.com>
Wed, 11 Jan 2012 09:23:09 +0100
changeset 85400 2140f9cb5d6a7bbe8218888564f32cda7d58c32b
parent 85399 8fd1b83456805a966980fa01c062988aed782215
child 85401 4fc86339a424b5aff60d4d6603a3ed1ba5c5cf37
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersevilpie
bugs332648
milestone12.0a1
Bug 332648 - Part g: Move AutoIdArray to jsapi.h; r=evilpie
content/html/content/src/nsHTMLCanvasElement.cpp
dom/plugins/base/nsJSNPRuntime.cpp
js/ipc/ObjectWrapperChild.cpp
js/src/jsapi.h
js/src/jscntxt.h
js/src/jsgc.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -496,52 +496,49 @@ nsHTMLCanvasElement::GetContext(const ns
 
       // note: if any contexts end up supporting something other
       // than objects, e.g. plain strings, then we'll need to expand
       // this to know how to create nsISupportsStrings etc.
       if (JSVAL_IS_OBJECT(aContextOptions)) {
         contextProps = do_CreateInstance("@mozilla.org/hash-property-bag;1");
 
         JSObject *opts = JSVAL_TO_OBJECT(aContextOptions);
-        JSIdArray *props = JS_Enumerate(cx, opts);
-        for (int i = 0; props && i < JS_IdArrayLength(cx, props); ++i) {
-          jsid propid = JS_IdArrayGet(cx, props, i);
+        JS::AutoIdArray props(cx, JS_Enumerate(cx, opts));
+        for (size_t i = 0; !!props && i < props.length(); ++i) {
+          jsid propid = props[i];
           jsval propname, propval;
           if (!JS_IdToValue(cx, propid, &propname) ||
               !JS_GetPropertyById(cx, opts, propid, &propval)) {
             continue;
           }
 
           JSString *propnameString = JS_ValueToString(cx, propname);
           nsDependentJSString pstr;
           if (!propnameString || !pstr.init(cx, propnameString)) {
-            JS_DestroyIdArray(cx, props);
             mCurrentContext = nsnull;
             return NS_ERROR_FAILURE;
           }
 
           if (JSVAL_IS_BOOLEAN(propval)) {
-            contextProps->SetPropertyAsBool(pstr, propval == JSVAL_TRUE ? true : false);
+            contextProps->SetPropertyAsBool(pstr, JSVAL_TO_BOOLEAN(propval));
           } else if (JSVAL_IS_INT(propval)) {
             contextProps->SetPropertyAsInt32(pstr, JSVAL_TO_INT(propval));
           } else if (JSVAL_IS_DOUBLE(propval)) {
             contextProps->SetPropertyAsDouble(pstr, JSVAL_TO_DOUBLE(propval));
           } else if (JSVAL_IS_STRING(propval)) {
             JSString *propvalString = JS_ValueToString(cx, propval);
             nsDependentJSString vstr;
             if (!propvalString || !vstr.init(cx, propvalString)) {
-              JS_DestroyIdArray(cx, props);
               mCurrentContext = nsnull;
               return NS_ERROR_FAILURE;
             }
 
             contextProps->SetPropertyAsAString(pstr, vstr);
           }
         }
-        JS_DestroyIdArray(cx, props);
       }
     }
 
     rv = UpdateContext(contextProps);
     if (NS_FAILED(rv)) {
       if (!forceThebes) {
         // Try again with a Thebes context
         forceThebes = true;
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -961,60 +961,52 @@ nsJSObjWrapper::NP_Enumerate(NPObject *n
   AutoCXPusher pusher(cx);
   JSAutoRequest ar(cx);
   AutoJSExceptionReporter reporter(cx);
   JSAutoEnterCompartment ac;
 
   if (!ac.enter(cx, npjsobj->mJSObj))
     return false;
 
-  JSIdArray *ida = ::JS_Enumerate(cx, npjsobj->mJSObj);
+  JS::AutoIdArray ida(cx, JS_Enumerate(cx, npjsobj->mJSObj));
   if (!ida) {
     return false;
   }
 
-  *count = ida->length;
+  *count = ida.length();
   *idarray = (NPIdentifier *)PR_Malloc(*count * sizeof(NPIdentifier));
   if (!*idarray) {
     ThrowJSException(cx, "Memory allocation failed for NPIdentifier!");
-
-    ::JS_DestroyIdArray(cx, ida);
-
     return false;
   }
 
   for (PRUint32 i = 0; i < *count; i++) {
     jsval v;
-    if (!::JS_IdToValue(cx, ida->vector[i], &v)) {
-      ::JS_DestroyIdArray(cx, ida);
+    if (!JS_IdToValue(cx, ida[i], &v)) {
       PR_Free(*idarray);
       return false;
     }
 
     NPIdentifier id;
     if (JSVAL_IS_STRING(v)) {
       JSString *str = JS_InternJSString(cx, JSVAL_TO_STRING(v));
       if (!str) {
-          ::JS_DestroyIdArray(cx, ida);
-          PR_Free(*idarray);
-
-          return false;
+        PR_Free(*idarray);
+        return false;
       }
       id = StringToNPIdentifier(cx, str);
     } else {
       NS_ASSERTION(JSVAL_IS_INT(v),
                    "The element in ida must be either string or int!\n");
       id = IntToNPIdentifier(JSVAL_TO_INT(v));
     }
 
     (*idarray)[i] = id;
   }
 
-  ::JS_DestroyIdArray(cx, ida);
-
   return true;
 }
 
 //static
 bool
 nsJSObjWrapper::NP_Construct(NPObject *npobj, const NPVariant *args,
                              uint32_t argCount, NPVariant *result)
 {
--- a/js/ipc/ObjectWrapperChild.cpp
+++ b/js/ipc/ObjectWrapperChild.cpp
@@ -34,17 +34,16 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "base/basictypes.h"
-#include "jscntxt.h"
 
 #include "mozilla/jsipc/ContextWrapperChild.h"
 #include "mozilla/jsipc/ObjectWrapperChild.h"
 #include "mozilla/jsipc/CPOWTypes.h"
 
 #include "jsapi.h"
 #include "nsAutoPtr.h"
 #include "nsTArray.h"
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3466,16 +3466,67 @@ extern JS_PUBLIC_API(jsint)
 JS_IdArrayLength(JSContext *cx, JSIdArray *ida);
 
 extern JS_PUBLIC_API(jsid)
 JS_IdArrayGet(JSContext *cx, JSIdArray *ida, jsint index);
 
 extern JS_PUBLIC_API(void)
 JS_DestroyIdArray(JSContext *cx, JSIdArray *ida);
 
+#ifdef __cplusplus
+
+namespace JS {
+
+class AutoIdArray : private AutoGCRooter {
+  public:
+    AutoIdArray(JSContext *cx, JSIdArray *ida JS_GUARD_OBJECT_NOTIFIER_PARAM)
+      : AutoGCRooter(cx, IDARRAY), idArray(ida)
+    {
+        JS_GUARD_OBJECT_NOTIFIER_INIT;
+    }
+    ~AutoIdArray() {
+        if (idArray)
+            JS_DestroyIdArray(context, idArray);
+    }
+    bool operator!() {
+        return !idArray;
+    }
+    jsid operator[](size_t i) const {
+        JS_ASSERT(idArray);
+        JS_ASSERT(i < length());
+        return JS_IdArrayGet(context, idArray, i);
+    }
+    size_t length() const {
+        return JS_IdArrayLength(context, idArray);
+    }
+
+    friend void AutoGCRooter::trace(JSTracer *trc);
+
+    JSIdArray *steal() {
+        JSIdArray *copy = idArray;
+        idArray = NULL;
+        return copy;
+    }
+
+  protected:
+    inline void trace(JSTracer *trc);
+
+  private:
+    JSIdArray *idArray;
+    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
+
+    /* No copy or assignment semantics. */
+    AutoIdArray(AutoIdArray &ida) MOZ_DELETE;
+    void operator=(AutoIdArray &ida) MOZ_DELETE;
+};
+
+} /* namespace JS */
+
+#endif /* __cplusplus */
+
 extern JS_PUBLIC_API(JSBool)
 JS_ValueToId(JSContext *cx, jsval v, jsid *idp);
 
 extern JS_PUBLIC_API(JSBool)
 JS_IdToValue(JSContext *cx, jsid id, jsval *vp);
 
 /*
  * JSNewResolveOp flag bits.
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1593,58 +1593,16 @@ typedef RootedVar<Shape*>             Ro
 typedef RootedVar<BaseShape*>         RootedVarBaseShape;
 typedef RootedVar<types::TypeObject*> RootedVarTypeObject;
 typedef RootedVar<JSString*>          RootedVarString;
 typedef RootedVar<JSAtom*>            RootedVarAtom;
 typedef RootedVar<jsid>               RootedVarId;
 typedef RootedVar<Value>              RootedVarValue;
 
 /* FIXME(bug 332648): Move this into a public header. */
-class AutoIdArray : private AutoGCRooter {
-  public:
-    AutoIdArray(JSContext *cx, JSIdArray *ida JS_GUARD_OBJECT_NOTIFIER_PARAM)
-      : AutoGCRooter(cx, IDARRAY), idArray(ida)
-    {
-        JS_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-    ~AutoIdArray() {
-        if (idArray)
-            JS_DestroyIdArray(context, idArray);
-    }
-    bool operator!() {
-        return idArray == NULL;
-    }
-    jsid operator[](size_t i) const {
-        JS_ASSERT(idArray);
-        JS_ASSERT(i < size_t(idArray->length));
-        return idArray->vector[i];
-    }
-    size_t length() const {
-         return idArray->length;
-    }
-
-    friend void AutoGCRooter::trace(JSTracer *trc);
-
-    JSIdArray *steal() {
-        JSIdArray *copy = idArray;
-        idArray = NULL;
-        return copy;
-    }
-
-  protected:
-    inline void trace(JSTracer *trc);
-
-  private:
-    JSIdArray * idArray;
-    JS_DECL_USE_GUARD_OBJECT_NOTIFIER
-
-    AutoIdArray(AutoIdArray &ida) MOZ_DELETE;
-    void operator=(AutoIdArray &ida) MOZ_DELETE;
-};
-
 /* The auto-root for enumeration object and its state. */
 class AutoEnumStateRooter : private AutoGCRooter
 {
   public:
     AutoEnumStateRooter(JSContext *cx, JSObject *obj
                         JS_GUARD_OBJECT_NOTIFIER_PARAM)
       : AutoGCRooter(cx, ENUMERATOR), obj(obj), stateValue()
     {
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1958,17 +1958,17 @@ AutoGCRooter::trace(JSTracer *trc)
         return;
 
       case ENUMERATOR:
         static_cast<AutoEnumStateRooter *>(this)->trace(trc);
         return;
 
       case IDARRAY: {
         JSIdArray *ida = static_cast<AutoIdArray *>(this)->idArray;
-        MarkIdRange(trc, ida->vector, ida->vector + ida->length, "js::AutoIdArray.idArray");
+        MarkIdRange(trc, ida->vector, ida->vector + ida->length, "JS::AutoIdArray.idArray");
         return;
       }
 
       case DESCRIPTORS: {
         PropDescArray &descriptors =
             static_cast<AutoPropDescArrayRooter *>(this)->descriptors;
         for (size_t i = 0, len = descriptors.length(); i < len; i++) {
             PropDesc &desc = descriptors[i];
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -56,18 +56,16 @@
 #include "XrayWrapper.h"
 #include "nsNullPrincipal.h"
 #include "nsJSUtils.h"
 #include "mozJSComponentLoader.h"
 #include "nsContentUtils.h"
 #include "jsgc.h"
 #include "jsfriendapi.h"
 
-#include "jscntxt.h" // AutoIdArray
-
 using namespace mozilla;
 using namespace js;
 /***************************************************************************/
 // stuff used by all
 
 static nsresult ThrowAndFail(uintN errNum, JSContext* cx, bool* retval)
 {
     XPCThrower::Throw(errNum, cx);
@@ -3753,17 +3751,17 @@ nsXPCComponents_Utils::MakeObjectPropsNo
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
     JSObject *obj = js::UnwrapObject(JSVAL_TO_OBJECT(vobj));
 
     JSAutoEnterCompartment ac;
     if (!ac.enter(cx, obj))
         return NS_ERROR_FAILURE;
 
-    js::AutoIdArray ida(cx, JS_Enumerate(cx, obj));
+    JS::AutoIdArray ida(cx, JS_Enumerate(cx, obj));
     if (!ida)
         return NS_ERROR_FAILURE;
 
     for (size_t i = 0; i < ida.length(); ++i) {
         jsid id = ida[i];
         jsval v;
 
         if (!JS_GetPropertyById(cx, obj, id, &v))
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -44,17 +44,17 @@
 
 #include "xpcprivate.h"
 #include "nsArrayEnumerator.h"
 #include "nsWrapperCache.h"
 #include "XPCWrapper.h"
 #include "AccessCheck.h"
 #include "nsJSUtils.h"
 
-#include "jscntxt.h" // mJSContext->errorReporter, JSIdArray, js::AutoValueVector
+#include "jscntxt.h" // mJSContext->errorReporter, js::AutoValueVector
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsXPCWrappedJSClass, nsIXPCWrappedJSClass)
 
 // the value of this variable is never used - we use its address as a sentinel
 static uint32_t zero_methods_descriptor;
 
 bool AutoScriptEvaluate::StartEvaluating(JSObject *scope, JSErrorReporter errorReporter)
 {
@@ -400,70 +400,59 @@ nsXPCWrappedJSClass::GetNamedPropertyAsV
 
 // static
 nsresult
 nsXPCWrappedJSClass::BuildPropertyEnumerator(XPCCallContext& ccx,
                                              JSObject* aJSObj,
                                              nsISimpleEnumerator** aEnumerate)
 {
     JSContext* cx = ccx.GetJSContext();
-    nsresult retval = NS_ERROR_FAILURE;
-    JSIdArray* idArray = nsnull;
-    int i;
 
-    // Saved state must be restored, all exits through 'out'...
     AutoScriptEvaluate scriptEval(cx);
     if (!scriptEval.StartEvaluating(aJSObj))
         return NS_ERROR_FAILURE;
 
-    idArray = JS_Enumerate(cx, aJSObj);
+    JS::AutoIdArray idArray(cx, JS_Enumerate(cx, aJSObj));
     if (!idArray)
-        return retval;
+        return NS_ERROR_FAILURE;
 
-    nsCOMArray<nsIProperty> propertyArray(idArray->length);
-    for (i = 0; i < idArray->length; i++) {
+    nsCOMArray<nsIProperty> propertyArray(idArray.length());
+    for (size_t i = 0; i < idArray.length(); i++) {
+        jsid idName = idArray[i];
+
         nsCOMPtr<nsIVariant> value;
-        jsid idName = idArray->vector[i];
         nsresult rv;
-
         if (!GetNamedPropertyAsVariantRaw(ccx, aJSObj, idName,
                                           getter_AddRefs(value), &rv)) {
             if (NS_FAILED(rv))
-                retval = rv;
-            goto out;
+                return rv;
+            return NS_ERROR_FAILURE;
         }
 
         jsval jsvalName;
         if (!JS_IdToValue(cx, idName, &jsvalName))
-            goto out;
+            return NS_ERROR_FAILURE;
 
         JSString* name = JS_ValueToString(cx, jsvalName);
         if (!name)
-            goto out;
+            return NS_ERROR_FAILURE;
 
         size_t length;
         const jschar *chars = JS_GetStringCharsAndLength(cx, name, &length);
         if (!chars)
-            goto out;
+            return NS_ERROR_FAILURE;
 
         nsCOMPtr<nsIProperty> property =
             new xpcProperty(chars, (PRUint32) length, value);
-        if (!property)
-            goto out;
 
         if (!propertyArray.AppendObject(property))
-            goto out;
+            return NS_ERROR_FAILURE;
     }
 
-    retval = NS_NewArrayEnumerator(aEnumerate, propertyArray);
-
-out:
-    JS_DestroyIdArray(cx, idArray);
-
-    return retval;
+    return NS_NewArrayEnumerator(aEnumerate, propertyArray);
 }
 
 /***************************************************************************/
 
 NS_IMPL_ISUPPORTS1(xpcProperty, nsIProperty)
 
 xpcProperty::xpcProperty(const PRUnichar* aName, PRUint32 aNameLen,
                          nsIVariant* aValue)