Bug 1490605 - Part 2: Return UTF-8 encoded strings from ValueToSourceForError. r=arai
authorAndré Bargull <andre.bargull@gmail.com>
Fri, 14 Sep 2018 09:51:14 -0700
changeset 492250 6a993fa3e3d8aff2cb8cd8be4390eda67a3328e7
parent 492249 096c2c7d43265e6eb2bc44be67459b849d781cec
child 492251 0fed430fe00c2c984a6a2c6cb4be30f62fe53baa
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1490605
milestone64.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 1490605 - Part 2: Return UTF-8 encoded strings from ValueToSourceForError. r=arai
js/src/ctypes/CTypes.cpp
js/src/jsapi.cpp
js/src/jsexn.cpp
js/src/vm/JSObject.cpp
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -995,30 +995,34 @@ GetErrorMessage(void* userRef, const uns
 {
   if (0 < errorNumber && errorNumber < CTYPESERR_LIMIT) {
     return &ErrorFormatString[errorNumber];
   }
   return nullptr;
 }
 
 static JS::UniqueChars
-EncodeLatin1(JSContext* cx, AutoString& str)
-{
-  return JS_EncodeStringToLatin1(cx, NewUCString(cx, str.finish()));
+EncodeUTF8(JSContext* cx, AutoString& str)
+{
+  RootedString string(cx, NewUCString(cx, str.finish()));
+  if (!string) {
+    return nullptr;
+  }
+  return JS_EncodeStringToUTF8(cx, string);
 }
 
 static const char*
 CTypesToSourceForError(JSContext* cx, HandleValue val, JS::UniqueChars& bytes)
 {
   if (val.isObject()) {
       RootedObject obj(cx, &val.toObject());
       if (CType::IsCType(obj) || CData::IsCDataMaybeUnwrap(&obj)) {
           RootedValue v(cx, ObjectValue(*obj));
           RootedString str(cx, JS_ValueToSource(cx, v));
-          bytes = JS_EncodeStringToLatin1(cx, str);
+          bytes = JS_EncodeStringToUTF8(cx, str);
           return bytes.get();
       }
   }
   return ValueToSourceForError(cx, val, bytes);
 }
 
 static void
 BuildCStyleFunctionTypeSource(JSContext* cx, HandleObject typeObj,
@@ -1194,38 +1198,38 @@ BuildTypeSource(JSContext* cx, JSObject*
 
 static JS::UniqueChars
 TypeSourceForError(JSContext* cx, JSObject* typeObj)
 {
   AutoString source;
   BuildTypeSource(cx, typeObj, true, source);
   if (!source)
     return nullptr;
-  return EncodeLatin1(cx, source);
+  return EncodeUTF8(cx, source);
 }
 
 static JS::UniqueChars
 FunctionTypeSourceForError(JSContext* cx, HandleObject funObj)
 {
   AutoString funSource;
   BuildFunctionTypeSource(cx, funObj, funSource);
   if (!funSource)
     return nullptr;
-  return EncodeLatin1(cx, funSource);
+  return EncodeUTF8(cx, funSource);
 }
 
 static JS::UniqueChars
 ConversionPositionForError(JSContext* cx, ConversionType convType, HandleObject funObj,
                            unsigned argIndex)
 {
   AutoString posSource;
   BuildConversionPosition(cx, convType, funObj, argIndex, posSource);
   if (!posSource)
     return nullptr;
-  return EncodeLatin1(cx, posSource);
+  return EncodeUTF8(cx, posSource);
 }
 
 class IndexCString final
 {
     char indexStr[21]; // space for UINT64_MAX plus terminating null
     static_assert(sizeof(size_t) <= 8, "index array too small");
 
   public:
@@ -1258,25 +1262,25 @@ ConvError(JSContext* cx, const char* exp
 
       IndexCString indexStr(arrIndex);
 
       JS::UniqueChars arrStr = TypeSourceForError(cx, arrObj);
       if (!arrStr) {
         return false;
       }
 
-      JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                                 CTYPESMSG_CONV_ERROR_ARRAY,
-                                 valStr, indexStr.get(), arrStr.get());
+      JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                               CTYPESMSG_CONV_ERROR_ARRAY,
+                               valStr, indexStr.get(), arrStr.get());
       break;
     }
     case TYPE_struct: {
-      JSFlatString* name = GetFieldName(arrObj, arrIndex);
+      RootedString name(cx, GetFieldName(arrObj, arrIndex));
       MOZ_ASSERT(name);
-      JS::UniqueChars nameStr = JS_EncodeStringToLatin1(cx, name);
+      JS::UniqueChars nameStr = JS_EncodeStringToUTF8(cx, name);
       if (!nameStr) {
         return false;
       }
 
       JS::UniqueChars structStr = TypeSourceForError(cx, arrObj);
       if (!structStr) {
         return false;
       }
@@ -1284,20 +1288,20 @@ ConvError(JSContext* cx, const char* exp
       JS::UniqueChars posStr;
       if (funObj) {
         posStr = ConversionPositionForError(cx, convType, funObj, argIndex);
         if (!posStr) {
           return false;
         }
       }
 
-      JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                                 CTYPESMSG_CONV_ERROR_STRUCT,
-                                 valStr, nameStr.get(), expectedStr, structStr.get(),
-                                 (posStr ? posStr.get() : ""));
+      JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                               CTYPESMSG_CONV_ERROR_STRUCT,
+                               valStr, nameStr.get(), expectedStr, structStr.get(),
+                               (posStr ? posStr.get() : ""));
       break;
     }
     default:
       MOZ_CRASH("invalid arrObj value");
     }
     return false;
   }
 
