Bug 1289050 - Part 8: Use ASCII or UTF8 variant of JS_ReportErrorNumber in non-simple cases. r=jwalden
authorTooru Fujisawa <arai_a@mac.com>
Mon, 15 Aug 2016 23:05:04 +0900
changeset 315957 f970fe55ff6cbf39fca00df19b0894ad0830fbd9
parent 315956 4e98bedb1102a74111da7d7bcdba99f7f9adae37
child 315958 245a2abe284edd7049699224ef26df239cef99fa
push id20634
push usercbook@mozilla.com
push dateFri, 30 Sep 2016 10:10:13 +0000
treeherderfx-team@afe79b010d13 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs1289050
milestone52.0a1
Bug 1289050 - Part 8: Use ASCII or UTF8 variant of JS_ReportErrorNumber in non-simple cases. r=jwalden
dom/plugins/base/nsJSNPRuntime.cpp
dom/system/OSFileConstants.cpp
js/src/asmjs/WasmBinaryToAST.cpp
js/src/asmjs/WasmJS.cpp
js/src/asmjs/WasmModule.cpp
js/src/builtin/Object.cpp
js/src/builtin/Promise.cpp
js/src/builtin/Reflect.cpp
js/src/builtin/TestingFunctions.cpp
js/src/builtin/TypedObject.cpp
js/src/ctypes/CTypes.cpp
js/src/jsapi.cpp
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/json.cpp
js/src/jsopcode.cpp
js/src/jsstr.cpp
js/src/perf/jsperf.cpp
js/src/proxy/BaseProxyHandler.cpp
js/src/proxy/OpaqueCrossCompartmentWrapper.cpp
js/src/proxy/ScriptedProxyHandler.cpp
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/src/vm/DebuggerMemory.cpp
js/src/vm/ErrorObject.cpp
js/src/vm/Interpreter.cpp
js/src/vm/JSONParser.cpp
js/src/vm/SavedStacks.cpp
js/src/vm/TraceLogging.cpp
js/src/vm/TypedArrayObject.cpp
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -1790,19 +1790,19 @@ NPObjWrapper_toPrimitive(JSContext *cx, 
     return false;
   if (v.isObject() && JS::IsCallable(&v.toObject())) {
     if (!JS_CallFunctionValue(cx, obj, v, JS::HandleValueArray::empty(), args.rval()))
       return false;
     if (args.rval().isPrimitive())
       return true;
   }
 
-  JS_ReportErrorNumber(cx, js::GetErrorMessage, nullptr, JSMSG_CANT_CONVERT_TO,
-                       JS_GetClass(obj)->name,
-                       "primitive type");
+  JS_ReportErrorNumberASCII(cx, js::GetErrorMessage, nullptr,
+                            JSMSG_CANT_CONVERT_TO,
+                            JS_GetClass(obj)->name, "primitive type");
   return false;
 }
 
 bool
 nsNPObjWrapper::IsWrapper(JSObject *obj)
 {
   return js::GetObjectClass(obj) == &sNPObjectJSWrapperClass;
 }
--- a/dom/system/OSFileConstants.cpp
+++ b/dom/system/OSFileConstants.cpp
@@ -836,18 +836,19 @@ JSObject *GetOrCreateObjectProperty(JSCo
   if (!JS_GetProperty(cx, aObject, aProperty, &val)) {
     return nullptr;
   }
   if (!val.isUndefined()) {
     if (val.isObject()) {
       return &val.toObject();
     }
 
-    JS_ReportErrorNumber(cx, js::GetErrorMessage, nullptr,
-      JSMSG_UNEXPECTED_TYPE, aProperty, "not an object");
+    JS_ReportErrorNumberASCII(cx, js::GetErrorMessage, nullptr,
+                              JSMSG_UNEXPECTED_TYPE,
+                              aProperty, "not an object");
     return nullptr;
   }
   return JS_DefineObject(cx, aObject, aProperty, nullptr, JSPROP_ENUMERATE);
 }
 
 /**
  * Set a property of an object from a nsString.
  *
--- a/js/src/asmjs/WasmBinaryToAST.cpp
+++ b/js/src/asmjs/WasmBinaryToAST.cpp
@@ -2138,18 +2138,18 @@ wasm::BinaryToAst(JSContext* cx, const u
         !AstDecodeExportSection(c) ||
         !AstDecodeStartSection(c) ||
         !AstDecodeElemSection(c) ||
         !AstDecodeCodeSection(c) ||
         !AstDecodeDataSection(c) ||
         !DecodeUnknownSections(c.d))
     {
         if (error) {
-            JS_ReportErrorNumber(c.cx, GetErrorMessage, nullptr, JSMSG_WASM_COMPILE_ERROR,
-                                 error.get());
+            JS_ReportErrorNumberASCII(c.cx, GetErrorMessage, nullptr, JSMSG_WASM_COMPILE_ERROR,
+                                      error.get());
             return false;
         }
         ReportOutOfMemory(c.cx);
         return false;
     }
 
     MOZ_ASSERT(!error, "unreported error in decoding");
 
--- a/js/src/asmjs/WasmJS.cpp
+++ b/js/src/asmjs/WasmJS.cpp
@@ -180,17 +180,17 @@ ThrowBadImportArg(JSContext* cx)
 {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMPORT_ARG);
     return false;
 }
 
 static bool
 ThrowBadImportField(JSContext* cx, const char* str)
 {
-    JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMPORT_FIELD, str);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMPORT_FIELD, str);
     return false;
 }
 
 static bool
 GetProperty(JSContext* cx, HandleObject obj, const char* chars, MutableHandleValue v)
 {
     JSAtom* atom = AtomizeUTF8Chars(cx, chars, strlen(chars));
     if (!atom)
@@ -356,18 +356,18 @@ wasm::Eval(JSContext* cx, Handle<TypedAr
     CompileArgs compileArgs;
     if (!compileArgs.initFromContext(cx, Move(scriptedCaller)))
         return false;
 
     UniqueChars error;
     SharedModule module = Compile(*bytecode, compileArgs, &error);
     if (!module) {
         if (error) {
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_COMPILE_ERROR,
-                                 error.get());
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_COMPILE_ERROR,
+                                      error.get());
             return false;
         }
         ReportOutOfMemory(cx);
         return false;
     }
 
     Rooted<FunctionVector> funcs(cx, FunctionVector(cx));
     RootedWasmTableObject table(cx);
@@ -436,17 +436,18 @@ static bool
 ToNonWrappingUint32(JSContext* cx, HandleValue v, uint32_t max, const char* kind, const char* noun,
                     uint32_t* u32)
 {
     double dbl;
     if (!ToInteger(cx, v, &dbl))
         return false;
 
     if (dbl < 0 || dbl > max) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_UINT32, kind, noun);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_UINT32,
+                                  kind, noun);
         return false;
     }
 
     *u32 = uint32_t(dbl);
     MOZ_ASSERT(double(*u32) == dbl);
     return true;
 }
 
@@ -477,18 +478,18 @@ GetResizableLimits(JSContext* cx, Handle
         if (!GetProperty(cx, obj, obj, maximumId, &maxVal))
             return false;
 
         limits->maximum.emplace();
         if (!ToNonWrappingUint32(cx, maxVal, max, kind, "maximum size", limits->maximum.ptr()))
             return false;
 
         if (limits->initial > *limits->maximum) {
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_UINT32,
-                                 kind, "maximum size");
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_UINT32,
+                                      kind, "maximum size");
             return false;
         }
     }
 
     return true;
 }
 
 // ============================================================================
@@ -592,18 +593,18 @@ WasmModuleObject::construct(JSContext* c
     CompileArgs compileArgs;
     if (!GetCompileArgs(cx, callArgs, "WebAssembly.Module", &bytecode, &compileArgs))
         return false;
 
     UniqueChars error;
     SharedModule module = Compile(*bytecode, compileArgs, &error);
     if (!module) {
         if (error) {
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_COMPILE_ERROR,
-                                 error.get());
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_COMPILE_ERROR,
+                                      error.get());
             return false;
         }
         ReportOutOfMemory(cx);
         return false;
     }
 
     RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmModule).toObject());
     RootedObject moduleObj(cx, WasmModuleObject::create(cx, *module, proto));
--- a/js/src/asmjs/WasmModule.cpp
+++ b/js/src/asmjs/WasmModule.cpp
@@ -510,22 +510,24 @@ CheckResizableLimits(JSContext* cx, uint
     if (isAsmJS) {
         MOZ_ASSERT(actualLength >= declaredMin);
         MOZ_ASSERT(!declaredMax);
         MOZ_ASSERT(actualLength == actualMax.value());
         return true;
     }
 
     if (actualLength < declaredMin || actualLength > declaredMax.valueOr(UINT32_MAX)) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMP_SIZE, kind);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMP_SIZE,
+                                  kind);
         return false;
     }
 
     if ((actualMax && (!declaredMax || *actualMax > *declaredMax)) || (!actualMax && declaredMax)) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMP_MAX, kind);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMP_MAX,
+                                  kind);
         return false;
     }
 
     return true;
 }
 
 // asm.js module instantiation supplies its own buffer, but for wasm, create and
 // initialize the buffer if one is requested. Either way, the buffer is wrapped
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -446,18 +446,19 @@ obj_setPrototypeOf(JSContext* cx, unsign
     if (args[0].isNullOrUndefined()) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_CONVERT_TO,
                                   args[0].isNull() ? "null" : "undefined", "object");
         return false;
     }
 
     /* Step 3. */
     if (!args[1].isObjectOrNull()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                             "Object.setPrototypeOf", "an object or null", InformalValueTypeName(args[1]));
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                  "Object.setPrototypeOf", "an object or null",
+                                  InformalValueTypeName(args[1]));
         return false;
     }
 
     /* Step 4. */
     if (!args[0].isObject()) {
         args.rval().set(args[0]);
         return true;
     }
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -588,17 +588,17 @@ CommonStaticResolveRejectImpl(JSContext*
     CallArgs args = CallArgsFromVp(argc, vp);
     RootedValue x(cx, args.get(0));
 
     // Steps 1-2.
     if (!args.thisv().isObject()) {
         const char* msg = mode == ResolveMode
                           ? "Receiver of Promise.resolve call"
                           : "Receiver of Promise.reject call";
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, msg);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, msg);
         return false;
     }
     RootedValue cVal(cx, args.thisv());
     RootedObject C(cx, &cVal.toObject());
 
     // Step 3 of Resolve.
     if (mode == ResolveMode && x.isObject()) {
         RootedObject xObj(cx, &x.toObject());
--- a/js/src/builtin/Reflect.cpp
+++ b/js/src/builtin/Reflect.cpp
@@ -323,19 +323,19 @@ Reflect_setPrototypeOf(JSContext* cx, un
 
     // Step 1.
     RootedObject obj(cx, NonNullObject(cx, args.get(0)));
     if (!obj)
         return false;
 
     // Step 2.
     if (!args.get(1).isObjectOrNull()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                             "Reflect.setPrototypeOf", "an object or null",
-                             InformalValueTypeName(args.get(1)));
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                  "Reflect.setPrototypeOf", "an object or null",
+                                  InformalValueTypeName(args.get(1)));
         return false;
     }
     RootedObject proto(cx, args.get(1).toObjectOrNull());
 
     // Step 4.
     ObjectOpResult result;
     if (!SetPrototype(cx, obj, proto, result))
         return false;
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -537,18 +537,18 @@ WasmTextToBinary(JSContext* cx, unsigned
             ReportUsageErrorASCII(cx, callee, "Second argument, if present, must be a String");
             return false;
         }
     }
 
     wasm::Bytes bytes;
     UniqueChars error;
     if (!wasm::TextToBinary(twoByteChars.twoByteChars(), &bytes, &error)) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_TEXT_FAIL,
