Bug 1504334 - Let Intl.RelativeTimeFormat ride the trains. r=jwalden, r=gandalf
authorAndré Bargull <andre.bargull@gmail.com>
Fri, 02 Nov 2018 14:11:14 -0700
changeset 505064 69b08ee5925dac595180a813dcf959929198699f
parent 505063 97a4811843233628012bd1188b7b66843303eaee
child 505065 b67a304cd9ec72707511a8f97d924781639836f2
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden, gandalf
bugs1504334
milestone65.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 1504334 - Let Intl.RelativeTimeFormat ride the trains. r=jwalden, r=gandalf
js/src/builtin/intl/IntlObject.cpp
js/src/builtin/intl/RelativeTimeFormat.cpp
js/src/builtin/intl/RelativeTimeFormat.js
js/src/jsfriendapi.h
js/src/shell/js.cpp
js/src/tests/non262/Intl/RelativeTimeFormat/construct-newtarget.js
js/src/tests/non262/Intl/RelativeTimeFormat/cross-compartment.js
js/src/tests/non262/Intl/RelativeTimeFormat/format.js
js/src/tests/non262/Intl/RelativeTimeFormat/relativetimeformat.js
js/src/tests/non262/Intl/RelativeTimeFormat/supportedLocalesOf.js
js/src/tests/test262-intl-relativetimeformat.js
js/src/tests/test262-update.py
js/src/tests/test262/intl402/RelativeTimeFormat/shell.js
js/src/vm/GlobalObject.h
toolkit/components/mozintl/MozIntlHelper.cpp
toolkit/components/mozintl/mozIMozIntlHelper.idl
toolkit/components/mozintl/mozIntl.js
toolkit/components/mozintl/test/test_mozintlhelper.js
--- a/js/src/builtin/intl/IntlObject.cpp
+++ b/js/src/builtin/intl/IntlObject.cpp
@@ -15,16 +15,17 @@
 #include "jsapi.h"
 
 #include "builtin/intl/Collator.h"
 #include "builtin/intl/CommonFunctions.h"
 #include "builtin/intl/DateTimeFormat.h"
 #include "builtin/intl/ICUStubs.h"
 #include "builtin/intl/NumberFormat.h"
 #include "builtin/intl/PluralRules.h"
+#include "builtin/intl/RelativeTimeFormat.h"
 #include "builtin/intl/ScopedICUObject.h"
 #include "js/CharacterEncoding.h"
 #include "js/Class.h"
 #include "js/StableStringChars.h"
 #include "vm/GlobalObject.h"
 #include "vm/JSContext.h"
 #include "vm/JSObject.h"
 #include "vm/StringType.h"
