Bug 858108 - GC: Root the Locale interface r=terrence r=bholley
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 05 Apr 2013 10:45:50 +0100
changeset 127774 59e4c48fa13fe08e73903fac1ec6e3d40d7e33a8
parent 127773 d0a75bdaa01efe52672396c1ea42f39143e38099
child 127775 842c175f344c4df1f33c9852a12134d4fa6d64e0
push id24512
push userryanvm@gmail.com
push dateFri, 05 Apr 2013 20:13:49 +0000
treeherdermozilla-central@139b6ba547fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence, bholley
bugs858108
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 858108 - GC: Root the Locale interface r=terrence r=bholley
js/src/jsapi.h
js/src/jsdate.cpp
js/src/jsnum.cpp
js/src/jsstr.cpp
js/xpconnect/src/XPCLocale.cpp
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1102,27 +1102,27 @@ typedef struct JSErrorFormatString {
     int16_t exnType;
 } JSErrorFormatString;
 
 typedef const JSErrorFormatString *
 (* JSErrorCallback)(void *userRef, const char *locale,
                     const unsigned errorNumber);
 
 typedef JSBool
-(* JSLocaleToUpperCase)(JSContext *cx, JSString *src, jsval *rval);
+(* JSLocaleToUpperCase)(JSContext *cx, JSHandleString src, JSMutableHandleValue rval);
 
 typedef JSBool
-(* JSLocaleToLowerCase)(JSContext *cx, JSString *src, jsval *rval);
+(* JSLocaleToLowerCase)(JSContext *cx, JSHandleString src, JSMutableHandleValue rval);
 
 typedef JSBool
-(* JSLocaleCompare)(JSContext *cx, JSString *src1, JSString *src2,
-                    jsval *rval);
+(* JSLocaleCompare)(JSContext *cx, JSHandleString src1, JSHandleString src2,
+                    JSMutableHandleValue rval);
 
 typedef JSBool
-(* JSLocaleToUnicode)(JSContext *cx, const char *src, jsval *rval);
+(* JSLocaleToUnicode)(JSContext *cx, const char *src, JSMutableHandleValue rval);
 
 /*
  * Security protocol types.
  */
 
 typedef void
 (* JSDestroyPrincipalsOp)(JSPrincipals *principals);
 
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -2757,17 +2757,17 @@ ToLocaleFormatHelper(JSContext *cx, Hand
               isdigit(buf[2]) && isdigit(buf[3]))) {
             JS_snprintf(buf + (result_len - 2), (sizeof buf) - (result_len - 2),
                         "%d", js_DateGetYear(cx, obj));
         }
 
     }
 
     if (cx->runtime->localeCallbacks && cx->runtime->localeCallbacks->localeToUnicode)
