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 134549 59e4c48fa13fe08e73903fac1ec6e3d40d7e33a8
parent 134548 d0a75bdaa01efe52672396c1ea42f39143e38099
child 134550 842c175f344c4df1f33c9852a12134d4fa6d64e0
push idunknown
push userunknown
push dateunknown
reviewersterrence, bholley
bugs858108
milestone23.0a1
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!");
   }