@@ -567,16 +568,20 @@ GlobalObject::initIntlObject(JSContext* 
     numberFormatProto = CreateNumberFormatPrototype(cx, intl, global, &numberFormat);
     if (!numberFormatProto) {
         return false;
     }
     RootedObject pluralRulesProto(cx, CreatePluralRulesPrototype(cx, intl, global));
     if (!pluralRulesProto) {
         return false;
     }
+    RootedObject relativeTimeFmtProto(cx, CreateRelativeTimeFormatPrototype(cx, intl, global));
+    if (!relativeTimeFmtProto) {
+        return false;
+    }
 
     // The |Intl| object is fully set up now, so define the global property.
     RootedValue intlValue(cx, ObjectValue(*intl));
     if (!DefineDataProperty(cx, global, cx->names().Intl, intlValue, JSPROP_RESOLVING)) {
         return false;
     }
 
     // Now that the |Intl| object is successfully added, we can OOM-safely fill
@@ -589,16 +594,17 @@ GlobalObject::initIntlObject(JSContext* 
     // |getPrototype(JSProto_*)|, but that has global-object-property-related
     // baggage we don't need or want, so we use one-off reserved slots.
     global->setReservedSlot(COLLATOR_PROTO, ObjectValue(*collatorProto));
     global->setReservedSlot(DATE_TIME_FORMAT, ObjectValue(*dateTimeFormat));
     global->setReservedSlot(DATE_TIME_FORMAT_PROTO, ObjectValue(*dateTimeFormatProto));
     global->setReservedSlot(NUMBER_FORMAT, ObjectValue(*numberFormat));
     global->setReservedSlot(NUMBER_FORMAT_PROTO, ObjectValue(*numberFormatProto));
     global->setReservedSlot(PLURAL_RULES_PROTO, ObjectValue(*pluralRulesProto));
+    global->setReservedSlot(RELATIVE_TIME_FORMAT_PROTO, ObjectValue(*relativeTimeFmtProto));
 
     // Also cache |Intl| to implement spec language that conditions behavior
     // based on values being equal to "the standard built-in |Intl| object".
     // Use |setConstructor| to correspond with |JSProto_Intl|.
     //
     // XXX We should possibly do a one-off reserved slot like above.
     global->setConstructor(JSProto_Intl, ObjectValue(*intl));
     return true;
--- a/js/src/builtin/intl/RelativeTimeFormat.cpp
+++ b/js/src/builtin/intl/RelativeTimeFormat.cpp
@@ -170,48 +170,16 @@ js::CreateRelativeTimeFormatPrototype(JS
     RootedValue ctorValue(cx, ObjectValue(*ctor));
     if (!DefineDataProperty(cx, Intl, cx->names().RelativeTimeFormat, ctorValue, 0)) {
         return nullptr;
     }
 
     return proto;
 }
 
-/* static */ bool
-js::GlobalObject::addRelativeTimeFormatConstructor(JSContext* cx, HandleObject intl)
-{
-    Handle<GlobalObject*> global = cx->global();
-
-    {
-        const HeapSlot& slot = global->getReservedSlotRef(RELATIVE_TIME_FORMAT_PROTO);
-        if (!slot.isUndefined()) {
-            MOZ_ASSERT(slot.isObject());
-            JS_ReportErrorASCII(cx,
-                                "the RelativeTimeFormat constructor can't be added "
-                                "multiple times in the same global");
-            return false;
-        }
-    }
-
-    JSObject* relativeTimeFormatProto = CreateRelativeTimeFormatPrototype(cx, intl, global);
-    if (!relativeTimeFormatProto) {
-        return false;
-    }
-
-    global->setReservedSlot(RELATIVE_TIME_FORMAT_PROTO, ObjectValue(*relativeTimeFormatProto));
-    return true;
-}
-
-bool
-js::AddRelativeTimeFormatConstructor(JSContext* cx, JS::Handle<JSObject*> intl)
-{
-    return GlobalObject::addRelativeTimeFormatConstructor(cx, intl);
-}
-
-
 bool
 js::intl_RelativeTimeFormat_availableLocales(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 0);
 
     RootedValue result(cx);
     // We're going to use ULocale availableLocales as per ICU recommendation:
--- a/js/src/builtin/intl/RelativeTimeFormat.js
+++ b/js/src/builtin/intl/RelativeTimeFormat.js
@@ -33,32 +33,38 @@ function relativeTimeFormatLocaleData() 
  */
 function resolveRelativeTimeFormatInternals(lazyRelativeTimeFormatData) {
     assert(IsObject(lazyRelativeTimeFormatData), "lazy data not an object?");
 
     var internalProps = std_Object_create(null);
 
     var RelativeTimeFormat = relativeTimeFormatInternalProperties;
 
-    // Step 10.
+    // Steps 7-8.
     const r = ResolveLocale(callFunction(RelativeTimeFormat.availableLocales, RelativeTimeFormat),
                             lazyRelativeTimeFormatData.requestedLocales,
                             lazyRelativeTimeFormatData.opt,
                             RelativeTimeFormat.relevantExtensionKeys,
                             RelativeTimeFormat.localeData);
 
-    // Step 11.
+    // Steps 9-10.
     internalProps.locale = r.locale;
 
-    // Step 14.
+    // Step 11.
+    assert(r.locale === r.dataLocale,
+           "resolved locale matches the resolved data-locale when no extension-keys are present");
+
+    // Step 13.
     internalProps.style = lazyRelativeTimeFormatData.style;
 
-    // Step 16.
+    // Step 15.
     internalProps.numeric = lazyRelativeTimeFormatData.numeric;
 
+    // Steps 16-20 (Not relevant in our implementation).
+
     return internalProps;
 }
 
 /**
  * Returns an object containing the RelativeTimeFormat internal properties of |obj|,
  * or throws a TypeError if |obj| isn't RelativeTimeFormat-initialized.
  */
 function getRelativeTimeFormatInternals(obj, methodName) {
@@ -96,51 +102,51 @@ function InitializeRelativeTimeFormat(re
 
     // Lazy RelativeTimeFormat data has the following structure:
     //
     //   {
     //     requestedLocales: List of locales,
     //     style: "long" / "short" / "narrow",
     //     numeric: "always" / "auto",
     //
-    //     opt: // opt object computer in InitializeRelativeTimeFormat
+    //     opt: // opt object computed in InitializeRelativeTimeFormat
     //       {
     //         localeMatcher: "lookup" / "best fit",
     //       }
     //   }
     //
     // Note that lazy data is only installed as a final step of initialization,
     // so every RelativeTimeFormat lazy data object has *all* these properties, never a
     // subset of them.
     const lazyRelativeTimeFormatData = std_Object_create(null);
 
-    // Step 3.
+    // Step 1.
     let requestedLocales = CanonicalizeLocaleList(locales);
     lazyRelativeTimeFormatData.requestedLocales = requestedLocales;
 
-    // Steps 4-5.
+    // Steps 2-3.
     if (options === undefined)
         options = std_Object_create(null);
     else
         options = ToObject(options);
 
-    // Step 6.
+    // Step 4.
     let opt = new Record();
 
-    // Steps 7-8.
+    // Steps 5-6.
     let matcher = GetOption(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit");
     opt.localeMatcher = matcher;
 
     lazyRelativeTimeFormatData.opt = opt;
 
-    // Steps 13-14.
+    // Steps 12-13.
     const style = GetOption(options, "style", "string", ["long", "short", "narrow"], "long");
     lazyRelativeTimeFormatData.style = style;
 
-    // Steps 15-16.
+    // Steps 14-15.
     const numeric = GetOption(options, "numeric", "string", ["always", "auto"], "always");
     lazyRelativeTimeFormatData.numeric = numeric;
 
     initializeIntlObject(relativeTimeFormat, "RelativeTimeFormat", lazyRelativeTimeFormatData);
 }
 
 /**
  * Returns the subset of the given locale list for which this locale list has a
@@ -223,25 +229,31 @@ function Intl_RelativeTimeFormat_format(
 }
 
 /**
  * Returns the resolved options for a RelativeTimeFormat object.
  *
  * Spec: ECMAScript 402 API, RelativeTimeFormat, 1.4.4.
  */
 function Intl_RelativeTimeFormat_resolvedOptions() {
-    var relativeTimeFormat;
-    // Check "this RelativeTimeFormat object" per introduction of section 1.4.
-    if (!IsObject(this) || (relativeTimeFormat = GuardToRelativeTimeFormat(this)) === null) {
+    // Step 1.
+    var relativeTimeFormat = this;
+
+    // Steps 2-3.
+    if (!IsObject(relativeTimeFormat) ||
+        (relativeTimeFormat = GuardToRelativeTimeFormat(relativeTimeFormat)) === null)
+    {
         return callFunction(CallRelativeTimeFormatMethodIfWrapped, this,
                             "Intl_RelativeTimeFormat_resolvedOptions");
     }
 
     var internals = getRelativeTimeFormatInternals(relativeTimeFormat, "resolvedOptions");
 
+    // Steps 4-5.
     var result = {
         locale: internals.locale,
         style: internals.style,
         numeric: internals.numeric,
     };
 
+    // Step 6.
     return result;
 }
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -2926,22 +2926,16 @@ ToWindowIfWindowProxy(JSObject* obj);
 // if passed bad input. But the current behavior is entirely under-specified
 // and emphatically not shippable on the web, and it *must* be fixed before
 // this functionality can be exposed in the real world. (There are also some
 // questions about whether the format exposed here is the *right* one to
 // standardize, that will also need to be resolved to ship this.)
 extern bool
 AddMozDateTimeFormatConstructor(JSContext* cx, JS::Handle<JSObject*> intl);
 
-// Create and add the Intl.RelativeTimeFormat constructor function to the provided
-// object.  This function throws if called more than once per realm/global
-// object.
-extern bool
-AddRelativeTimeFormatConstructor(JSContext* cx, JS::Handle<JSObject*> intl);
-
 class MOZ_STACK_CLASS JS_FRIEND_API AutoAssertNoContentJS
 {
   public:
     explicit AutoAssertNoContentJS(JSContext* cx);
     ~AutoAssertNoContentJS();
 
   private:
     JSContext* context_;
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1242,20 +1242,16 @@ AddIntlExtras(JSContext* cx, unsigned ar
     if (!JS_DefineFunctions(cx, intl, funcs)) {
         return false;
     }
 
     if (!js::AddMozDateTimeFormatConstructor(cx, intl)) {
         return false;
     }
 
-    if (!js::AddRelativeTimeFormatConstructor(cx, intl)) {
-        return false;
-    }
-
     args.rval().setUndefined();
     return true;
 }
 #endif // ENABLE_INTL_API
 
 static MOZ_MUST_USE bool
 EvalUtf8AndPrint(JSContext* cx, const char* bytes, size_t length,
                  int lineno, bool compileOnly)
--- a/js/src/tests/non262/Intl/RelativeTimeFormat/construct-newtarget.js
+++ b/js/src/tests/non262/Intl/RelativeTimeFormat/construct-newtarget.js
@@ -1,16 +1,14 @@
-// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty("addIntlExtras"))
+// |reftest| skip-if(!this.hasOwnProperty("Intl"))
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
-addIntlExtras(Intl);
-
 var obj = new Intl.RelativeTimeFormat();
 
 // Test that new RTF produces an object with the right prototype.
 assertEq(Object.getPrototypeOf(obj), Intl.RelativeTimeFormat.prototype);
 
 // Test subclassing %Intl.RelativeTimeFormat% works correctly.
 class MyRelativeTimeFormat extends Intl.RelativeTimeFormat {}
 
--- a/js/src/tests/non262/Intl/RelativeTimeFormat/cross-compartment.js
+++ b/js/src/tests/non262/Intl/RelativeTimeFormat/cross-compartment.js
@@ -1,14 +1,11 @@
-// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty("addIntlExtras"))
-
-addIntlExtras(Intl);
+// |reftest| skip-if(!this.hasOwnProperty("Intl"))
 
 var otherGlobal = newGlobal();
-otherGlobal.addIntlExtras(otherGlobal.Intl);
 
 var relativeTimeFormat = new Intl.RelativeTimeFormat();
 var ccwRelativeTimeFormat = new otherGlobal.Intl.RelativeTimeFormat();
 
 // Test Intl.RelativeTimeFormat.prototype.format with a CCW object.
 var Intl_RelativeTimeFormat_format = Intl.RelativeTimeFormat.prototype.format;
 
 assertEq(Intl_RelativeTimeFormat_format.call(ccwRelativeTimeFormat, 0, "hour"),
--- a/js/src/tests/non262/Intl/RelativeTimeFormat/format.js
+++ b/js/src/tests/non262/Intl/RelativeTimeFormat/format.js
@@ -1,19 +1,17 @@
-// |reftest| skip-if(!this.hasOwnProperty('Intl')||!this.hasOwnProperty('addIntlExtras'))
+// |reftest| skip-if(!this.hasOwnProperty('Intl'))
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 // Tests the format function with a diverse set of locales and options.
 
 var rtf;
 
-addIntlExtras(Intl);
-
 {
   // Numeric format
   rtf = new Intl.RelativeTimeFormat("en-US");
   assertEq(rtf.format(0, "second"), "in 0 seconds");
   assertEq(rtf.format(-0, "second"), "0 seconds ago");
   assertEq(rtf.format(-1, "second"), "1 second ago");
   assertEq(rtf.format(1, "second"), "in 1 second");
 
--- a/js/src/tests/non262/Intl/RelativeTimeFormat/relativetimeformat.js
+++ b/js/src/tests/non262/Intl/RelativeTimeFormat/relativetimeformat.js
@@ -1,17 +1,15 @@
-// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty('addIntlExtras'))
+// |reftest| skip-if(!this.hasOwnProperty("Intl"))
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 // Tests the format function with a diverse set of locales and options.
 
 var rtf;
 
-addIntlExtras(Intl);
-
 rtf = new Intl.RelativeTimeFormat("en-us");
 assertEq(rtf.resolvedOptions().locale, "en-US");
 assertEq(rtf.resolvedOptions().style, "long");
 assertEq(rtf.resolvedOptions().numeric, "always");
 
 reportCompare(0, 0, 'ok');
--- a/js/src/tests/non262/Intl/RelativeTimeFormat/supportedLocalesOf.js
+++ b/js/src/tests/non262/Intl/RelativeTimeFormat/supportedLocalesOf.js
@@ -1,9 +1,9 @@
-// |reftest| skip-if(!this.hasOwnProperty('Intl')||!this.hasOwnProperty('addIntlExtras')||xulRuntime.shell)
+// |reftest| skip-if(!this.hasOwnProperty('Intl')||xulRuntime.shell)
 // -- test in browser only that ICU has locale data for all Mozilla languages
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 // This array contains the locales that ICU supports in
 // number formatting whose languages Mozilla localizes Firefox into.
@@ -361,15 +361,13 @@ var locales = [
     "zh-Hans-MO",
     "zh-Hans-SG",
     "zh-Hant",
     "zh-Hant-HK",
     "zh-Hant-MO",
     "zh-Hant-TW",
 ];
 
-addIntlExtras(Intl);
-
 const result = Intl.RelativeTimeFormat.supportedLocalesOf(locales);
 
 assertEqArray(locales, result);
 
 reportCompare(0, 0, 'ok');
deleted file mode 100644
--- a/js/src/tests/test262-intl-relativetimeformat.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// 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/.
-
-// Call the shell helper to add Intl.RelativeTimeFormat to the Intl object.
-if (typeof addIntlExtras === "function") {
-    let intlExtras = {};
-    addIntlExtras(intlExtras);
-
-    Object.defineProperty(Intl, "RelativeTimeFormat", {
-        value: intlExtras.RelativeTimeFormat,
-        writable: true, enumerable: false, configurable: true
-    });
-}
--- a/js/src/tests/test262-update.py
+++ b/js/src/tests/test262-update.py
@@ -368,21 +368,16 @@ def process_test262(test262Dir, test262O
     explicitIncludes[os.path.join("built-ins", "Atomics")] = ["testAtomics.js",
                                                               "testTypedArray.js"]
     explicitIncludes[os.path.join("built-ins", "DataView")] = ["byteConversionValues.js"]
     explicitIncludes[os.path.join("built-ins", "Promise")] = ["promiseHelper.js"]
     explicitIncludes[os.path.join("built-ins", "TypedArray")] = ["byteConversionValues.js",
                                                                  "detachArrayBuffer.js", "nans.js"]
     explicitIncludes[os.path.join("built-ins", "TypedArrays")] = ["detachArrayBuffer.js"]
 
-    # Intl.RelativeTimeFormat isn't yet enabled by default.
-    localIncludesMap[os.path.join("intl402", "RelativeTimeFormat")] = [
-        "test262-intl-relativetimeformat.js"
-    ]
-
     # Process all test directories recursively.
     for (dirPath, dirNames, fileNames) in os.walk(testDir):
         relPath = os.path.relpath(dirPath, testDir)
         if relPath == ".":
             continue
 
         # Skip creating a "prs" directory if it already exists
         if relPath not in ("prs", "local") and not os.path.exists(os.path.join(test262OutDir,
--- a/js/src/tests/test262/intl402/RelativeTimeFormat/shell.js
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/shell.js
@@ -1,15 +0,0 @@
-// file: test262-intl-relativetimeformat.js
-// This Source Code Form is subject to the terms of the Mozilla Public
-// 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/.
-
-// Call the shell helper to add Intl.RelativeTimeFormat to the Intl object.
-if (typeof addIntlExtras === "function") {
-    let intlExtras = {};
-    addIntlExtras(intlExtras);
-
-    Object.defineProperty(Intl, "RelativeTimeFormat", {
-        value: intlExtras.RelativeTimeFormat,
-        writable: true, enumerable: false, configurable: true
-    });
-}
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -796,19 +796,16 @@ class GlobalObject : public NativeObject
 
     // Implemented in builtin/MapObject.cpp.
     static bool initMapIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
     static bool initSetIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
 
     // Implemented in builtin/intl/IntlObject.cpp.
     static bool initIntlObject(JSContext* cx, Handle<GlobalObject*> global);
 
-    // Implemented in builtin/intl/RelativeTimeFormat.cpp.
-    static bool addRelativeTimeFormatConstructor(JSContext* cx, HandleObject intl);
-
     // Implemented in builtin/ModuleObject.cpp
     static bool initModuleProto(JSContext* cx, Handle<GlobalObject*> global);
     static bool initImportEntryProto(JSContext* cx, Handle<GlobalObject*> global);
     static bool initExportEntryProto(JSContext* cx, Handle<GlobalObject*> global);
     static bool initRequestedModuleProto(JSContext* cx, Handle<GlobalObject*> global);
 
     // Implemented in builtin/TypedObject.cpp
     static bool initTypedObjectModule(JSContext* cx, Handle<GlobalObject*> global);
--- a/toolkit/components/mozintl/MozIntlHelper.cpp
+++ b/toolkit/components/mozintl/MozIntlHelper.cpp
@@ -79,37 +79,16 @@ MozIntlHelper::AddDateTimeFormatConstruc
   if (!js::AddMozDateTimeFormatConstructor(cx, realIntlObj)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MozIntlHelper::AddRelativeTimeFormatConstructor(JS::Handle<JS::Value> val, JSContext* cx)
-{
-  if (!val.isObject()) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  JS::Rooted<JSObject*> realIntlObj(cx, js::CheckedUnwrap(&val.toObject()));
-  if (!realIntlObj) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  JSAutoRealm ar(cx, realIntlObj);
-
-  if (!js::AddRelativeTimeFormatConstructor(cx, realIntlObj)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 MozIntlHelper::AddGetLocaleInfo(JS::Handle<JS::Value> val, JSContext* cx)
 {
   static const JSFunctionSpec funcs[] = {
     JS_SELF_HOSTED_FN("getLocaleInfo", "Intl_getLocaleInfo", 1, 0),
     JS_FS_END
   };
 
   return AddFunctions(cx, val, funcs);
--- a/toolkit/components/mozintl/mozIMozIntlHelper.idl
+++ b/toolkit/components/mozintl/mozIMozIntlHelper.idl
@@ -37,16 +37,9 @@ interface mozIMozIntlHelper : nsISupport
    * Operating System regional preferences and adjust for that.
    *
    * That means that if user will manually select time format (hour12/24) or
    * adjust how the date should be displayed, MozDateTimeFormat will use that.
    *
    * This API should be used everywhere in the UI instead of regular Intl  API.
    */
   [implicit_jscontext] void addDateTimeFormatConstructor(in jsval intlObject);
-
-  /**
-   * Adds a RelativeTimeFormat constructor to the given object.  This function may only
-   * be called once within a realm/global object: calling it multiple times will
-   * throw.
-   */
-  [implicit_jscontext] void addRelativeTimeFormatConstructor(in jsval intlObject);
 };
--- a/toolkit/components/mozintl/mozIntl.js
+++ b/toolkit/components/mozintl/mozIntl.js
@@ -350,23 +350,17 @@ class MozIntl {
       constructor(locales, options, ...args) {
         super(getLocales(locales), options, ...args);
       }
     }
     return MozPluralRules;
   }
 
   get RelativeTimeFormat() {
-    if (!this._cache.hasOwnProperty("RelativeTimeFormat")) {
-      mozIntlHelper.addRelativeTimeFormatConstructor(this._cache);
-    }
-
-    const RelativeTimeFormat = this._cache.RelativeTimeFormat;
-
-    class MozRelativeTimeFormat extends RelativeTimeFormat {
+    class MozRelativeTimeFormat extends Intl.RelativeTimeFormat {
       constructor(locales, options = {}, ...args) {
 
         // If someone is asking for MozRelativeTimeFormat, it's likely they'll want
         // to use `formatBestUnit` which works better with `auto`
         if (options.numeric === undefined) {
           options.numeric = "auto";
         }
         super(getLocales(locales), options, ...args);
--- a/toolkit/components/mozintl/test/test_mozintlhelper.js
+++ b/toolkit/components/mozintl/test/test_mozintlhelper.js
@@ -32,27 +32,23 @@ function test_cross_global(miHelper) {
   equal(waivedX.getCalendarInfo() instanceof global.Object, true);
 }
 
 function test_methods_presence(miHelper) {
   equal(miHelper.addGetCalendarInfo instanceof Function, true);
   equal(miHelper.addGetDisplayNames instanceof Function, true);
   equal(miHelper.addGetLocaleInfo instanceof Function, true);
   equal(miHelper.addDateTimeFormatConstructor instanceof Function, true);
-  equal(miHelper.addRelativeTimeFormatConstructor instanceof Function, true);
 
   let x = {};
 
   miHelper.addGetCalendarInfo(x);
   equal(x.getCalendarInfo instanceof Function, true);
 
   miHelper.addGetDisplayNames(x);
   equal(x.getDisplayNames instanceof Function, true);
 
   miHelper.addGetLocaleInfo(x);
   equal(x.getLocaleInfo instanceof Function, true);
 
   miHelper.addDateTimeFormatConstructor(x);
   equal(x.DateTimeFormat instanceof Function, true);
-
-  miHelper.addRelativeTimeFormatConstructor(x);
-  equal(x.RelativeTimeFormat instanceof Function, true);
 }