@@ -1307,51 +1311,51 @@ ConvError(JSContext* cx, const char* exp
 
     IndexCString indexStr(argIndex + 1);
 
     JS::UniqueChars funStr = FunctionTypeSourceForError(cx, funObj);
     if (!funStr) {
       return false;
     }
 
-    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                               CTYPESMSG_CONV_ERROR_ARG,
-                               valStr, indexStr.get(), funStr.get());
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                             CTYPESMSG_CONV_ERROR_ARG,
+                             valStr, indexStr.get(), funStr.get());
     break;
   }
   case ConversionType::Finalizer: {
     MOZ_ASSERT(funObj);
 
     JS::UniqueChars funStr = FunctionTypeSourceForError(cx, funObj);
     if (!funStr) {
       return false;
     }
 
-    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                               CTYPESMSG_CONV_ERROR_FIN, valStr, funStr.get());
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                             CTYPESMSG_CONV_ERROR_FIN, valStr, funStr.get());
     break;
   }
   case ConversionType::Return: {
     MOZ_ASSERT(funObj);
 
     JS::UniqueChars funStr = FunctionTypeSourceForError(cx, funObj);
     if (!funStr) {
       return false;
     }
 
-    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                               CTYPESMSG_CONV_ERROR_RET, valStr, funStr.get());
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                             CTYPESMSG_CONV_ERROR_RET, valStr, funStr.get());
     break;
   }
   case ConversionType::Setter:
   case ConversionType::Construct:
     MOZ_ASSERT(!funObj);
 