-                             error.get() ? error.get() : "out of memory");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_WASM_TEXT_FAIL,
+                                  error.get() ? error.get() : "out of memory");
         return false;
     }
 
     RootedObject obj(cx, JS_NewUint8Array(cx, bytes.length()));
     if (!obj)
         return false;
 
     memcpy(obj->as<TypedArrayObject>().viewDataUnshared(), bytes.begin(), bytes.length());
@@ -962,29 +962,29 @@ NondeterministicGetWeakMapKeys(JSContext
     CallArgs args = CallArgsFromVp(argc, vp);
 
     if (args.length() != 1) {
         RootedObject callee(cx, &args.callee());
         ReportUsageErrorASCII(cx, callee, "Wrong number of arguments");
         return false;
     }
     if (!args[0].isObject()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                             "nondeterministicGetWeakMapKeys", "WeakMap",
-                             InformalValueTypeName(args[0]));
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                  "nondeterministicGetWeakMapKeys", "WeakMap",
+                                  InformalValueTypeName(args[0]));
         return false;
     }
     RootedObject arr(cx);
     RootedObject mapObj(cx, &args[0].toObject());
     if (!JS_NondeterministicGetWeakMapKeys(cx, mapObj, &arr))
         return false;
     if (!arr) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                             "nondeterministicGetWeakMapKeys", "WeakMap",
-                             args[0].toObject().getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                  "nondeterministicGetWeakMapKeys", "WeakMap",
+                                  args[0].toObject().getClass()->name);
         return false;
     }
     args.rval().setObject(*arr);
     return true;
 }
 
 class HasChildTracer : public JS::CallbackTracer
 {
@@ -3179,19 +3179,19 @@ SetDiscardSource(JSContext* cx, unsigned
 static bool
 GetConstructorName(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (!args.requireAtLeast(cx, "getConstructorName", 1))
         return false;
 
     if (!args[0].isObject()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                             "getConstructorName", "Object",
-                             InformalValueTypeName(args[0]));
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                  "getConstructorName", "Object",
+                                  InformalValueTypeName(args[0]));
         return false;
     }
 
     RootedAtom name(cx);
     if (!args[0].toObject().constructorDisplayAtom(cx, &name))
         return false;
 
     if (name) {
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -45,18 +45,18 @@ static const JSFunctionSpec TypedObjectM
     JS_SELF_HOSTED_FN("objectType", "TypeOfTypedObject", 1, 0),
     JS_SELF_HOSTED_FN("storage", "StorageOfTypedObject", 1, 0),
     JS_FS_END
 };
 
 static void
 ReportCannotConvertTo(JSContext* cx, HandleValue fromValue, const char* toType)
 {
-    JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_CONVERT_TO,
-                         InformalValueTypeName(fromValue), toType);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_CONVERT_TO,
+                              InformalValueTypeName(fromValue), toType);
 }
 
 template<class T>
 static inline T*
 ToObjectIf(HandleValue value)
 {
     if (!value.isObject())
         return nullptr;
@@ -263,18 +263,18 @@ ScalarTypeDescr::typeName(Type type)
     MOZ_CRASH("Invalid type");
 }
 
 bool
 ScalarTypeDescr::call(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() < 1) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
