Bug 1485066 - Part 5: Use js::EncodeLatin1/StringToNewUTF8CharsZ instead of JS_EncodeString[ToUTF8] for engine internal code. r=Waldo
☠☠ backed out by 3d23c2f43b8a ☠ ☠
authorAndré Bargull <andre.bargull@gmail.com>
Wed, 05 Sep 2018 01:25:10 -0700
changeset 434761 8defc9eabfac7b9d73551c99dcefb0da52438001
parent 434760 bf167b0a3af38a895690054de642027af9aafef3
child 434762 b08b0cfc1dbe100feece9c2085cb73d8577735ed
push id107490
push usercsabou@mozilla.com
push dateWed, 05 Sep 2018 12:25:08 +0000
treeherdermozilla-inbound@e40f67f15bf1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs1485066
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 1485066 - Part 5: Use js::EncodeLatin1/StringToNewUTF8CharsZ instead of JS_EncodeString[ToUTF8] for engine internal code. r=Waldo
js/src/builtin/ReflectParse.cpp
js/src/builtin/TypedObject.cpp
js/src/builtin/intl/Collator.cpp
js/src/builtin/intl/CommonFunctions.cpp
js/src/builtin/intl/CommonFunctions.h
js/src/builtin/intl/DateTimeFormat.cpp
js/src/builtin/intl/IntlObject.cpp
js/src/builtin/intl/NumberFormat.cpp
js/src/builtin/intl/PluralRules.cpp
js/src/builtin/intl/RelativeTimeFormat.cpp
js/src/jsapi.cpp
js/src/jsexn.cpp
js/src/proxy/ScriptedProxyHandler.cpp
js/src/vm/BytecodeUtil.cpp
js/src/vm/Interpreter.cpp
js/src/vm/JSFunction-inl.h
js/src/vm/JSObject.cpp
js/src/vm/NativeObject.cpp
js/src/vm/SelfHosting.cpp
js/src/vm/StringType.cpp
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -3389,17 +3389,17 @@ reflect_parse(JSContext* cx, uint32_t ar
             if (!GetPropertyDefault(cx, config, sourceId, nullVal, &prop))
                 return false;
 
             if (!prop.isNullOrUndefined()) {
                 RootedString str(cx, ToString<CanGC>(cx, prop));
                 if (!str)
                     return false;
 
-                filename = JS_EncodeString(cx, str);
+                filename = EncodeLatin1(cx, str);
                 if (!filename)
                     return false;
             }
 
             /* config.line */
             RootedId lineId(cx, NameToId(cx->names().line));
             RootedValue oneValue(cx, Int32Value(1));
             if (!GetPropertyDefault(cx, config, lineId, oneValue, &prop) ||
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -1594,17 +1594,17 @@ TypedObject::createZeroed(JSContext* cx,
 
 static bool
 ReportTypedObjTypeError(JSContext* cx,
                         const unsigned errorNumber,
                         HandleTypedObject obj)
 {
     // Serialize type string of obj
     RootedAtom typeReprAtom(cx, &obj->typeDescr().stringRepr());
-    UniqueChars typeReprStr = JS_EncodeStringToUTF8(cx, typeReprAtom);
+    UniqueChars typeReprStr = StringToNewUTF8CharsZ(cx, *typeReprAtom);
     if (!typeReprStr)
         return false;
 
     JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, errorNumber, typeReprStr.get());
     return false;
 }
 
 /* static */ void
@@ -1701,17 +1701,17 @@ ReportPropertyError(JSContext* cx,
                     const unsigned errorNumber,
                     HandleId id)
 {
     RootedValue idVal(cx, IdToValue(id));
     RootedString str(cx, ValueToSource(cx, idVal));
     if (!str)
         return false;
 
-    UniqueChars propName = JS_EncodeStringToUTF8(cx, str);
+    UniqueChars propName = StringToNewUTF8CharsZ(cx, *str);
     if (!propName)
         return false;
 
     JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, errorNumber, propName.get());
     return false;
 }
 
 bool
--- a/js/src/builtin/intl/Collator.cpp
+++ b/js/src/builtin/intl/Collator.cpp
@@ -195,17 +195,17 @@ js::intl_Collator_availableLocales(JSCon
 
 bool
 js::intl_availableCollations(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
     MOZ_ASSERT(args[0].isString());
 
-    UniqueChars locale = JS_EncodeString(cx, args[0].toString());
+    UniqueChars locale = intl::EncodeLocale(cx, args[0].toString());
     if (!locale)
         return false;
     UErrorCode status = U_ZERO_ERROR;
     UEnumeration* values = ucol_getKeywordValuesForLocale("co", locale.get(), false, &status);
     if (U_FAILURE(status)) {
         ReportInternalError(cx);
         return false;
     }
@@ -272,17 +272,17 @@ NewUCollator(JSContext* cx, Handle<Colla
     RootedValue value(cx);
 
     RootedObject internals(cx, intl::GetInternalsObject(cx, collator));
     if (!internals)
         return nullptr;
 
     if (!GetProperty(cx, internals, internals, cx->names().locale, &value))
         return nullptr;
-    UniqueChars locale = JS_EncodeString(cx, value.toString());
+    UniqueChars locale = intl::EncodeLocale(cx, value.toString());
     if (!locale)
         return nullptr;
 
     // UCollator options with default values.
     UColAttributeValue uStrength = UCOL_DEFAULT;
     UColAttributeValue uCaseLevel = UCOL_OFF;
     UColAttributeValue uAlternate = UCOL_DEFAULT;
     UColAttributeValue uNumeric = UCOL_OFF;
--- a/js/src/builtin/intl/CommonFunctions.cpp
+++ b/js/src/builtin/intl/CommonFunctions.cpp
@@ -4,16 +4,19 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Operations used to implement multiple Intl.* classes. */
 
 #include "builtin/intl/CommonFunctions.h"
 
 #include "mozilla/Assertions.h"
+#include "mozilla/TextUtils.h"
+
+#include <algorithm>
 
 #include "jsfriendapi.h" // for GetErrorMessage, JSMSG_INTERNAL_INTL_ERROR
 
 #include "js/Value.h"
 #include "vm/JSContext.h"
 #include "vm/JSObject.h"
 #include "vm/SelfHosting.h"
 #include "vm/Stack.h"
@@ -77,16 +80,42 @@ js::intl::GetInternalsObject(JSContext* 
 }
 
 void
 js::intl::ReportInternalError(JSContext* cx)
 {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
 }
 
+js::UniqueChars
+js::intl::EncodeLocale(JSContext* cx, JSString* locale)
+{
+#ifdef DEBUG
+    auto containsOnlyValidBCP47Chars = [](auto* chars, size_t length) {
+        return length > 0 &&
+               mozilla::IsAsciiAlpha(chars[0]) &&
+               std::all_of(chars, chars + length, [](auto c) {
+                   return mozilla::IsAsciiAlphanumeric(c) || c == '-';
+               });
+    };
+
+    if (JSLinearString* linear = locale->ensureLinear(cx)) {
+        JS::AutoCheckCannotGC nogc;
+        MOZ_ASSERT(linear->hasLatin1Chars()
+                   ? containsOnlyValidBCP47Chars(linear->latin1Chars(nogc), linear->length())
+                   : containsOnlyValidBCP47Chars(linear->twoByteChars(nogc), linear->length()));
+    } else {
+        // Ignore OOM when only performing a debug assertion.
+        cx->recoverFromOutOfMemory();
+    }
+#endif
+
+    return EncodeLatin1(cx, locale);
+}
+
 bool
 js::intl::GetAvailableLocales(JSContext* cx, CountAvailable countAvailable,
                               GetAvailable getAvailable, JS::MutableHandle<JS::Value> result)
 {
     RootedObject locales(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr));
     if (!locales)
         return false;
 
--- a/js/src/builtin/intl/CommonFunctions.h
+++ b/js/src/builtin/intl/CommonFunctions.h
@@ -67,16 +67,19 @@ static inline const char*
 IcuLocale(const char* locale)
 {
     if (StringsAreEqual(locale, "und"))
         return ""; // ICU root locale
 
     return locale;
 }
 
+extern UniqueChars
+EncodeLocale(JSContext* cx, JSString* locale);
+
 // Starting with ICU 59, UChar defaults to char16_t.
 static_assert(mozilla::IsSame<UChar, char16_t>::value,
               "SpiderMonkey doesn't support redefining UChar to a different type");
 
 // The inline capacity we use for a Vector<char16_t>.  Use this to ensure that
 // our uses of ICU string functions, below and elsewhere, will try to fill the
 // buffer's entire inline capacity before growing it and heap-allocating.
 constexpr size_t INITIAL_CHAR_BUFFER_SIZE = 32;
--- a/js/src/builtin/intl/DateTimeFormat.cpp
+++ b/js/src/builtin/intl/DateTimeFormat.cpp
@@ -278,17 +278,17 @@ const CalendarAlias calendarAliases[] = 
 
 bool
 js::intl_availableCalendars(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
     MOZ_ASSERT(args[0].isString());
 
-    UniqueChars locale = JS_EncodeString(cx, args[0].toString());
+    UniqueChars locale = intl::EncodeLocale(cx, args[0].toString());
     if (!locale)
         return false;
 
     RootedObject calendars(cx, NewDenseEmptyArray(cx));
     if (!calendars)
         return false;
     uint32_t index = 0;
 
@@ -355,17 +355,17 @@ js::intl_availableCalendars(JSContext* c
 
 bool
 js::intl_defaultCalendar(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
     MOZ_ASSERT(args[0].isString());
 
-    UniqueChars locale = JS_EncodeString(cx, args[0].toString());
+    UniqueChars locale = intl::EncodeLocale(cx, args[0].toString());
     if (!locale)
         return false;
 
     return DefaultCalendar(cx, locale, args.rval());
 }
 
 bool
 js::intl_IsValidTimeZoneName(JSContext* cx, unsigned argc, Value* vp)
@@ -522,17 +522,17 @@ js::intl_isDefaultTimeZone(JSContext* cx
 bool
 js::intl_patternForSkeleton(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
     MOZ_ASSERT(args[0].isString());
     MOZ_ASSERT(args[1].isString());
 
-    UniqueChars locale = JS_EncodeString(cx, args[0].toString());
+    UniqueChars locale = intl::EncodeLocale(cx, args[0].toString());
     if (!locale)
         return false;
 
     AutoStableStringChars skeleton(cx);
     if (!skeleton.initTwoByte(cx, args[1].toString()))
         return false;
 
     mozilla::Range<const char16_t> skelChars = skeleton.twoByteRange();
@@ -559,17 +559,17 @@ js::intl_patternForSkeleton(JSContext* c
 
 bool
 js::intl_patternForStyle(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 4);
     MOZ_ASSERT(args[0].isString());
 
-    UniqueChars locale = JS_EncodeString(cx, args[0].toString());
+    UniqueChars locale = intl::EncodeLocale(cx, args[0].toString());
     if (!locale)
         return false;
 
     UDateFormatStyle dateStyle = UDAT_NONE;
     UDateFormatStyle timeStyle = UDAT_NONE;
 
     if (args[1].isString()) {
         JSLinearString* dateStyleStr = args[1].toString()->ensureLinear(cx);
@@ -640,17 +640,17 @@ NewUDateFormat(JSContext* cx, Handle<Dat
     RootedValue value(cx);
 
     RootedObject internals(cx, intl::GetInternalsObject(cx, dateTimeFormat));
     if (!internals)
        return nullptr;
 
     if (!GetProperty(cx, internals, internals, cx->names().locale, &value))
         return nullptr;
-    UniqueChars locale = JS_EncodeString(cx, value.toString());
+    UniqueChars locale = intl::EncodeLocale(cx, value.toString());
     if (!locale)
         return nullptr;
 
     // We don't need to look at calendar and numberingSystem - they can only be
     // set via the Unicode locale extension and are therefore already set on
     // locale.
 
     if (!GetProperty(cx, internals, internals, cx->names().timeZone, &value))
--- a/js/src/builtin/intl/IntlObject.cpp
+++ b/js/src/builtin/intl/IntlObject.cpp
@@ -45,17 +45,17 @@ using js::intl::IcuLocale;
 /******************** Intl ********************/
 
 bool
 js::intl_GetCalendarInfo(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
 
-    UniqueChars locale = JS_EncodeString(cx, args[0].toString());
+    UniqueChars locale = intl::EncodeLocale(cx, args[0].toString());
     if (!locale)
         return false;
 
     UErrorCode status = U_ZERO_ERROR;
     const UChar* uTimeZone = nullptr;
     int32_t uTimeZoneLength = 0;
     UCalendar* cal = ucal_open(uTimeZone, uTimeZoneLength, locale.get(), UCAL_DEFAULT, &status);
     if (U_FAILURE(status)) {
@@ -365,18 +365,17 @@ ComputeSingleDisplayName(JSContext* cx, 
 
 bool
 js::intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 3);
 
     // 1. Assert: locale is a string.
-    RootedString str(cx, args[0].toString());
-    UniqueChars locale = JS_EncodeStringToUTF8(cx, str);
+    UniqueChars locale = intl::EncodeLocale(cx, args[0].toString());
     if (!locale)
         return false;
 
     // 2. Assert: style is a string.
     DisplayNameStyle dnStyle;
     {
         JSLinearString* style = args[1].toString()->ensureLinear(cx);
         if (!style)
@@ -456,17 +455,17 @@ js::intl_ComputeDisplayNames(JSContext* 
 }
 
 bool
 js::intl_GetLocaleInfo(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
 
-    UniqueChars locale = JS_EncodeString(cx, args[0].toString());
+    UniqueChars locale = intl::EncodeLocale(cx, args[0].toString());
     if (!locale)
         return false;
 
     RootedObject info(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!info)
         return false;
 
     if (!DefineDataProperty(cx, info, cx->names().locale, args[0]))
--- a/js/src/builtin/intl/NumberFormat.cpp
+++ b/js/src/builtin/intl/NumberFormat.cpp
@@ -209,17 +209,17 @@ js::intl_NumberFormat_availableLocales(J
 
 bool
 js::intl_numberingSystem(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
     MOZ_ASSERT(args[0].isString());
 
-    UniqueChars locale = JS_EncodeString(cx, args[0].toString());
+    UniqueChars locale = intl::EncodeLocale(cx, args[0].toString());
     if (!locale)
         return false;
 
     UErrorCode status = U_ZERO_ERROR;
     UNumberingSystem* numbers = unumsys_open(IcuLocale(locale.get()), &status);
     if (U_FAILURE(status)) {
         intl::ReportInternalError(cx);
         return false;
@@ -251,17 +251,17 @@ NewUNumberFormat(JSContext* cx, Handle<N
     RootedValue value(cx);
 
     RootedObject internals(cx, intl::GetInternalsObject(cx, numberFormat));
     if (!internals)
        return nullptr;
 
     if (!GetProperty(cx, internals, internals, cx->names().locale, &value))
         return nullptr;
-    UniqueChars locale = JS_EncodeString(cx, value.toString());
+    UniqueChars locale = intl::EncodeLocale(cx, value.toString());
     if (!locale)
         return nullptr;
 
     // UNumberFormat options with default values
     UNumberFormatStyle uStyle = UNUM_DECIMAL;
     const UChar* uCurrency = nullptr;
     uint32_t uMinimumIntegerDigits = 1;
     uint32_t uMinimumFractionDigits = 0;
--- a/js/src/builtin/intl/PluralRules.cpp
+++ b/js/src/builtin/intl/PluralRules.cpp
@@ -191,17 +191,17 @@ NewUNumberFormatForPluralRules(JSContext
     RootedObject internals(cx, intl::GetInternalsObject(cx, pluralRules));
     if (!internals)
        return nullptr;
 
     RootedValue value(cx);
 
     if (!GetProperty(cx, internals, internals, cx->names().locale, &value))
         return nullptr;
-    UniqueChars locale = JS_EncodeString(cx, value.toString());
+    UniqueChars locale = intl::EncodeLocale(cx, value.toString());
     if (!locale)
         return nullptr;
 
     uint32_t uMinimumIntegerDigits = 1;
     uint32_t uMinimumFractionDigits = 0;
     uint32_t uMaximumFractionDigits = 3;
     int32_t uMinimumSignificantDigits = -1;
     int32_t uMaximumSignificantDigits = -1;
@@ -264,17 +264,17 @@ NewUPluralRules(JSContext* cx, Handle<Pl
     RootedObject internals(cx, intl::GetInternalsObject(cx, pluralRules));
     if (!internals)
         return nullptr;
 
     RootedValue value(cx);
 
     if (!GetProperty(cx, internals, internals, cx->names().locale, &value))
         return nullptr;
-    UniqueChars locale = JS_EncodeString(cx, value.toString());
+    UniqueChars locale = intl::EncodeLocale(cx, value.toString());
     if (!locale)
         return nullptr;
 
     if (!GetProperty(cx, internals, internals, cx->names().type, &value))
         return nullptr;
 
     UPluralType category;
     {
--- a/js/src/builtin/intl/RelativeTimeFormat.cpp
+++ b/js/src/builtin/intl/RelativeTimeFormat.cpp
@@ -219,17 +219,17 @@ NewURelativeDateTimeFormatter(JSContext*
     RootedObject internals(cx, intl::GetInternalsObject(cx, relativeTimeFormat));
     if (!internals)
         return nullptr;
 
     RootedValue value(cx);
 
     if (!GetProperty(cx, internals, internals, cx->names().locale, &value))
         return nullptr;
-    UniqueChars locale = JS_EncodeString(cx, value.toString());
+    UniqueChars locale = intl::EncodeLocale(cx, value.toString());
     if (!locale)
         return nullptr;
 
     if (!GetProperty(cx, internals, internals, cx->names().style, &value))
         return nullptr;
 
     UDateRelativeDateTimeFormatterStyle relDateTimeStyle;
     {
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -175,17 +175,17 @@ JS::ObjectOpResult::reportStrictErrorOrW
     }
 
     if (ErrorTakesArguments(code_)) {
         RootedValue idv(cx, IdToValue(id));
         RootedString str(cx, ValueToSource(cx, idv));
         if (!str)
             return false;
 
-        UniqueChars propName = JS_EncodeStringToUTF8(cx, str);
+        UniqueChars propName = StringToNewUTF8CharsZ(cx, *str);
         if (!propName)
             return false;
 
         if (code_ == JSMSG_SET_NON_OBJECT_RECEIVER) {
             // We know that the original receiver was a primitive, so unbox it.
             RootedValue val(cx, ObjectValue(*obj));
             if (!obj->is<ProxyObject>()) {
                 if (!Unbox(cx, obj, &val))
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -1089,25 +1089,25 @@ js::ValueToSourceForError(JSContext* cx,
     } else if (val.isNumber()) {
         if (!sb.append("the number "))
             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 = JS_EncodeString(cx, str);
+        bytes = EncodeLatin1(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 = JS_EncodeString(cx, str);
+    bytes = EncodeLatin1(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/proxy/ScriptedProxyHandler.cpp
+++ b/js/src/proxy/ScriptedProxyHandler.cpp
@@ -174,17 +174,17 @@ GetProxyTrap(JSContext* cx, HandleObject
 
     if (func.isNull()) {
         func.setUndefined();
         return true;
     }
 
     // Step 4.
     if (!IsCallable(func)) {
-        UniqueChars bytes = JS_EncodeString(cx, name);
+        UniqueChars bytes = EncodeLatin1(cx, name);
         if (!bytes)
             return false;
 
         JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_BAD_TRAP, bytes.get());
         return false;
     }
 
     return true;
--- a/js/src/vm/BytecodeUtil.cpp
+++ b/js/src/vm/BytecodeUtil.cpp
@@ -1160,24 +1160,24 @@ ToDisassemblySource(JSContext* cx, Handl
     if (v.isObject()) {
         JSObject& obj = v.toObject();
 
         if (obj.is<JSFunction>()) {
             RootedFunction fun(cx, &obj.as<JSFunction>());
             JSString* str = JS_DecompileFunction(cx, fun);
             if (!str)
                 return nullptr;
-            return JS_EncodeString(cx, str);
+            return EncodeLatin1(cx, str);
         }
 
         if (obj.is<RegExpObject>()) {
             JSString* source = obj.as<RegExpObject>().toString(cx);
             if (!source)
                 return nullptr;
-            return JS_EncodeString(cx, source);
+            return EncodeLatin1(cx, source);
         }
     }
 
     return ValueToPrintableLatin1(cx, v, true);
 }
 
 static bool
 ToDisassemblySource(JSContext* cx, HandleScope scope, UniqueChars* bytes)
@@ -2309,17 +2309,17 @@ js::DecompileValueGenerator(JSContext* c
     if (!fallback) {
         if (v.isUndefined())
             return DuplicateString(cx, js_undefined_str); // Prevent users from seeing "(void 0)"
         fallback = ValueToSource(cx, v);
         if (!fallback)
             return nullptr;
     }
 
-    return JS_EncodeString(cx, fallback);
+    return EncodeLatin1(cx, fallback);
 }
 
 static bool
 DecompileArgumentFromStack(JSContext* cx, int formalIndex, UniqueChars* res)
 {
     MOZ_ASSERT(formalIndex >= 0);
 
     *res = nullptr;
@@ -2399,17 +2399,17 @@ js::DecompileArgument(JSContext* cx, int
     }
     if (v.isUndefined())
         return DuplicateString(cx, js_undefined_str); // Prevent users from seeing "(void 0)"
 
     RootedString fallback(cx, ValueToSource(cx, v));
     if (!fallback)
         return nullptr;
 
-    return JS_EncodeString(cx, fallback);
+    return EncodeLatin1(cx, fallback);
 }
 
 extern bool
 js::IsValidBytecodeOffset(JSContext* cx, JSScript* script, size_t offset)
 {
     // This could be faster (by following jump instructions if the target is <= offset).
     for (BytecodeRange r(cx, script); !r.empty(); r.popFront()) {
         size_t here = r.frontOffset();
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1856,17 +1856,17 @@ js::ReportInNotObjectError(JSContext* cx
             if (!buf.appendSubstring(str, 0, MaxStringLength))
                 return nullptr;
             if (!buf.append("..."))
                 return nullptr;
             str = buf.finishString();
             if (!str)
                 return nullptr;
         }
-        return JS_EncodeString(cx, str);
+        return EncodeLatin1(cx, str);
     };
 
     if (lref.isString() && rref.isString()) {
         UniqueChars lbytes = uniqueCharsFromString(cx, lref);
         if (!lbytes)
             return;
         UniqueChars rbytes = uniqueCharsFromString(cx, rref);
         if (!rbytes)
--- a/js/src/vm/JSFunction-inl.h
+++ b/js/src/vm/JSFunction-inl.h
@@ -17,17 +17,17 @@
 #include "vm/JSObject-inl.h"
 
 namespace js {
 
 inline const char*
 GetFunctionNameBytes(JSContext* cx, JSFunction* fun, UniqueChars* bytes)
 {
     if (JSAtom* name = fun->explicitName()) {
-        *bytes = JS_EncodeString(cx, name);
+        *bytes = EncodeLatin1(cx, name);
         return bytes->get();
     }
     return js_anonymous_str;
 }
 
 inline bool
 CanReuseFunctionForClone(JSContext* cx, HandleFunction fun)
 {
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -256,17 +256,17 @@ bool
 js::Throw(JSContext* cx, jsid id, unsigned errorNumber, const char* details)
 {
     MOZ_ASSERT(js_ErrorFormatString[errorNumber].argCount == (details ? 2 : 1));
 
     RootedValue idVal(cx, IdToValue(id));
     JSString* idstr = ValueToSource(cx, idVal);
     if (!idstr)
        return false;
-    UniqueChars bytes = JS_EncodeString(cx, idstr);
+    UniqueChars bytes = EncodeLatin1(cx, idstr);
     if (!bytes)
         return false;
 
     if (details) {
         JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, errorNumber, bytes.get(),
                                    details);
     } else {
         JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, errorNumber, bytes.get());
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -2470,17 +2470,17 @@ MaybeReportUndeclaredVarAssignment(JSCon
         if (IsStrictSetPC(pc))
             flags = JSREPORT_ERROR;
         else if (cx->realm()->behaviors().extraWarnings(cx))
             flags = JSREPORT_WARNING | JSREPORT_STRICT;
         else
             return true;
     }
 
-    UniqueChars bytes = JS_EncodeStringToUTF8(cx, propname);
+    UniqueChars bytes = StringToNewUTF8CharsZ(cx, *propname);
     if (!bytes)
         return false;
     return JS_ReportErrorFlagsAndNumberUTF8(cx, flags, GetErrorMessage, nullptr,
                                             JSMSG_UNDECLARED_VAR, bytes.get());
 }
 
 /*
  * Finish assignment to a shapeful data property of a native object obj. This
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -294,19 +294,19 @@ ThrowErrorWithType(JSContext* cx, JSExnT
 
     UniqueChars errorArgs[3];
     for (unsigned i = 1; i < 4 && i < args.length(); i++) {
         RootedValue val(cx, args[i]);
         if (val.isInt32()) {
             JSString* str = ToString<CanGC>(cx, val);
             if (!str)
                 return;
-            errorArgs[i - 1] = JS_EncodeString(cx, str);
+            errorArgs[i - 1] = EncodeLatin1(cx, str);
         } else if (val.isString()) {
-            errorArgs[i - 1] = JS_EncodeString(cx, val.toString());
+            errorArgs[i - 1] = EncodeLatin1(cx, val.toString());
         } else {
             errorArgs[i - 1] = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, val, nullptr);
         }
         if (!errorArgs[i - 1])
             return;
     }
 
     JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, errorNumber,
--- a/js/src/vm/StringType.cpp
+++ b/js/src/vm/StringType.cpp
@@ -2071,31 +2071,31 @@ js::ValueToPrintableLatin1(JSContext* cx
         str = ValueToSource(cx, v);
     else
         str = ToString<CanGC>(cx, v);
     if (!str)
         return nullptr;
     str = QuoteString(cx, str, 0);
     if (!str)
         return nullptr;
-    return JS_EncodeString(cx, str);
+    return EncodeLatin1(cx, str);
 }
 
 UniqueChars
 js::ValueToPrintableUTF8(JSContext* cx, const Value& vArg, bool asSource)
 {
     RootedValue v(cx, vArg);
     RootedString str(cx);
     if (asSource)
         str.set(ValueToSource(cx, v));
     else
         str.set(ToString<CanGC>(cx, v));
     if (!str)
         return nullptr;
-    return JS_EncodeStringToUTF8(cx, str);
+    return StringToNewUTF8CharsZ(cx, *str);
 }
 
 template <AllowGC allowGC>
 JSString*
 js::ToStringSlow(JSContext* cx, typename MaybeRooted<Value, allowGC>::HandleType arg)
 {
     /* As with ToObjectSlow, callers must verify that |arg| isn't a string. */
     MOZ_ASSERT(!arg.isString());