-    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                               CTYPESMSG_CONV_ERROR_SET, valStr, expectedStr);
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                             CTYPESMSG_CONV_ERROR_SET, valStr, expectedStr);
     break;
   }
 
   return false;
 }
 
 static bool
 ConvError(JSContext* cx, HandleObject expectedType, HandleValue actual,
@@ -1369,35 +1373,37 @@ ConvError(JSContext* cx, HandleObject ex
   return ConvError(cx, expectedStr.get(), actual, convType, funObj, argIndex,
                    arrObj, arrIndex);
 }
 
 static bool
 ArgumentConvError(JSContext* cx, HandleValue actual, const char* funStr,
                   unsigned argIndex)
 {
+  MOZ_ASSERT(JS::StringIsASCII(funStr));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actual, valBytes);
   if (!valStr) {
     return false;
   }
 
   IndexCString indexStr(argIndex + 1);
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_CONV_ERROR_ARG, valStr, indexStr.get(), funStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_CONV_ERROR_ARG, valStr, indexStr.get(), funStr);
   return false;
 }
 
 static bool
 ArgumentLengthError(JSContext* cx, const char* fun, const char* count,
                     const char* s)
 {
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_WRONG_ARG_LENGTH, fun, count, s);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_WRONG_ARG_LENGTH, fun, count, s);
   return false;
 }
 
 static bool
 ArrayLengthMismatch(JSContext* cx, unsigned expectedLength, HandleObject arrObj,
                     unsigned actualLength, HandleValue actual,
                     ConversionType convType)
 {
@@ -1412,19 +1418,19 @@ ArrayLengthMismatch(JSContext* cx, unsig
   IndexCString expectedLengthStr(expectedLength);
   IndexCString actualLengthStr(actualLength);
 
   JS::UniqueChars arrStr = TypeSourceForError(cx, arrObj);
   if (!arrStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_ARRAY_MISMATCH,
-                             valStr, arrStr.get(), expectedLengthStr.get(), actualLengthStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_ARRAY_MISMATCH,
+                           valStr, arrStr.get(), expectedLengthStr.get(), actualLengthStr.get());
   return false;
 }
 
 static bool
 ArrayLengthOverflow(JSContext* cx, unsigned expectedLength, HandleObject arrObj,
                     unsigned actualLength, HandleValue actual,
                     ConversionType convType)
 {
@@ -1439,19 +1445,19 @@ ArrayLengthOverflow(JSContext* cx, unsig
   IndexCString expectedLengthStr(expectedLength);
   IndexCString actualLengthStr(actualLength);
 
   JS::UniqueChars arrStr = TypeSourceForError(cx, arrObj);
   if (!arrStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_ARRAY_OVERFLOW,
-                             valStr, arrStr.get(), expectedLengthStr.get(), actualLengthStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_ARRAY_OVERFLOW,
+                           valStr, arrStr.get(), expectedLengthStr.get(), actualLengthStr.get());
   return false;
 }
 
 static bool
 ArgumentRangeMismatch(JSContext* cx, const char* func, const char* range)
 {
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             CTYPESMSG_ARG_RANGE_MISMATCH, func, range);
@@ -1473,23 +1479,23 @@ CannotConstructError(JSContext* cx, cons
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             CTYPESMSG_CANNOT_CONSTRUCT, type);
   return false;
 }
 
 static bool
 DuplicateFieldError(JSContext* cx, Handle<JSFlatString*> name)
 {
-  JS::UniqueChars nameStr = JS_EncodeStringToLatin1(cx, name);
+  JS::UniqueChars nameStr = JS_EncodeStringToUTF8(cx, name);
   if (!nameStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_DUPLICATE_FIELD, nameStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_DUPLICATE_FIELD, nameStr.get());
   return false;
 }
 
 static bool
 EmptyFinalizerCallError(JSContext* cx, const char* funName)
 {
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             CTYPESMSG_EMPTY_FIN_CALL, funName);
@@ -1503,18 +1509,18 @@ EmptyFinalizerError(JSContext* cx, Conve
   JS::UniqueChars posStr;
   if (funObj) {
     posStr = ConversionPositionForError(cx, convType, funObj, argIndex);
     if (!posStr) {
       return false;
     }
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_EMPTY_FIN, (posStr ? posStr.get() : ""));
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_EMPTY_FIN, (posStr ? posStr.get() : ""));
   return false;
 }
 
 static bool
 FieldCountMismatch(JSContext* cx,
                    unsigned expectedCount, HandleObject structObj,
                    unsigned actualCount, HandleValue actual,
                    ConversionType convType,
@@ -1539,127 +1545,127 @@ FieldCountMismatch(JSContext* cx,
   JS::UniqueChars posStr;
   if (funObj) {
     posStr = ConversionPositionForError(cx, convType, funObj, argIndex);
     if (!posStr) {
       return false;
     }
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_MISMATCH,
-                             valStr, structStr.get(), expectedCountStr.get(), actualCountStr.get(),
-                             (posStr ? posStr.get() : ""));
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_MISMATCH,
+                           valStr, structStr.get(), expectedCountStr.get(), actualCountStr.get(),
+                           (posStr ? posStr.get() : ""));
   return false;
 }
 
 static bool
 FieldDescriptorCountError(JSContext* cx, HandleValue typeVal, size_t length)
 {
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, typeVal, valBytes);
   if (!valStr) {
     return false;
   }
 
   IndexCString lengthStr(length);
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_DESC_COUNT, valStr, lengthStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_DESC_COUNT, valStr, lengthStr.get());
   return false;
 }
 
 static bool
 FieldDescriptorNameError(JSContext* cx, HandleId id)
 {
   JS::UniqueChars idBytes;
   RootedValue idVal(cx, IdToValue(id));
   const char* propStr = CTypesToSourceForError(cx, idVal, idBytes);
   if (!propStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_DESC_NAME, propStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_DESC_NAME, propStr);
   return false;
 }
 
 static bool
 FieldDescriptorSizeError(JSContext* cx, HandleObject typeObj, HandleId id)
 {
   RootedValue typeVal(cx, ObjectValue(*typeObj));
   JS::UniqueChars typeBytes;
   const char* typeStr = CTypesToSourceForError(cx, typeVal, typeBytes);
   if (!typeStr) {
     return false;
   }
 
   RootedString idStr(cx, IdToString(cx, id));
-  JS::UniqueChars propStr = JS_EncodeStringToLatin1(cx, idStr);
+  JS::UniqueChars propStr = JS_EncodeStringToUTF8(cx, idStr);
   if (!propStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_DESC_SIZE, typeStr, propStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_DESC_SIZE, typeStr, propStr.get());
   return false;
 }
 
 static bool
 FieldDescriptorNameTypeError(JSContext* cx, HandleValue typeVal)
 {
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, typeVal, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_DESC_NAMETYPE, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_DESC_NAMETYPE, valStr);
   return false;
 }
 
 static bool
 FieldDescriptorTypeError(JSContext* cx, HandleValue poroVal, HandleId id)
 {
   JS::UniqueChars typeBytes;
   const char* typeStr = CTypesToSourceForError(cx, poroVal, typeBytes);
   if (!typeStr) {
     return false;
   }
 
   RootedString idStr(cx, IdToString(cx, id));
-  JS::UniqueChars propStr = JS_EncodeStringToLatin1(cx, idStr);
+  JS::UniqueChars propStr = JS_EncodeStringToUTF8(cx, idStr);
   if (!propStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_DESC_TYPE, typeStr, propStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_DESC_TYPE, typeStr, propStr.get());
   return false;
 }
 
 static bool
 FieldMissingError(JSContext* cx, JSObject* typeObj, JSFlatString* name_)
 {
   JS::UniqueChars typeBytes;
   RootedString name(cx, name_);
   RootedValue typeVal(cx, ObjectValue(*typeObj));
   const char* typeStr = CTypesToSourceForError(cx, typeVal, typeBytes);
   if (!typeStr) {
     return false;
   }
 
-  JS::UniqueChars nameStr = JS_EncodeStringToLatin1(cx, name);
+  JS::UniqueChars nameStr = JS_EncodeStringToUTF8(cx, name);
   if (!nameStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIELD_MISSING, typeStr, nameStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIELD_MISSING, typeStr, nameStr.get());
   return false;
 }
 
 static bool
 FinalizerSizeError(JSContext* cx, HandleObject funObj, HandleValue actual)
 {
   MOZ_ASSERT(CType::IsCType(funObj));
 
@@ -1669,18 +1675,18 @@ FinalizerSizeError(JSContext* cx, Handle
     return false;
   }
 
   JS::UniqueChars funStr = FunctionTypeSourceForError(cx, funObj);
   if (!funStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_FIN_SIZE_ERROR, funStr.get(), valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_FIN_SIZE_ERROR, funStr.get(), valStr);
   return false;
 }
 
 static bool
 FunctionArgumentLengthMismatch(JSContext* cx,
                                unsigned expectedCount, unsigned actualCount,
                                HandleObject funObj, HandleObject typeObj,
                                bool isVariadic)
