--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -3576,46 +3576,16 @@ CreatePluralRulesPrototype(JSContext* cx
RootedValue ctorValue(cx, ObjectValue(*ctor));
if (!DefineDataProperty(cx, Intl, cx->names().PluralRules, ctorValue, 0))
return nullptr;
return proto;
}
-/* static */ bool
-js::GlobalObject::addPluralRulesConstructor(JSContext* cx, HandleObject intl)
-{
- Handle<GlobalObject*> global = cx->global();
-
- {
- const HeapSlot& slot = global->getReservedSlotRef(PLURAL_RULES_PROTO);
- if (!slot.isUndefined()) {
- MOZ_ASSERT(slot.isObject());
- JS_ReportErrorASCII(cx,
- "the PluralRules constructor can't be added "
- "multiple times in the same global");
- return false;
- }
- }
-
- JSObject* pluralRulesProto = CreatePluralRulesPrototype(cx, intl, global);
- if (!pluralRulesProto)
- return false;
-
- global->setReservedSlot(PLURAL_RULES_PROTO, ObjectValue(*pluralRulesProto));
- return true;
-}
-
-bool
-js::AddPluralRulesConstructor(JSContext* cx, JS::Handle<JSObject*> intl)
-{
- return GlobalObject::addPluralRulesConstructor(cx, intl);
-}
-
bool
js::intl_PluralRules_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:
@@ -4377,16 +4347,19 @@ GlobalObject::initIntlObject(JSContext*
RootedObject dateTimeFormatProto(cx), dateTimeFormat(cx);
dateTimeFormatProto = CreateDateTimeFormatPrototype(cx, intl, global, &dateTimeFormat, DateTimeFormatOptions::Standard);
if (!dateTimeFormatProto)
return false;
RootedObject numberFormatProto(cx), numberFormat(cx);
numberFormatProto = CreateNumberFormatPrototype(cx, intl, global, &numberFormat);
if (!numberFormatProto)
return false;
+ RootedObject pluralRulesProto(cx, CreatePluralRulesPrototype(cx, intl, global));
+ if (!pluralRulesProto)
+ 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
// in all relevant reserved global slots.
@@ -4397,16 +4370,17 @@ GlobalObject::initIntlObject(JSContext*
// |String.prototype| we have |JSProto_*| that enables
// |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));
// 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;
deleted file mode 100644
--- a/js/src/jit-test/tests/auto-regress/bug1334573.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// |jit-test| error:Error
-
-if (this.Intl) {
- addIntlExtras(Intl);
- addIntlExtras(Intl);
-} else {
- throw new Error();
-}
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -3057,22 +3057,16 @@ ToWindowProxyIfWindow(JSObject* obj)
/**
* If `obj` is a WindowProxy, get its associated Window (the compartment's
* global), else return `obj`. This function is infallible and never returns
* nullptr.
*/
extern JS_FRIEND_API(JSObject*)
ToWindowIfWindowProxy(JSObject* obj);
-// Create and add the Intl.PluralRules constructor function to the provided
-// object. This function throws if called more than once per realm/global
-// object.
-extern bool
-AddPluralRulesConstructor(JSContext* cx, JS::Handle<JSObject*> intl);
-
// Create and add the Intl.MozDateTimeFormat constructor function to the provided
// object.
//
// This custom date/time formatter constructor gives users the ability
// to specify a custom format pattern. This pattern is passed *directly*
// to ICU with NO SYNTAX PARSING OR VALIDATION WHATSOEVER. ICU appears to
// have a a modicum of testing of this, and it won't fall over completely
// if passed bad input. But the current behavior is entirely under-specified
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -784,19 +784,16 @@ AddIntlExtras(JSContext* cx, unsigned ar
JS_SELF_HOSTED_FN("getLocaleInfo", "Intl_getLocaleInfo", 1, 0),
JS_SELF_HOSTED_FN("getDisplayNames", "Intl_getDisplayNames", 2, 0),
JS_FS_END
};
if (!JS_DefineFunctions(cx, intl, funcs))
return false;
- if (!js::AddPluralRulesConstructor(cx, intl))
- return false;
-
if (!js::AddMozDateTimeFormatConstructor(cx, intl))
return false;
args.rval().setUndefined();
return true;
}
#endif // ENABLE_INTL_API
@@ -6685,18 +6682,17 @@ static const JSFunctionSpecWithHelp shel
#ifdef ENABLE_INTL_API
JS_FN_HELP("addIntlExtras", AddIntlExtras, 1, 0,
"addIntlExtras(obj)",
"Adds various not-yet-standardized Intl functions as properties on the\n"
"provided object (this should generally be Intl itself). The added\n"
"functions and their behavior are experimental: don't depend upon them\n"
"unless you're willing to update your code if these experimental APIs change\n"
-"underneath you. Calling this function more than once in a realm/global\n"
-"will throw."),
+"underneath you."),
#endif // ENABLE_INTL_API
JS_FS_HELP_END
};
static const JSFunctionSpecWithHelp fuzzing_unsafe_functions[] = {
JS_FN_HELP("getSelfHostedValue", GetSelfHostedValue, 1, 0,
"getSelfHostedValue()",
--- a/js/src/tests/Intl/PluralRules/call.js
+++ b/js/src/tests/Intl/PluralRules/call.js
@@ -1,11 +1,9 @@
-// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty("addIntlExtras"))
-
-addIntlExtras(Intl);
+// |reftest| skip-if(!this.hasOwnProperty("Intl"))
function IsConstructor(o) {
try {
new (new Proxy(o, {construct: () => ({})}));
return true;
} catch (e) {
return false;
}
--- a/js/src/tests/Intl/PluralRules/construct-newtarget.js
+++ b/js/src/tests/Intl/PluralRules/construct-newtarget.js
@@ -1,11 +1,9 @@
-// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty("addIntlExtras"))
-
-addIntlExtras(Intl);
+// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Test subclassing %Intl.PluralRules% works correctly.
class MyPluralRules extends Intl.PluralRules {}
var obj = new MyPluralRules();
assertEq(obj instanceof MyPluralRules, true);
assertEq(obj instanceof Intl.PluralRules, true);
assertEq(Object.getPrototypeOf(obj), MyPluralRules.prototype);
--- a/js/src/tests/Intl/PluralRules/negativeZeroFractionDigits.js
+++ b/js/src/tests/Intl/PluralRules/negativeZeroFractionDigits.js
@@ -1,11 +1,9 @@
-// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty('addIntlExtras'))
-
-addIntlExtras(Intl);
+// |reftest| skip-if(!this.hasOwnProperty("Intl"))
const optionsList = [
{minimumFractionDigits: -0, maximumFractionDigits: -0},
{minimumFractionDigits: -0, maximumFractionDigits: +0},
{minimumFractionDigits: +0, maximumFractionDigits: -0},
{minimumFractionDigits: +0, maximumFractionDigits: +0},
];
--- a/js/src/tests/Intl/PluralRules/pluralrules.js
+++ b/js/src/tests/Intl/PluralRules/pluralrules.js
@@ -1,16 +1,14 @@
-// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty('addIntlExtras'))
+// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Tests the format function with a diverse set of locales and options.
var pr;
-addIntlExtras(Intl);
-
pr = new Intl.PluralRules("en-us");
assertEq(pr.resolvedOptions().locale, "en-US");
assertEq(pr.resolvedOptions().type, "cardinal");
assertEq(pr.resolvedOptions().pluralCategories.length, 2);
pr = new Intl.PluralRules("de", {type: 'cardinal'});
assertEq(pr.resolvedOptions().pluralCategories.length, 2);
--- a/js/src/tests/Intl/PluralRules/resolvedOptions-overridden-species.js
+++ b/js/src/tests/Intl/PluralRules/resolvedOptions-overridden-species.js
@@ -1,14 +1,12 @@
-// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty("addIntlExtras"))
+// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Tests the PluralRules.resolvedOptions function for overriden Array[Symbol.species].
-addIntlExtras(Intl);
-
var pl = new Intl.PluralRules("de");
Object.defineProperty(Array, Symbol.species, {
value: function() {
return new Proxy(["?"], {
get(t, pk, r) {
return Reflect.get(t, pk, r);
},
--- a/js/src/tests/Intl/PluralRules/select.js
+++ b/js/src/tests/Intl/PluralRules/select.js
@@ -1,16 +1,14 @@
-// |reftest| skip-if(!this.hasOwnProperty('Intl')||!this.hasOwnProperty('addIntlExtras'))
+// |reftest| skip-if(!this.hasOwnProperty('Intl'))
// Tests the format function with a diverse set of locales and options.
var pr;
-addIntlExtras(Intl);
-
pr = new Intl.PluralRules("en-us");
assertEq(pr.select(0), "other");
assertEq(pr.select(0.5), "other");
assertEq(pr.select(1.2), "other");
assertEq(pr.select(1.5), "other");
assertEq(pr.select(1.7), "other");
assertEq(pr.select(-1), "one");
assertEq(pr.select(1), "one");
--- a/js/src/tests/Intl/PluralRules/supportedLocalesOf.js
+++ b/js/src/tests/Intl/PluralRules/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 array contains the locales that ICU supports in
// number formatting whose languages Mozilla localizes Firefox into.
// Current as of ICU 50.1.2 and Firefox March 2013.
var locales = [
"af",
"af-NA",
@@ -357,15 +357,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.PluralRules.supportedLocalesOf(locales);
assertEqArray(locales, result);
reportCompare(0, 0, 'ok');
--- a/js/src/tests/jstests.list
+++ b/js/src/tests/jstests.list
@@ -1,19 +1,16 @@
# Manifest entries for imported test suites whose individual test cases
# we don't want to change.
skip script ecma_6/String/normalize-generateddata-input.js # input data for other test
# Skip intl402 tests when Intl isn't available.
skip-if(!this.hasOwnProperty('Intl')) include test262/intl402/jstests.list
-# Skip Intl.PluralRules tests when the addIntlExtras helper isn't available.
-skip-if(!this.hasOwnProperty('addIntlExtras')) include test262/intl402/PluralRules/jstests.list
-
# Skip built-ins/Simd tests when SIMD isn't available.
skip-if(!this.hasOwnProperty('SIMD')) include test262/built-ins/Simd/jstests.list
# Skip built-in/Atomics when Atomics isn't available
skip-if(!this.hasOwnProperty('Atomics')) include test262/built-ins/Atomics/jstests.list
# Skip built-in/SharedArrayBuffer
skip-if(!this.hasOwnProperty('SharedArrayBuffer')) include test262/built-ins/SharedArrayBuffer/jstests.list
deleted file mode 100644
--- a/js/src/tests/test262-intl-extras.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 experimental features to the Intl object.
-if (typeof addIntlExtras === "function") {
- let intlExtras = {};
- addIntlExtras(intlExtras);
-
- Object.defineProperty(Intl, "PluralRules", {
- value: intlExtras.PluralRules,
- writable: true, enumerable: false, configurable: true
- });
-}
--- a/js/src/tests/test262-update.py
+++ b/js/src/tests/test262-update.py
@@ -316,19 +316,16 @@ def process_test262(test262Dir, test262O
explicitIncludes = {}
explicitIncludes["intl402"] = ["testBuiltInObject.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.PluralRules isn't yet enabled by default.
- localIncludesMap[os.path.join("intl402", "PluralRules")] = ["test262-intl-extras.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 != "prs" or not os.path.exists(os.path.join(test262OutDir, relPath)):
--- a/js/src/tests/test262/intl402/PluralRules/shell.js
+++ b/js/src/tests/test262/intl402/PluralRules/shell.js
@@ -1,15 +0,0 @@
-// file: test262-intl-extras.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 experimental features to the Intl object.
-if (typeof addIntlExtras === "function") {
- let intlExtras = {};
- addIntlExtras(intlExtras);
-
- Object.defineProperty(Intl, "PluralRules", {
- value: intlExtras.PluralRules,
- writable: true, enumerable: false, configurable: true
- });
-}
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -277,17 +277,16 @@
macro(ownKeys, ownKeys, "ownKeys") \
macro(Object_valueOf, Object_valueOf, "Object_valueOf") \
macro(package, package, "package") \
macro(parseFloat, parseFloat, "parseFloat") \
macro(parseInt, parseInt, "parseInt") \
macro(pattern, pattern, "pattern") \
macro(pending, pending, "pending") \
macro(PluralRules, PluralRules, "PluralRules") \
- macro(PluralRulesSelect, PluralRulesSelect, "Intl_PluralRules_Select") \
macro(percentSign, percentSign, "percentSign") \
macro(plusSign, plusSign, "plusSign") \
macro(public, public_, "public") \
macro(pull, pull, "pull") \
macro(preventExtensions, preventExtensions, "preventExtensions") \
macro(private, private_, "private") \
macro(promise, promise, "promise") \
macro(propertyIsEnumerable, propertyIsEnumerable, "propertyIsEnumerable") \
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -773,17 +773,16 @@ class GlobalObject : public NativeObject
static bool initAsyncGenerators(JSContext* cx, Handle<GlobalObject*> global);
// Implemented in builtin/MapObject.cpp.
static bool initMapIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
static bool initSetIteratorProto(JSContext* cx, Handle<GlobalObject*> global);
// Implemented in Intl.cpp.
static bool initIntlObject(JSContext* cx, Handle<GlobalObject*> global);
- static bool addPluralRulesConstructor(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