-        return cx->runtime->localeCallbacks->localeToUnicode(cx, buf, rval.address());
+        return cx->runtime->localeCallbacks->localeToUnicode(cx, buf, rval);
 
     RawString str = JS_NewStringCopyZ(cx, buf);
     if (!str)
         return false;
     rval.setString(str);
     return true;
 }
 
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -720,17 +720,17 @@ num_toLocaleString_impl(JSContext *cx, C
         strcpy(tmpDest, nint + 1);
     } else {
         JS_ASSERT(tmpDest - buf + ptrdiff_t(strlen(nint)) <= buflen);
         strcpy(tmpDest, nint);
     }
 
     if (cx->runtime->localeCallbacks && cx->runtime->localeCallbacks->localeToUnicode) {
         Rooted<Value> v(cx, StringValue(str));
-        bool ok = !!cx->runtime->localeCallbacks->localeToUnicode(cx, buf, v.address());
+        bool ok = !!cx->runtime->localeCallbacks->localeToUnicode(cx, buf, &v);
         if (ok)
             args.rval().set(v);
         js_free(buf);
         return ok;
     }
 
     str = js_NewStringCopyN<CanGC>(cx, buf, buflen);
     js_free(buf);
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -682,17 +682,17 @@ str_toLocaleLowerCase(JSContext *cx, uns
      * Forcefully ignore the first (or any) argument and return toLowerCase(),
      * ECMA has reserved that argument, presumably for defining the locale.
      */
     if (cx->runtime->localeCallbacks && cx->runtime->localeCallbacks->localeToLowerCase) {
         RootedString str(cx, ThisToStringForStringProto(cx, args));
         if (!str)
             return false;
 
-        Value result;
+        RootedValue result(cx);
         if (!cx->runtime->localeCallbacks->localeToLowerCase(cx, str, &result))
             return false;
 
         args.rval().set(result);
         return true;
     }
 
     return ToLowerCaseHelper(cx, args);
@@ -749,17 +749,17 @@ str_toLocaleUpperCase(JSContext *cx, uns
      * Forcefully ignore the first (or any) argument and return toUpperCase(),
      * ECMA has reserved that argument, presumably for defining the locale.
      */
     if (cx->runtime->localeCallbacks && cx->runtime->localeCallbacks->localeToUpperCase) {
         RootedString str(cx, ThisToStringForStringProto(cx, args));
         if (!str)
             return false;
 
-        Value result;
+        RootedValue result(cx);
         if (!cx->runtime->localeCallbacks->localeToUpperCase(cx, str, &result))
             return false;
 
         args.rval().set(result);
         return true;
     }
 
     return ToUpperCaseHelper(cx, args);
@@ -775,17 +775,17 @@ str_localeCompare(JSContext *cx, unsigne
         return false;
 
     Value thatValue = args.length() > 0 ? args[0] : UndefinedValue();
     RootedString thatStr(cx, ToString<CanGC>(cx, thatValue));
     if (!thatStr)
         return false;
 
     if (cx->runtime->localeCallbacks && cx->runtime->localeCallbacks->localeCompare) {
-        Value result;
+        RootedValue result(cx);
         if (!cx->runtime->localeCallbacks->localeCompare(cx, str, thatStr, &result))
             return false;
 
         args.rval().set(result);
         return true;
     }
 
     int32_t result;
--- a/js/xpconnect/src/XPCLocale.cpp
+++ b/js/xpconnect/src/XPCLocale.cpp
@@ -67,64 +67,64 @@ struct XPCLocaleCallbacks : public JSLoc
     MOZ_ASSERT(lc->localeToUnicode == LocaleToUnicode);
 
     XPCLocaleCallbacks* ths = static_cast<XPCLocaleCallbacks*>(lc);
     ths->AssertThreadSafety();
     return ths;
   }
 
   static JSBool
-  LocaleToUpperCase(JSContext *cx, JSString *src, jsval *rval)
+  LocaleToUpperCase(JSContext *cx, JSHandleString src, JSMutableHandleValue rval)
   {
     return ChangeCase(cx, src, rval, ToUpperCase);
   }
 
   static JSBool
-  LocaleToLowerCase(JSContext *cx, JSString *src, jsval *rval)
+  LocaleToLowerCase(JSContext *cx, JSHandleString src, JSMutableHandleValue rval)
   {
     return ChangeCase(cx, src, rval, ToLowerCase);
   }
 
   static JSBool
-  LocaleToUnicode(JSContext* cx, const char* src, jsval* rval)
+  LocaleToUnicode(JSContext* cx, const char* src, JSMutableHandleValue rval)
   {
     return This(JS_GetRuntime(cx))->ToUnicode(cx, src, rval);
   }
 
   static JSBool
-  LocaleCompare(JSContext *cx, JSString *src1, JSString *src2, jsval *rval)
+  LocaleCompare(JSContext *cx, JSHandleString src1, JSHandleString src2, JSMutableHandleValue rval)
   {
     return This(JS_GetRuntime(cx))->Compare(cx, src1, src2, rval);
   }
 
 private:
   static JSBool
-  ChangeCase(JSContext* cx, JSString* src, jsval* rval,
+  ChangeCase(JSContext* cx, JSHandleString src, JSMutableHandleValue rval,
              void(*changeCaseFnc)(const nsAString&, nsAString&))
   {
     nsDependentJSString depStr;
     if (!depStr.init(cx, src)) {
       return false;
     }
 
     nsAutoString result;
     changeCaseFnc(depStr, result);
 
     JSString *ucstr =
       JS_NewUCStringCopyN(cx, (jschar*)result.get(), result.Length());
     if (!ucstr) {
       return false;
     }
 
-    *rval = STRING_TO_JSVAL(ucstr);
+    rval.set(STRING_TO_JSVAL(ucstr));
     return true;
   }
 
   JSBool
-  Compare(JSContext *cx, JSString *src1, JSString *src2, jsval *rval)
+  Compare(JSContext *cx, JSHandleString src1, JSHandleString src2, JSMutableHandleValue rval)
   {
     nsresult rv;
 
     if (!mCollation) {
       nsCOMPtr<nsILocaleService> localeService =
         do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
 
       if (NS_SUCCEEDED(rv)) {
@@ -156,22 +156,22 @@ private:
     rv = mCollation->CompareString(nsICollation::kCollationStrengthDefault,
                                    depStr1, depStr2, &result);
 
     if (NS_FAILED(rv)) {
       xpc::Throw(cx, rv);
       return false;
     }
 
-    *rval = INT_TO_JSVAL(result);
+    rval.set(INT_TO_JSVAL(result));
     return true;
   }
 
   JSBool
-  ToUnicode(JSContext* cx, const char* src, jsval* rval)
+  ToUnicode(JSContext* cx, const char* src, JSMutableHandleValue rval)
   {
     nsresult rv;
 
     if (!mDecoder) {
       // use app default locale
       nsCOMPtr<nsILocaleService> localeService =
         do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
       if (NS_SUCCEEDED(rv)) {
@@ -196,17 +196,16 @@ private:
               if (NS_SUCCEEDED(rv))
                 ccm->GetUnicodeDecoder(charset.get(), getter_AddRefs(mDecoder));
             }
           }
         }
       }
     }
 
-    JSString *str = nullptr;
     int32_t srcLength = PL_strlen(src);
 
     if (mDecoder) {
       int32_t unicharLength = srcLength;
       PRUnichar *unichars =
         (PRUnichar *)JS_malloc(cx, (srcLength + 1) * sizeof(PRUnichar));
       if (unichars) {
         rv = mDecoder->Convert(src, &srcLength, unichars, &unicharLength);
@@ -217,32 +216,28 @@ private:
           // nsIUnicodeDecoder::Convert may use fewer than srcLength PRUnichars
           if (unicharLength + 1 < srcLength + 1) {
             PRUnichar *shrunkUnichars =
               (PRUnichar *)JS_realloc(cx, unichars,
                                       (unicharLength + 1) * sizeof(PRUnichar));
             if (shrunkUnichars)
               unichars = shrunkUnichars;
           }
-          str = JS_NewUCString(cx,
-                               reinterpret_cast<jschar*>(unichars),
-                               unicharLength);
+          JSString *str = JS_NewUCString(cx, reinterpret_cast<jschar*>(unichars), unicharLength);
+          if (str) {
+            rval.setString(str);
+            return true;
+          }
         }
-        if (!str)
-          JS_free(cx, unichars);
+        JS_free(cx, unichars);
       }
     }
 
-    if (!str) {
-      xpc::Throw(cx, NS_ERROR_OUT_OF_MEMORY);
-      return false;
-    }
-
-    *rval = STRING_TO_JSVAL(str);
-    return true;
+    xpc::Throw(cx, NS_ERROR_OUT_OF_MEMORY);
+    return false;
   }
 
   void AssertThreadSafety()
   {
     MOZ_ASSERT(mThread == PR_GetCurrentThread(),
                "XPCLocaleCallbacks used unsafely!");
   }