@@ -1696,131 +1702,142 @@ FunctionArgumentLengthMismatch(JSContext
     return false;
   }
 
   IndexCString expectedCountStr(expectedCount);
   IndexCString actualCountStr(actualCount);
 
   const char* variadicStr = isVariadic ? " or more": "";
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_ARG_COUNT_MISMATCH,
-                             funStr.get(), expectedCountStr.get(), variadicStr,
-                             actualCountStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_ARG_COUNT_MISMATCH,
+                           funStr.get(), expectedCountStr.get(), variadicStr,
+                           actualCountStr.get());
   return false;
 }
 
 static bool
 FunctionArgumentTypeError(JSContext* cx,
                           uint32_t index, HandleValue typeVal, const char* reason)
 {
+  MOZ_ASSERT(JS::StringIsASCII(reason));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, typeVal, valBytes);
   if (!valStr) {
     return false;
   }
 
   IndexCString indexStr(index + 1);
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_ARG_TYPE_ERROR,
-                             indexStr.get(), reason, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_ARG_TYPE_ERROR,
+                           indexStr.get(), reason, valStr);
   return false;
 }
 
 static bool
 FunctionReturnTypeError(JSContext* cx, HandleValue type, const char* reason)
 {
+  MOZ_ASSERT(JS::StringIsASCII(reason));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, type, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_RET_TYPE_ERROR, reason, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_RET_TYPE_ERROR, reason, valStr);
   return false;
 }
 
 static bool
 IncompatibleCallee(JSContext* cx, const char* funName, HandleObject actualObj)
 {
+  MOZ_ASSERT(JS::StringIsASCII(funName));
+
   JS::UniqueChars valBytes;
   RootedValue val(cx, ObjectValue(*actualObj));
   const char* valStr = CTypesToSourceForError(cx, val, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_INCOMPATIBLE_CALLEE, funName, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_INCOMPATIBLE_CALLEE, funName, valStr);
   return false;
 }
 
 static bool
 IncompatibleThisProto(JSContext* cx, const char* funName,
                       const char* actualType)
 {
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_INCOMPATIBLE_THIS,
-                             funName, actualType);
+  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                            CTYPESMSG_INCOMPATIBLE_THIS,
+                            funName, actualType);
   return false;
 }
 
 static bool
 IncompatibleThisProto(JSContext* cx, const char* funName, HandleValue actualVal)
 {
+  MOZ_ASSERT(JS::StringIsASCII(funName));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actualVal, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_INCOMPATIBLE_THIS_VAL,
-                             funName, "incompatible object", valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_INCOMPATIBLE_THIS_VAL,
+                           funName, "incompatible object", valStr);
   return false;
 }
 
 static bool
 IncompatibleThisType(JSContext* cx, const char* funName, const char* actualType)
 {
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             CTYPESMSG_INCOMPATIBLE_THIS_TYPE,
                             funName, actualType);
   return false;
 }
 
 static bool
 IncompatibleThisType(JSContext* cx, const char* funName, const char* actualType,
                      HandleValue actualVal)
 {
+  MOZ_ASSERT(JS::StringIsASCII(funName));
+  MOZ_ASSERT(JS::StringIsASCII(actualType));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actualVal, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_INCOMPATIBLE_THIS_VAL,
-                             funName, actualType, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_INCOMPATIBLE_THIS_VAL,
+                           funName, actualType, valStr);
   return false;
 }
 
 static bool
 InvalidIndexError(JSContext* cx, HandleValue val)
 {
   JS::UniqueChars idBytes;
   const char* indexStr = CTypesToSourceForError(cx, val, idBytes);
   if (!indexStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_INVALID_INDEX, indexStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_INVALID_INDEX, indexStr);
   return false;
 }
 
 static bool
 InvalidIndexError(JSContext* cx, HandleId id)
 {
   RootedValue idVal(cx, IdToValue(id));
   return InvalidIndexError(cx, idVal);
@@ -1842,47 +1859,49 @@ NonPrimitiveError(JSContext* cx, HandleO
 {
   MOZ_ASSERT(CType::IsCType(typeObj));
 
   JS::UniqueChars typeStr = TypeSourceForError(cx, typeObj);
   if (!typeStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_NON_PRIMITIVE, typeStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_NON_PRIMITIVE, typeStr.get());
   return false;
 }
 
 static bool
 NonStringBaseError(JSContext* cx, HandleValue thisVal)
 {
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, thisVal, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_NON_STRING_BASE, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_NON_STRING_BASE, valStr);
   return false;
 }
 
 static bool
 NullPointerError(JSContext* cx, const char* action, HandleObject obj)
 {
+  MOZ_ASSERT(JS::StringIsASCII(action));
+
   JS::UniqueChars valBytes;
   RootedValue val(cx, ObjectValue(*obj));
   const char* valStr = CTypesToSourceForError(cx, val, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_NULL_POINTER, action, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_NULL_POINTER, action, valStr);
   return false;
 }
 
 static bool
 PropNameNonStringError(JSContext* cx, HandleId id, HandleValue actual,
                        ConversionType convType,
                        HandleObject funObj = nullptr, unsigned argIndex = 0)
 {
@@ -1902,68 +1921,72 @@ PropNameNonStringError(JSContext* cx, Ha
   JS::UniqueChars posStr;
   if (funObj) {
     posStr = ConversionPositionForError(cx, convType, funObj, argIndex);
     if (!posStr) {
       return false;
     }
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_PROP_NONSTRING, propStr, valStr,
-                             (posStr ? posStr.get() : ""));
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_PROP_NONSTRING, propStr, valStr,
+                           (posStr ? posStr.get() : ""));
   return false;
 }
 
 static bool
 SizeOverflow(JSContext* cx, const char* name, const char* limit)
 {
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                             CTYPESMSG_SIZE_OVERFLOW, name, limit);
   return false;
 }
 
 static bool
 TypeError(JSContext* cx, const char* expected, HandleValue actual)
 {
+  MOZ_ASSERT(JS::StringIsASCII(expected));
+
   JS::UniqueChars bytes;
   const char* src = CTypesToSourceForError(cx, actual, bytes);
   if (!src) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_TYPE_ERROR, expected, src);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_TYPE_ERROR, expected, src);
   return false;
 }
 
 static bool
 TypeOverflow(JSContext* cx, const char* expected, HandleValue actual)
 {
+  MOZ_ASSERT(JS::StringIsASCII(expected));
+
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actual, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_TYPE_OVERFLOW, valStr, expected);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_TYPE_OVERFLOW, valStr, expected);
   return false;
 }
 
 static bool
 UndefinedSizeCastError(JSContext* cx, HandleObject targetTypeObj)
 {
   JS::UniqueChars targetTypeStr = TypeSourceForError(cx, targetTypeObj);
   if (!targetTypeStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_UNDEFINED_SIZE_CAST, targetTypeStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_UNDEFINED_SIZE_CAST, targetTypeStr.get());
   return false;
 }
 
 static bool
 SizeMismatchCastError(JSContext* cx,
                       HandleObject sourceTypeObj, HandleObject targetTypeObj,
                       size_t sourceSize, size_t targetSize)
 {
@@ -1975,51 +1998,53 @@ SizeMismatchCastError(JSContext* cx,
   JS::UniqueChars targetTypeStr = TypeSourceForError(cx, targetTypeObj);
   if (!targetTypeStr) {
     return false;
   }
 
   IndexCString sourceSizeStr(sourceSize);
   IndexCString targetSizeStr(targetSize);
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_SIZE_MISMATCH_CAST,
-                             targetTypeStr.get(), sourceTypeStr.get(),
-                             targetSizeStr.get(), sourceSizeStr.get());
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_SIZE_MISMATCH_CAST,
+                           targetTypeStr.get(), sourceTypeStr.get(),
+                           targetSizeStr.get(), sourceSizeStr.get());
   return false;
 }
 
 static bool
 UndefinedSizePointerError(JSContext* cx, const char* action, HandleObject obj)
 {
+  MOZ_ASSERT(JS::StringIsASCII(action));
+
   JS::UniqueChars valBytes;
   RootedValue val(cx, ObjectValue(*obj));
   const char* valStr = CTypesToSourceForError(cx, val, valBytes);
   if (!valStr) {
     return false;
   }
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_UNDEFINED_SIZE, action, valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_UNDEFINED_SIZE, action, valStr);
   return false;
 }
 
 static bool
 VariadicArgumentTypeError(JSContext* cx, uint32_t index, HandleValue actual)
 {
   JS::UniqueChars valBytes;
   const char* valStr = CTypesToSourceForError(cx, actual, valBytes);
   if (!valStr) {
     return false;
   }
 
   IndexCString indexStr(index + 1);
 
-  JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
-                             CTYPESMSG_VARG_TYPE_ERROR, indexStr.get(), valStr);
+  JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+                           CTYPESMSG_VARG_TYPE_ERROR, indexStr.get(), valStr);
   return false;
 }
 
 MOZ_MUST_USE JSObject*
 GetThisObject(JSContext* cx, const CallArgs& args, const char* msg)
 {
   if (!args.thisv().isObject()) {
     IncompatibleThisProto(cx, msg, args.thisv());
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1694,19 +1694,19 @@ JS::GetFirstArgumentAsTypeHint(JSContext
 
     UniqueChars bytes;
     const char* source = ValueToSourceForError(cx, args.get(0), bytes);
     if (!source) {
         ReportOutOfMemory(cx);
         return false;
     }
 
-    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                               "Symbol.toPrimitive",
-                               "\"string\", \"number\", or \"default\"", source);
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                             "Symbol.toPrimitive",
+                             "\"string\", \"number\", or \"default\"", source);
     return false;
 }
 
 JS_PUBLIC_API(JSObject*)
 JS_InitClass(JSContext* cx, HandleObject obj, HandleObject parent_proto,
              const JSClass* clasp, JSNative constructor, unsigned nargs,
              const JSPropertySpec* ps, const JSFunctionSpec* fs,
              const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs)
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -1156,27 +1156,27 @@ js::ValueToSourceForError(JSContext* cx,
             return "<<error converting value to string>>";
         }
     } else if (val.isString()) {
         if (!sb.append("the string ")) {
             return "<<error converting value to string>>";
         }
     } else {
         MOZ_ASSERT(val.isBoolean() || val.isSymbol());
-        bytes = EncodeLatin1(cx, str);
+        bytes = StringToNewUTF8CharsZ(cx, *str);
         return bytes.get();
     }
     if (!sb.append(str)) {
         return "<<error converting value to string>>";
     }
     str = sb.finishString();
     if (!str) {
         return "<<error converting value to string>>";
     }