-                             args.callee().getClass()->name, "0", "s");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
+                                  args.callee().getClass()->name, "0", "s");
         return false;
     }
 
     Rooted<ScalarTypeDescr*> descr(cx, &args.callee().as<ScalarTypeDescr>());
     ScalarTypeDescr::Type type = descr->type();
 
     double number;
     if (!ToNumber(cx, args[0], &number))
@@ -374,19 +374,18 @@ bool
 js::ReferenceTypeDescr::call(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     MOZ_ASSERT(args.callee().is<ReferenceTypeDescr>());
     Rooted<ReferenceTypeDescr*> descr(cx, &args.callee().as<ReferenceTypeDescr>());
 
     if (args.length() < 1) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                             JSMSG_MORE_ARGS_NEEDED,
-                             descr->typeName(), "0", "s");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
+                                  descr->typeName(), "0", "s");
         return false;
     }
 
     switch (descr->type()) {
       case ReferenceTypeDescr::TYPE_ANY:
         args.rval().set(args[0]);
         return true;
 
@@ -1586,24 +1585,22 @@ TypedObject::createZeroed(JSContext* cx,
 }
 
 static bool
 ReportTypedObjTypeError(JSContext* cx,
                         const unsigned errorNumber,
                         HandleTypedObject obj)
 {
     // Serialize type string of obj
-    char* typeReprStr = JS_EncodeString(cx, &obj->typeDescr().stringRepr());
+    RootedAtom typeReprAtom(cx, &obj->typeDescr().stringRepr());
+    UniqueChars typeReprStr(JS_EncodeStringToUTF8(cx, typeReprAtom));
     if (!typeReprStr)
         return false;
 
-    JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                         errorNumber, typeReprStr);
-
-    JS_free(cx, (void*) typeReprStr);
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, errorNumber, typeReprStr.get());
     return false;
 }
 
 /* static */ void
 OutlineTypedObject::obj_trace(JSTracer* trc, JSObject* object)
 {
     OutlineTypedObject& typedObj = object->as<OutlineTypedObject>();
 
@@ -1695,24 +1692,21 @@ ReportPropertyError(JSContext* cx,
                     const unsigned errorNumber,
                     HandleId id)
 {
     RootedValue idVal(cx, IdToValue(id));
     RootedString str(cx, ValueToSource(cx, idVal));
     if (!str)
         return false;
 
-    char* propName = JS_EncodeString(cx, str);
+    UniqueChars propName(JS_EncodeStringToUTF8(cx, str));
     if (!propName)
         return false;
 
-    JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                         errorNumber, propName);
-
-    JS_free(cx, propName);
+    JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, errorNumber, propName.get());
     return false;
 }
 
 bool
 TypedObject::obj_defineProperty(JSContext* cx, HandleObject obj, HandleId id,
                                 Handle<PropertyDescriptor> desc,
                                 ObjectOpResult& result)
 {
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -1344,35 +1344,35 @@ ArrayLengthOverflow(JSContext* cx, unsig
                        valStr, arrStr, expectedLengthStr, actualLengthStr);
   return false;
 }
 
 static bool
 ArgumentRangeMismatch(JSContext* cx, const char* arg, const char* func,
                      const char* range)
 {
-  JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                       CTYPESMSG_ARG_RANGE_MISMATCH, arg, func, range);
+  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                            CTYPESMSG_ARG_RANGE_MISMATCH, arg, func, range);
   return false;
 }
 
 static bool
 ArgumentTypeMismatch(JSContext* cx, const char* arg, const char* func,
                      const char* type)
 {
-  JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                       CTYPESMSG_ARG_TYPE_MISMATCH, arg, func, type);
+  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                            CTYPESMSG_ARG_TYPE_MISMATCH, arg, func, type);
   return false;
 }
 
 static bool
 CannotConstructError(JSContext* cx, const char* type)
 {
-  JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                       CTYPESMSG_CANNOT_CONSTRUCT, type);
+  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                            CTYPESMSG_CANNOT_CONSTRUCT, type);
   return false;
 }
 
 static bool
 DuplicateFieldError(JSContext* cx, Handle<JSFlatString*> name)
 {
   JSAutoByteString nameBytes;
   const char* nameStr = nameBytes.encodeLatin1(cx, name);
@@ -1382,18 +1382,18 @@ DuplicateFieldError(JSContext* cx, Handl
   JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                        CTYPESMSG_DUPLICATE_FIELD, nameStr);
   return false;
 }
 
 static bool
 EmptyFinalizerCallError(JSContext* cx, const char* funName)
 {
-  JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                       CTYPESMSG_EMPTY_FIN_CALL, funName);
+  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                            CTYPESMSG_EMPTY_FIN_CALL, funName);
   return false;
 }
 
 static bool
 EmptyFinalizerError(JSContext* cx, ConversionType convType,
                     HandleObject funObj = nullptr, unsigned argIndex = 0)
 {
   JSAutoByteString posBytes;
@@ -1683,18 +1683,19 @@ IncompatibleThisProto(JSContext* cx, con
                        CTYPESMSG_INCOMPATIBLE_THIS_VAL,
                        funName, "incompatible object", valStr);
   return false;
 }
 
 static bool
 IncompatibleThisType(JSContext* cx, const char* funName, const char* actualType)
 {
-  JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                       CTYPESMSG_INCOMPATIBLE_THIS_TYPE, funName, 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)
 {
   JSAutoByteString valBytes;
@@ -1732,18 +1733,18 @@ static bool
 InvalidIndexRangeError(JSContext* cx, size_t index, size_t length)
 {
   char indexStr[16];
   SprintfLiteral(indexStr, "%" PRIuSIZE, index);
 
   char lengthStr[16];
   SprintfLiteral(lengthStr,"%" PRIuSIZE, length);
 
-  JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                       CTYPESMSG_INVALID_RANGE, indexStr, lengthStr);
+  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                            CTYPESMSG_INVALID_RANGE, indexStr, lengthStr);
   return false;
 }
 
 static bool
 NonPrimitiveError(JSContext* cx, HandleObject typeObj)
 {
   MOZ_ASSERT(CType::IsCType(typeObj));
 
@@ -1817,18 +1818,18 @@ PropNameNonStringError(JSContext* cx, Ha
   JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                        CTYPESMSG_PROP_NONSTRING, propStr, valStr, posStr);
   return false;
 }
 
 static bool
 SizeOverflow(JSContext* cx, const char* name, const char* limit)
 {
-  JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                       CTYPESMSG_SIZE_OVERFLOW, name, limit);
+  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                            CTYPESMSG_SIZE_OVERFLOW, name, limit);
   return false;
 }
 
 static bool
 TypeError(JSContext* cx, const char* expected, HandleValue actual)
 {
   JSAutoByteString bytes;
   const char* src = CTypesToSourceForError(cx, actual, bytes);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -117,18 +117,18 @@ using JS::ToUint32;
 #endif
 
 bool
 JS::CallArgs::requireAtLeast(JSContext* cx, const char* fnname, unsigned required) const
 {
     if (length() < required) {
         char numArgsStr[40];
         SprintfLiteral(numArgsStr, "%u", required - 1);
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
-                             fnname, numArgsStr, required == 2 ? "" : "s");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
+                                  fnname, numArgsStr, required == 2 ? "" : "s");
         return false;
     }
 
     return true;
 }
 
 static bool
 ErrorTakesArguments(unsigned msg)
@@ -1584,20 +1584,20 @@ JS::ToPrimitive(JSContext* cx, HandleObj
     vp.setObject(*obj);
     return ToPrimitiveSlow(cx, hint, vp);
 }
 
 JS_PUBLIC_API(bool)
 JS::GetFirstArgumentAsTypeHint(JSContext* cx, CallArgs args, JSType *result)
 {
     if (!args.get(0).isString()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                             "Symbol.toPrimitive",
-                             "\"string\", \"number\", or \"default\"",
-                             InformalValueTypeName(args.get(0)));
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                  "Symbol.toPrimitive",
+                                  "\"string\", \"number\", or \"default\"",
+                                  InformalValueTypeName(args.get(0)));
         return false;
     }
 
     RootedString str(cx, args.get(0).toString());
     bool match;
 
     if (!EqualStrings(cx, str, cx->names().default_, &match))
         return false;
@@ -1726,18 +1726,18 @@ JS_GetConstructor(JSContext* cx, HandleO
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, proto);
 
     RootedValue cval(cx);
     if (!GetProperty(cx, proto, proto, cx->names().constructor, &cval))
         return nullptr;
     if (!IsFunctionObject(cval)) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NO_CONSTRUCTOR,
-                             proto->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NO_CONSTRUCTOR,
+                                  proto->getClass()->name);
         return nullptr;
     }
     return &cval.toObject();
 }
 
 bool
 JS::CompartmentBehaviors::extraWarnings(JSContext* cx) const
 {
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -853,18 +853,18 @@ ErrorReport::init(JSContext* cx, HandleV
     if (str)
         message_ = bytesStorage.encodeUtf8(cx, str);
     if (!message_)
         message_ = "unknown (can't convert to string)";
 
     if (!reportp) {
         // This is basically an inlined version of
         //
-        //   JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-        //                        JSMSG_UNCAUGHT_EXCEPTION, message_);
+        //   JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
+        //                            JSMSG_UNCAUGHT_EXCEPTION, message_);
         //
         // but without the reporting bits.  Instead it just puts all
         // the stuff we care about in our ownedReport and message_.
         if (!populateUncaughtExceptionReportUTF8(cx, message_)) {
             // Just give up.  We're out of memory or something; not much we can
             // do here.
             return false;
         }
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1136,20 +1136,19 @@ js::FunctionToString(JSContext* cx, Hand
 
 JSString*
 fun_toStringHelper(JSContext* cx, HandleObject obj, unsigned indent)
 {
     if (!obj->is<JSFunction>()) {
         if (JSFunToStringOp op = obj->getOpsFunToString())
             return op(cx, obj, indent);
 
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                             JSMSG_INCOMPATIBLE_PROTO,
-                             js_Function_str, js_toString_str,
-                             "object");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                                  JSMSG_INCOMPATIBLE_PROTO,
+                                  js_Function_str, js_toString_str, "object");
         return nullptr;
     }
 
     RootedFunction fun(cx, &obj->as<JSFunction>());
     return FunctionToString(cx, fun, indent != JS_DONT_PRETTY_PRINT);
 }
 
 bool
@@ -1283,18 +1282,18 @@ js::fun_apply(JSContext* cx, unsigned ar
         if (!args2.init(iter.numActualArgs()))
             return false;
 
         // Steps 7-8.
         iter.unaliasedForEachActual(cx, CopyTo(args2.array()));
     } else {
         // Step 3.
         if (!args[1].isObject()) {
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                                 JSMSG_BAD_APPLY_ARGS, js_apply_str);
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                                      JSMSG_BAD_APPLY_ARGS, js_apply_str);
             return false;
         }
 
         // Steps 4-5 (note erratum removing steps originally numbered 5 and 7 in
         // original version of ES5).
         RootedObject aobj(cx, &args[1].toObject());
         uint32_t length;
         if (!GetLengthProperty(cx, aobj, &length))
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -882,17 +882,17 @@ ComputePrecisionInRange(JSContext* cx, i
 {
     if (minPrecision <= prec && prec <= maxPrecision) {
         *precision = int(prec);
         return true;
     }
 
     ToCStringBuf cbuf;
     if (char* numStr = NumberToCString(cx, &cbuf, prec, 10))
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PRECISION_RANGE, numStr);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_PRECISION_RANGE, numStr);
     return false;
 }
 
 static bool
 DToStrResult(JSContext* cx, double d, JSDToStrMode mode, int precision, const CallArgs& args)
 {
     char buf[DTOSTR_VARIABLE_BUFFER_SIZE(MAX_PRECISION + 1)];
     char* numStr = js_dtostr(cx->mainThread().dtoaState, buf, sizeof buf, mode, precision, d);
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -186,18 +186,18 @@ js::FromPropertyDescriptorToObject(JSCon
     return true;
 }
 
 bool
 js::GetFirstArgumentAsObject(JSContext* cx, const CallArgs& args, const char* method,
                              MutableHandleObject objp)
 {
     if (args.length() == 0) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
-                             method, "0", "s");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
+                                  method, "0", "s");
         return false;
     }
 
     HandleValue v = args[0];
     if (!v.isObject()) {
         UniqueChars bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, nullptr);
         if (!bytes)
             return false;
@@ -257,18 +257,18 @@ js::Throw(JSContext* cx, JSObject* obj, 
 
 
 /*** PropertyDescriptor operations and DefineProperties ******************************************/
 
 bool
 CheckCallable(JSContext* cx, JSObject* obj, const char* fieldName)
 {
     if (obj && !obj->isCallable()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_GET_SET_FIELD,
-                             fieldName);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_GET_SET_FIELD,
+                                  fieldName);
         return false;
     }
     return true;
 }
 
 bool
 js::ToPropertyDescriptor(JSContext* cx, HandleValue descval, bool checkAccessors,
                          MutableHandle<PropertyDescriptor> desc)