-    bytes = EncodeLatin1(cx, str);
+    bytes = StringToNewUTF8CharsZ(cx, *str);
     return bytes.get();
 }
 
 bool
 js::GetInternalError(JSContext* cx, unsigned errorNumber, MutableHandleValue error)
 {
     FixedInvokeArgs<1> args(cx);
     args[0].set(Int32Value(errorNumber));
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -90,30 +90,30 @@ js::ReportNotObject(JSContext* cx, Handl
 
 void
 js::ReportNotObjectArg(JSContext* cx, const char* nth, const char* fun, HandleValue v)
 {
     MOZ_ASSERT(!v.isObject());
 
     UniqueChars bytes;
     if (const char* chars = ValueToSourceForError(cx, v, bytes)) {
-        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT_ARG,
-                                   nth, fun, chars);
+        JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT_ARG,
+                                 nth, fun, chars);
     }
 }
 
 void
 js::ReportNotObjectWithName(JSContext* cx, const char* name, HandleValue v)
 {
     MOZ_ASSERT(!v.isObject());
 
     UniqueChars bytes;
     if (const char* chars = ValueToSourceForError(cx, v, bytes)) {
-        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT_NAME,
-                                   name, chars);
+        JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT_NAME,
+                                 name, chars);
     }
 }
 
 JS_PUBLIC_API(const char*)
 JS::InformalValueTypeName(const Value& v)
 {
     if (v.isObject()) {
         return v.toObject().getClass()->name;