@@ -335,36 +335,36 @@ js::ToPropertyDescriptor(JSContext* cx, 
         return false;
     hasGetOrSet = found;
     if (found) {
         if (v.isObject()) {
             if (checkAccessors && !CheckCallable(cx, &v.toObject(), js_getter_str))
                 return false;
             desc.setGetterObject(&v.toObject());
         } else if (!v.isUndefined()) {
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_GET_SET_FIELD,
-                                 js_getter_str);
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_GET_SET_FIELD,
+                                      js_getter_str);
             return false;
         }
         attrs |= JSPROP_GETTER | JSPROP_SHARED;
     }
 
     // step 9
     id = NameToId(cx->names().set);
     if (!GetPropertyIfPresent(cx, obj, id, &v, &found))
         return false;
     hasGetOrSet |= found;
     if (found) {
         if (v.isObject()) {
             if (checkAccessors && !CheckCallable(cx, &v.toObject(), js_setter_str))
                 return false;
             desc.setSetterObject(&v.toObject());
         } else if (!v.isUndefined()) {
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_GET_SET_FIELD,
-                                 js_setter_str);
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_GET_SET_FIELD,
+                                      js_setter_str);
             return false;
         }
         attrs |= JSPROP_SETTER | JSPROP_SHARED;
     }
 
     // step 10
     if (hasGetOrSet) {
         if (!(attrs & JSPROP_IGNORE_READONLY) || !(attrs & JSPROP_IGNORE_VALUE)) {
@@ -2834,18 +2834,18 @@ js::UnwatchGuts(JSContext* cx, JS::Handl
 
 bool
 js::WatchProperty(JSContext* cx, HandleObject obj, HandleId id, HandleObject callable)
 {
     if (WatchOp op = obj->getOpsWatch())
         return op(cx, obj, id, callable);
 
     if (!obj->isNative() || obj->is<TypedArrayObject>()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_WATCH,
-                             obj->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_WATCH,
+                                  obj->getClass()->name);
         return false;
     }
 
     return WatchGuts(cx, obj, id, callable);
 }
 
 bool
 js::UnwatchProperty(JSContext* cx, HandleObject obj, HandleId id)
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -304,18 +304,18 @@ class CycleDetector
   public:
     CycleDetector(StringifyContext* scx, HandleObject obj)
       : stack(&scx->stack), obj_(obj) {
     }
 
     bool foundCycle(JSContext* cx) {
         auto addPtr = stack.lookupForAdd(obj_);
         if (addPtr) {
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_JSON_CYCLIC_VALUE,
-                                 js_object_str);
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_JSON_CYCLIC_VALUE,
+                                      js_object_str);
             return false;
         }
         if (!stack.add(addPtr, obj_)) {
             ReportOutOfMemory(cx);
             return false;
         }
         return true;
     }
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -926,18 +926,18 @@ unsigned
 js::Disassemble1(JSContext* cx, HandleScript script, jsbytecode* pc,
                  unsigned loc, bool lines, Sprinter* sp)
 {
     JSOp op = (JSOp)*pc;
     if (op >= JSOP_LIMIT) {
         char numBuf1[12], numBuf2[12];
         SprintfLiteral(numBuf1, "%d", op);
         SprintfLiteral(numBuf2, "%d", JSOP_LIMIT);
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                             JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BYTECODE_TOO_BIG,
+                                  numBuf1, numBuf2);
         return 0;
     }
     const JSCodeSpec* cs = &CodeSpec[op];
     ptrdiff_t len = (ptrdiff_t) cs->length;
     if (!sp->jsprintf("%05u:", loc))
         return 0;
     if (lines) {
         if (!sp->jsprintf("%4u", PCToLineNumber(script, pc)))
@@ -1111,18 +1111,17 @@ js::Disassemble1(JSContext* cx, HandleSc
       print_int:
         if (!sp->jsprintf(" %d", i))
             return 0;
         break;
 
       default: {
         char numBuf[12];
         SprintfLiteral(numBuf, "%x", cs->format);
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                             JSMSG_UNKNOWN_FORMAT, numBuf);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_UNKNOWN_FORMAT, numBuf);
         return 0;
       }
     }
     sp->put("\n");
     return len;
 }
 
 #endif /* DEBUG */
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -2786,17 +2786,17 @@ ToCodePoint(JSContext* cx, HandleValue c
     double nextCP;
     if (!ToNumber(cx, code, &nextCP))
         return false;
 
     // String.fromCodePoint, Steps 5.c-d.
     if (JS::ToInteger(nextCP) != nextCP || nextCP < 0 || nextCP > 0x10FFFF) {
         ToCStringBuf cbuf;
         if (char* numStr = NumberToCString(cx, &cbuf, nextCP))
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_A_CODEPOINT, numStr);
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_A_CODEPOINT, numStr);
         return false;
     }
 
     *codePoint = uint32_t(nextCP);
     return true;
 }
 
 static bool
--- a/js/src/perf/jsperf.cpp
+++ b/js/src/perf/jsperf.cpp
@@ -231,18 +231,18 @@ GetPM(JSContext* cx, JS::HandleValue val
     RootedObject obj(cx, &value.toObject());
     PerfMeasurement* p = (PerfMeasurement*)
         JS_GetInstancePrivate(cx, obj, &pm_class, nullptr);
     if (p)
         return p;
 
     // JS_GetInstancePrivate only sets an exception if its last argument
     // is nonzero, so we have to do it by hand.
-    JS_ReportErrorNumber(cx, GetErrorMessage, 0, JSMSG_INCOMPATIBLE_PROTO,
-                         pm_class.name, fname, JS_GetClass(obj)->name);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, 0, JSMSG_INCOMPATIBLE_PROTO,
+                              pm_class.name, fname, JS_GetClass(obj)->name);
     return nullptr;
 }
 
 namespace JS {
 
 JSObject*
 RegisterPerfMeasurement(JSContext* cx, HandleObject globalArg)
 {
--- a/js/src/proxy/BaseProxyHandler.cpp
+++ b/js/src/proxy/BaseProxyHandler.cpp
@@ -416,18 +416,18 @@ BaseProxyHandler::setImmutablePrototype(
 {
     *succeeded = false;
     return true;
 }
 
 bool
 BaseProxyHandler::watch(JSContext* cx, HandleObject proxy, HandleId id, HandleObject callable) const
 {
-    JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_WATCH,
-                         proxy->getClass()->name);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_WATCH,
+                              proxy->getClass()->name);
     return false;
 }
 
 bool
 BaseProxyHandler::unwatch(JSContext* cx, HandleObject proxy, HandleId id) const
 {
     return true;
 }
--- a/js/src/proxy/OpaqueCrossCompartmentWrapper.cpp
+++ b/js/src/proxy/OpaqueCrossCompartmentWrapper.cpp
@@ -181,14 +181,14 @@ OpaqueCrossCompartmentWrapper::className
 {
     return "Opaque";
 }
 
 JSString*
 OpaqueCrossCompartmentWrapper::fun_toString(JSContext* cx, HandleObject proxy,
                                             unsigned indent) const
 {
-    JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO, js_Function_str,
-                         js_toString_str, "object");
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                              js_Function_str, js_toString_str, "object");
     return nullptr;
 }
 
 const OpaqueCrossCompartmentWrapper OpaqueCrossCompartmentWrapper::singleton;
--- a/js/src/proxy/ScriptedProxyHandler.cpp
+++ b/js/src/proxy/ScriptedProxyHandler.cpp
@@ -1257,18 +1257,18 @@ ScriptedProxyHandler::className(JSContex
 {
     // Right now the caller is not prepared to handle failures.
     return BaseProxyHandler::className(cx, proxy);
 }
 
 JSString*
 ScriptedProxyHandler::fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const
 {
-    JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                         js_Function_str, js_toString_str, "object");
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                              js_Function_str, js_toString_str, "object");
     return nullptr;
 }
 
 bool
 ScriptedProxyHandler::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const
 {
     MOZ_CRASH("Should not end up in ScriptedProxyHandler::regexp_toShared");
     return false;
@@ -1308,18 +1308,18 @@ IsRevokedScriptedProxy(JSObject* obj)
     return obj && IsScriptedProxy(obj) && !obj->as<ProxyObject>().target();
 }
 
 // ES8 rev 0c1bd3004329336774cbc90de727cd0cf5f11e93 9.5.14 ProxyCreate.
 static bool
 ProxyCreate(JSContext* cx, CallArgs& args, const char* callerName)
 {
     if (args.length() < 2) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
-                             callerName, "1", "s");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
+                                  callerName, "1", "s");
         return false;
     }
 
     // Step 1.
     RootedObject target(cx, NonNullObject(cx, args[0]));
     if (!target)
         return false;
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1701,18 +1701,18 @@ Evaluate(JSContext* cx, unsigned argc, V
         // replace the current bytecode by the same stream of bytes.
         if (loadBytecode && assertEqBytecode) {
             if (saveLength != loadLength) {
                 char loadLengthStr[16];
                 SprintfLiteral(loadLengthStr, "%" PRIu32, loadLength);
                 char saveLengthStr[16];
                 SprintfLiteral(saveLengthStr,"%" PRIu32, saveLength);
 
-                JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_CACHE_EQ_SIZE_FAILED,
-                                     loadLengthStr, saveLengthStr);
+                JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr, JSSMSG_CACHE_EQ_SIZE_FAILED,
+                                          loadLengthStr, saveLengthStr);
                 return false;
             }
 
             if (!PodEqual(loadBuffer, saveBuffer.get(), loadLength)) {
                 JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr,
                                           JSSMSG_CACHE_EQ_CONTENT_FAILED);
                 return false;
             }
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -405,18 +405,18 @@ NukeDebuggerWrapper(NativeObject *wrappe
     wrapper->setPrivate(nullptr);
 }
 
 static bool
 ValueToStableChars(JSContext* cx, const char *fnname, HandleValue value,
                    AutoStableStringChars& stableChars)
 {
     if (!value.isString()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                             fnname, "string", InformalValueTypeName(value));
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                  fnname, "string", InformalValueTypeName(value));
         return false;
     }
     RootedLinearString linear(cx, value.toString()->ensureLinear(cx));
     if (!linear)
         return false;
     if (!stableChars.initTwoByte(cx, linear))
         return false;
     return true;
@@ -1196,19 +1196,18 @@ Debugger::wrapDebuggeeObject(JSContext* 
 
     return true;
 }
 
 static NativeObject*
 ToNativeDebuggerObject(JSContext* cx, MutableHandleObject obj)
 {
     if (obj->getClass() != &DebuggerObject::class_) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                             JSMSG_NOT_EXPECTED_TYPE, "Debugger",
-                             "Debugger.Object", obj->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                  "Debugger", "Debugger.Object", obj->getClass()->name);
         return nullptr;
     }
 
     NativeObject* ndobj = &obj->as<NativeObject>();
 
     Value owner = ndobj->getReservedSlot(JSSLOT_DEBUGOBJECT_OWNER);
     if (owner.isUndefined()) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
@@ -1250,18 +1249,18 @@ Debugger::unwrapDebuggeeValue(JSContext*
     return true;
 }
 
 static bool
 CheckArgCompartment(JSContext* cx, JSObject* obj, JSObject* arg,
                     const char* methodname, const char* propname)
 {
     if (arg->compartment() != obj->compartment()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEBUG_COMPARTMENT_MISMATCH,
-                             methodname, propname);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEBUG_COMPARTMENT_MISMATCH,
+                                  methodname, propname);
         return false;
     }
     return true;
 }
 
 static bool
 CheckArgCompartment(JSContext* cx, JSObject* obj, HandleValue v,
                     const char* methodname, const char* propname)
@@ -3183,30 +3182,30 @@ const Class Debugger::class_ = {
 
 /* static */ Debugger*
 Debugger::fromThisValue(JSContext* cx, const CallArgs& args, const char* fnname)
 {
     JSObject* thisobj = NonNullObject(cx, args.thisv());
     if (!thisobj)
         return nullptr;
     if (thisobj->getClass() != &Debugger::class_) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger", fnname, thisobj->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger", fnname, thisobj->getClass()->name);
         return nullptr;
     }
 
     /*
      * Forbid Debugger.prototype, which is of the Debugger JSClass but isn't
      * really a Debugger object. The prototype object is distinguished by
      * having a nullptr private value.
      */
     Debugger* dbg = fromJSObject(thisobj);
     if (!dbg) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger", fnname, "prototype object");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger", fnname, "prototype object");
     }
     return dbg;
 }
 
 #define THIS_DEBUGGER(cx, argc, vp, fnname, args, dbg)                       \
     CallArgs args = CallArgsFromVp(argc, vp);                                \
     Debugger* dbg = Debugger::fromThisValue(cx, args, fnname);               \
     if (!dbg)                                                                \
@@ -5045,19 +5044,19 @@ bool
 Debugger::isCompilableUnit(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     if (!args.requireAtLeast(cx, "Debugger.isCompilableUnit", 1))
         return false;
 
     if (!args[0].isString()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                             JSMSG_NOT_EXPECTED_TYPE, "Debugger.isCompilableUnit",
-                             "string", InformalValueTypeName(args[0]));
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                  "Debugger.isCompilableUnit", "string",
+                                  InformalValueTypeName(args[0]));
         return false;
     }
 
     JSString* str = args[0].toString();
     size_t length = GetStringLength(str);
 
     AutoStableStringChars chars(cx);
     if (!chars.initTwoByte(cx, str))
@@ -5401,28 +5400,28 @@ Debugger::wrapWasmScript(JSContext* cx, 
 
 static JSObject*
 DebuggerScript_check(JSContext* cx, const Value& v, const char* fnname)
 {
     JSObject* thisobj = NonNullObject(cx, v);
     if (!thisobj)
         return nullptr;
     if (thisobj->getClass() != &DebuggerScript_class) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger.Script", fnname, thisobj->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger.Script", fnname, thisobj->getClass()->name);
         return nullptr;
     }
 
     /*
      * Check for Debugger.Script.prototype, which is of class DebuggerScript_class
      * but whose script is null.
      */
     if (!GetScriptReferentCell(thisobj)) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger.Script", fnname, "prototype object");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger.Script", fnname, "prototype object");
         return nullptr;
     }
 
     return thisobj;
 }
 
 template <typename ReferentT>
 static JSObject*
@@ -6796,26 +6795,26 @@ DebuggerSource_construct(JSContext* cx, 
 
 static NativeObject*
 DebuggerSource_check(JSContext* cx, HandleValue thisv, const char* fnname)
 {
     JSObject* thisobj = NonNullObject(cx, thisv);
     if (!thisobj)
         return nullptr;
     if (thisobj->getClass() != &DebuggerSource_class) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger.Source", fnname, thisobj->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger.Source", fnname, thisobj->getClass()->name);
         return nullptr;
     }
 
     NativeObject* nthisobj = &thisobj->as<NativeObject>();
 
     if (!GetSourceReferentRawObject(thisobj)) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger.Source", fnname, "prototype object");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger.Source", fnname, "prototype object");
         return nullptr;
     }
 
     return nthisobj;
 }
 
 template <typename ReferentT>
 static NativeObject*
@@ -7673,34 +7672,34 @@ DebuggerFrame_finalize(FreeOp* fop, JSOb
 
 /* static */ DebuggerFrame*
 DebuggerFrame::checkThis(JSContext* cx, const CallArgs& args, const char* fnname, bool checkLive)
 {
     JSObject* thisobj = NonNullObject(cx, args.thisv());
     if (!thisobj)
         return nullptr;
     if (thisobj->getClass() != &DebuggerFrame::class_) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger.Frame", fnname, thisobj->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger.Frame", fnname, thisobj->getClass()->name);
         return nullptr;
     }
 
     RootedDebuggerFrame frame(cx, &thisobj->as<DebuggerFrame>());
 
     /*
      * Forbid Debugger.Frame.prototype, which is of class DebuggerFrame::class_
      * but isn't really a working Debugger.Frame object. The prototype object
      * is distinguished by having a nullptr private value. Also, forbid popped
      * frames.
      */
     if (!frame->getPrivate() &&
         frame->getReservedSlot(JSSLOT_DEBUGFRAME_OWNER).isUndefined())
     {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger.Frame", fnname, "prototype object");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger.Frame", fnname, "prototype object");
         return nullptr;
     }
 
     if (checkLive && !DebuggerFrame::requireLive(cx, frame))
         return nullptr;
 
     return frame;
 }
@@ -7905,18 +7904,18 @@ DebuggerArguments_getArg(JSContext* cx, 
     CallArgs args = CallArgsFromVp(argc, vp);
     int32_t i = args.callee().as<JSFunction>().getExtendedSlot(0).toInt32();
 
     /* Check that the this value is an Arguments object. */
     RootedObject argsobj(cx, NonNullObject(cx, args.thisv()));
     if (!argsobj)
         return false;
     if (argsobj->getClass() != &DebuggerArguments_class) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Arguments", "getArgument", argsobj->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Arguments", "getArgument", argsobj->getClass()->name);
         return false;
     }
 
     /*
      * Put the Debugger.Frame into the this-value slot, then use THIS_FRAME
      * to check that it is still live and get the fp.
      */
     args.setThis(argsobj->as<NativeObject>().getReservedSlot(JSSLOT_DEBUGARGUMENTS_FRAME));
@@ -8259,30 +8258,30 @@ DebuggerObject_trace(JSTracer* trc, JSOb
 
 /* static */ DebuggerObject*
 DebuggerObject::checkThis(JSContext* cx, const CallArgs& args, const char* fnname)
 {
     JSObject* thisobj = NonNullObject(cx, args.thisv());
     if (!thisobj)
         return nullptr;
     if (thisobj->getClass() != &DebuggerObject::class_) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger.Object", fnname, thisobj->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger.Object", fnname, thisobj->getClass()->name);
         return nullptr;
     }
 
     /*
      * Forbid Debugger.Object.prototype, which is of class DebuggerObject::class_
      * but isn't a real working Debugger.Object. The prototype object is
      * distinguished by having no referent.
      */
     DebuggerObject* nthisobj = &thisobj->as<DebuggerObject>();
     if (!nthisobj->getPrivate()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger.Object", fnname, "prototype object");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger.Object", fnname, "prototype object");
         return nullptr;
     }
     return nthisobj;
 }
 
 #define THIS_DEBUGOBJECT(cx, argc, vp, fnname, args, object)                         \
     CallArgs args = CallArgsFromVp(argc, vp);                                        \
     RootedDebuggerObject object(cx, DebuggerObject::checkThis(cx, args, fnname)); \
@@ -8309,32 +8308,32 @@ DebuggerObject::checkThis(JSContext* cx,
 #define THIS_DEBUGOBJECT_PROMISE(cx, argc, vp, fnname, args, obj)                   \
    THIS_DEBUGOBJECT_REFERENT(cx, argc, vp, fnname, args, obj);                      \
    obj = CheckedUnwrap(obj);                                                        \
    if (!obj) {                                                                      \
        JS_ReportErrorASCII(cx, "Permission denied to access object");               \
        return false;                                                                \
    }                                                                                \
    if (!obj->is<PromiseObject>()) {                                                 \
-       JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,  \
-                            "Debugger", "Promise", obj->getClass()->name);          \
+       JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,\
+                                 "Debugger", "Promise", obj->getClass()->name);     \
        return false;                                                                \
    }                                                                                \
    Rooted<PromiseObject*> promise(cx, &obj->as<PromiseObject>());
 
 #define THIS_DEBUGOBJECT_OWNER_PROMISE(cx, argc, vp, fnname, args, dbg, obj)        \
    THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, fnname, args, dbg, obj);           \
    obj = CheckedUnwrap(obj);                                                        \
    if (!obj) {                                                                      \
        JS_ReportErrorASCII(cx, "Permission denied to access object");               \
        return false;                                                                \
    }                                                                                \
    if (!obj->is<PromiseObject>()) {                                                 \
-       JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,  \
-                            "Debugger", "Promise", obj->getClass()->name);          \
+       JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,\
+                                 "Debugger", "Promise", obj->getClass()->name);     \
        return false;                                                                \
    }                                                                                \
    Rooted<PromiseObject*> promise(cx, &obj->as<PromiseObject>());
 
 /* static */ bool
 DebuggerObject::construct(JSContext* cx, unsigned argc, Value* vp)
 {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NO_CONSTRUCTOR,
@@ -9092,18 +9091,18 @@ DebuggerObject::applyMethod(JSContext* c
 {
     THIS_DEBUGOBJECT(cx, argc, vp, "apply", callArgs, object);
 
     RootedValue thisv(cx, callArgs.get(0));
 
     Rooted<ValueVector> args(cx, ValueVector(cx));
     if (callArgs.length() >= 2 && !callArgs[1].isNullOrUndefined()) {
         if (!callArgs[1].isObject()) {
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_APPLY_ARGS,
-                                 js_apply_str);
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_APPLY_ARGS,
+                                      js_apply_str);
             return false;
         }
 
         RootedObject argsobj(cx, &callArgs[1].toObject());
 
         unsigned argc = 0;
         if (!GetLengthProperty(cx, argsobj, &argc))
             return false;
@@ -9902,18 +9901,18 @@ DebuggerObject::deleteProperty(JSContext
 /* static */ bool
 DebuggerObject::call(JSContext* cx, HandleDebuggerObject object, HandleValue thisv_,
                      Handle<ValueVector> args, MutableHandleValue result)
 {
     RootedObject referent(cx, object->referent());
     Debugger* dbg = object->owner();
 
     if (!referent->isCallable()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger.Object", "call", referent->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger.Object", "call", referent->getClass()->name);
         return false;
     }
 
     RootedValue calleev(cx, ObjectValue(*referent));
 
     /*
      * Unwrap Debugger.Objects. This happens in the debugger's compartment since
      * that is where any exceptions must be reported.
@@ -9964,19 +9963,19 @@ DebuggerObject::call(JSContext* cx, Hand
     return dbg->receiveCompletionValue(ac, ok, result, result);
 }
 
 /* static */ bool
 DebuggerObject::forceLexicalInitializationByName(JSContext* cx, HandleDebuggerObject object,
                                                  HandleId id, bool& result)
 {
     if (!JSID_IS_STRING(id)) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                             JSMSG_NOT_EXPECTED_TYPE, "Debugger.Object.prototype.forceLexicalInitializationByName",
-                             "string", InformalValueTypeName(IdToValue(id)));
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                  "Debugger.Object.prototype.forceLexicalInitializationByName",
+                                  "string", InformalValueTypeName(IdToValue(id)));
         return false;
     }
 
     MOZ_ASSERT(object->isGlobal());
 
     Rooted<GlobalObject*> referent(cx, &object->referent()->as<GlobalObject>());
 
     RootedObject globalLexical(cx, &referent->lexicalEnvironment());
@@ -10130,18 +10129,18 @@ DebuggerObject::requirePromise(JSContext
        referent = CheckedUnwrap(referent);
        if (!referent) {
            JS_ReportErrorASCII(cx, "Permission denied to access object");
            return false;
        }
    }
 
    if (!referent->is<PromiseObject>()) {
-      JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                           "Debugger", "Promise", object->getClass()->name);
+      JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                "Debugger", "Promise", object->getClass()->name);
       return false;
    }
 
    return true;
 }
 #endif // SPIDERMONKEY_PROMISE
 
 /* static */ bool
@@ -10194,30 +10193,30 @@ DebuggerEnv_trace(JSTracer* trc, JSObjec
 /* static */ DebuggerEnvironment*
 DebuggerEnvironment::checkThis(JSContext* cx, const CallArgs& args, const char* fnname,
                                bool requireDebuggee)
 {
     JSObject* thisobj = NonNullObject(cx, args.thisv());
     if (!thisobj)
         return nullptr;
     if (thisobj->getClass() != &DebuggerEnvironment::class_) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger.Environment", fnname, thisobj->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger.Environment", fnname, thisobj->getClass()->name);
         return nullptr;
     }
 
     /*
      * Forbid Debugger.Environment.prototype, which is of class DebuggerEnvironment::class_
      * but isn't a real working Debugger.Environment. The prototype object is
      * distinguished by having no referent.
      */
     DebuggerEnvironment* nthisobj = &thisobj->as<DebuggerEnvironment>();
     if (!nthisobj->getPrivate()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             "Debugger.Environment", fnname, "prototype object");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  "Debugger.Environment", fnname, "prototype object");
         return nullptr;
     }
 
     /*
      * Forbid access to Debugger.Environment objects that are not debuggee
      * environments.
      */
     if (requireDebuggee) {
--- a/js/src/vm/DebuggerMemory.cpp
+++ b/js/src/vm/DebuggerMemory.cpp
@@ -78,34 +78,35 @@ DebuggerMemory::construct(JSContext* cx,
 };
 
 /* static */ DebuggerMemory*
 DebuggerMemory::checkThis(JSContext* cx, CallArgs& args, const char* fnName)
 {
     const Value& thisValue = args.thisv();
 
     if (!thisValue.isObject()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, InformalValueTypeName(thisValue));
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT,
+                                  InformalValueTypeName(thisValue));
         return nullptr;
     }
 
     JSObject& thisObject = thisValue.toObject();
     if (!thisObject.is<DebuggerMemory>()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             class_.name, fnName, thisObject.getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  class_.name, fnName, thisObject.getClass()->name);
         return nullptr;
     }
 
     // Check for Debugger.Memory.prototype, which has the same class as
     // Debugger.Memory instances, however doesn't actually represent an instance
     // of Debugger.Memory. It is the only object that is<DebuggerMemory>() but
     // doesn't have a Debugger instance.
     if (thisObject.as<DebuggerMemory>().getReservedSlot(JSSLOT_DEBUGGER).isUndefined()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             class_.name, fnName, "prototype object");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  class_.name, fnName, "prototype object");
         return nullptr;
     }
 
     return &thisObject.as<DebuggerMemory>();
 }
 
 /**
  * Get the |DebuggerMemory*| from the current this value and handle any errors
--- a/js/src/vm/ErrorObject.cpp
+++ b/js/src/vm/ErrorObject.cpp
@@ -160,18 +160,18 @@ js::ErrorObject::getOrCreateErrorReport(
 
 /* static */ bool
 js::ErrorObject::checkAndUnwrapThis(JSContext* cx, CallArgs& args, const char* fnName,
                                     MutableHandle<ErrorObject*> error)
 {
     const Value& thisValue = args.thisv();
 
     if (!thisValue.isObject()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT,
-                             InformalValueTypeName(thisValue));
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT,
+                                  InformalValueTypeName(thisValue));
         return false;
     }
 
     // Walk up the prototype chain until we find the first ErrorObject that has
     // the slots we need. This allows us to support the poor-man's subclassing
     // of error: Object.create(Error.prototype).
 
     RootedObject target(cx, CheckedUnwrap(&thisValue.toObject()));
@@ -183,18 +183,18 @@ js::ErrorObject::checkAndUnwrapThis(JSCo
     RootedObject proto(cx);
     while (!target->is<ErrorObject>()) {
         if (!GetPrototype(cx, target, &proto))
             return false;
 
         if (!proto) {
             // We walked the whole prototype chain and did not find an Error
             // object.
-            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                                 js_Error_str, fnName, thisValue.toObject().getClass()->name);
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                      js_Error_str, fnName, thisValue.toObject().getClass()->name);
             return false;
         }
 
         target = CheckedUnwrap(proto);
         if (!target) {
             JS_ReportErrorASCII(cx, "Permission denied to access object");
             return false;
         }
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -4120,18 +4120,17 @@ END_CASE(JSOP_DEBUGCHECKSELFHOSTED)
 CASE(JSOP_IS_CONSTRUCTING)
     PUSH_MAGIC(JS_IS_CONSTRUCTING);
 END_CASE(JSOP_IS_CONSTRUCTING)
 
 DEFAULT()
 {
     char numBuf[12];
     SprintfLiteral(numBuf, "%d", *REGS.pc);
-    JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
-                         JSMSG_BAD_BYTECODE, numBuf);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_BYTECODE, numBuf);
     goto error;
 }
 
 } /* interpreter loop */
 
     MOZ_CRASH("Interpreter loop exited via fallthrough");
 
   error:
--- a/js/src/vm/JSONParser.cpp
+++ b/js/src/vm/JSONParser.cpp
@@ -90,18 +90,18 @@ JSONParser<CharT>::error(const char* msg
         getTextPosition(&column, &line);
 
         const size_t MaxWidth = sizeof("4294967295");
         char columnNumber[MaxWidth];
         SprintfLiteral(columnNumber, "%" PRIu32, column);
         char lineNumber[MaxWidth];
         SprintfLiteral(lineNumber, "%" PRIu32, line);
 
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_JSON_BAD_PARSE,
-                             msg, lineNumber, columnNumber);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_JSON_BAD_PARSE,
+                                  msg, lineNumber, columnNumber);
     }
 }
 
 bool
 JSONParserBase::errorReturn()
 {
     return errorHandling == NoError;
 }
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -603,34 +603,35 @@ GetFirstSubsumedSavedFrame(JSContext* cx
 
 /* static */ bool
 SavedFrame::checkThis(JSContext* cx, CallArgs& args, const char* fnName,
                       MutableHandleObject frame)
 {
     const Value& thisValue = args.thisv();
 
     if (!thisValue.isObject()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, InformalValueTypeName(thisValue));
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT,
+                                  InformalValueTypeName(thisValue));
         return false;
     }
 
     JSObject* thisObject = CheckedUnwrap(&thisValue.toObject());
     if (!thisObject || !thisObject->is<SavedFrame>()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             SavedFrame::class_.name, fnName,
-                             thisObject ? thisObject->getClass()->name : "object");
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  SavedFrame::class_.name, fnName,
+                                  thisObject ? thisObject->getClass()->name : "object");
         return false;
     }
 
     // Check for SavedFrame.prototype, which has the same class as SavedFrame
     // instances, however doesn't actually represent a captured stack frame. It
     // is the only object that is<SavedFrame>() but doesn't have a source.
-    if (thisObject->as<SavedFrame>().getReservedSlot(JSSLOT_SOURCE).isNull()) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
-                             SavedFrame::class_.name, fnName, "prototype object");
+    if (!SavedFrame::isSavedFrameAndNotProto(*thisObject)) {
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
+                                  SavedFrame::class_.name, fnName, "prototype object");
         return false;
     }
 
     // Now set "frame" to the actual object we were invoked in (which may be a
     // wrapper), not the unwrapped version.  Consumers will need to know what
     // that original object was, and will do principal checks as needed.
     frame.set(&thisValue.toObject());
     return true;
--- a/js/src/vm/TraceLogging.cpp
+++ b/js/src/vm/TraceLogging.cpp
@@ -188,17 +188,17 @@ TraceLoggerThread::enable()
     logTimestamp(TraceLogger_Enable);
 
     return true;
 }
 
 bool
 TraceLoggerThread::fail(JSContext* cx, const char* error)
 {
-    JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_TRACELOGGER_ENABLE_FAIL, error);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TRACELOGGER_ENABLE_FAIL, error);
     failed = true;
     enabled_ = 0;
 
     return false;
 }
 
 bool
 TraceLoggerThread::enable(JSContext* cx)
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -1600,18 +1600,18 @@ DataViewObject::create(JSContext* cx, ui
     return &dvobj;
 }
 
 bool
 DataViewObject::getAndCheckConstructorArgs(JSContext* cx, JSObject* bufobj, const CallArgs& args,
                                            uint32_t* byteOffsetPtr, uint32_t* byteLengthPtr)
 {
     if (!IsArrayBuffer(bufobj)) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                             "DataView", "ArrayBuffer", bufobj->getClass()->name);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
+                                  "DataView", "ArrayBuffer", bufobj->getClass()->name);
         return false;
     }
 
     Rooted<ArrayBufferObject*> buffer(cx, &AsArrayBuffer(bufobj));
     uint32_t byteOffset = 0;
     uint32_t byteLength = buffer->byteLength();
 
     if (args.length() > 1) {