commit aa84570e2880bd25e911bbfd949272e33c49d7bf
parent d1491cd093113845b4f62af4c19e40f6a291aad0
Author: André Bargull <andre.bargull@gmail.com>
Date: Tue, 16 Dec 2025 19:38:28 +0000
Bug 2005785 - Part 1: Move Intl.getCanonicalLocales and Intl.supportedValuesOf to C++. r=spidermonkey-reviewers,dminor
Differential Revision: https://phabricator.services.mozilla.com/D276253
Diffstat:
6 files changed, 51 insertions(+), 54 deletions(-)
diff --git a/js/src/builtin/intl/IntlObject.cpp b/js/src/builtin/intl/IntlObject.cpp
@@ -42,6 +42,7 @@
#include "vm/NativeObject-inl.h"
using namespace js;
+using namespace js::intl;
/******************** Intl ********************/
@@ -105,13 +106,6 @@ bool js::intl_GetCalendarInfo(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
-static void ReportBadKey(JSContext* cx, JSString* key) {
- if (UniqueChars chars = QuoteString(cx, key, '"')) {
- JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INVALID_KEY,
- chars.get());
- }
-}
-
// 9.2.2 BestAvailableLocale ( availableLocales, locale )
//
// Carries an additional third argument in our implementation to provide the
@@ -501,37 +495,70 @@ static ArrayObject* AvailableUnits(JSContext* cx) {
return CreateArrayFromSortedList(cx, simpleMeasureUnitNames);
}
-bool js::intl_SupportedValuesOf(JSContext* cx, unsigned argc, JS::Value* vp) {
+/**
+ * Intl.getCanonicalLocales ( locales )
+ */
+static bool intl_getCanonicalLocales(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp);
- MOZ_ASSERT(args.length() == 1);
- MOZ_ASSERT(args[0].isString());
- JSLinearString* key = args[0].toString()->ensureLinear(cx);
+ // Step 1.
+ Rooted<LocalesList> locales(cx, cx);
+ if (!CanonicalizeLocaleList(cx, args.get(0), &locales)) {
+ return false;
+ }
+
+ // Step 2.
+ auto* array = LocalesListToArray(cx, locales);
+ if (!array) {
+ return false;
+ }
+ args.rval().setObject(*array);
+ return true;
+}
+
+/**
+ * Intl.supportedValuesOf ( key )
+ */
+static bool intl_supportedValuesOf(JSContext* cx, unsigned argc, Value* vp) {
+ CallArgs args = CallArgsFromVp(argc, vp);
+
+ // Step 1.
+ auto* key = ToString(cx, args.get(0));
if (!key) {
return false;
}
+ auto* linearKey = key->ensureLinear(cx);
+ if (!linearKey) {
+ return false;
+ }
+
+ // Steps 2-8.
ArrayObject* list;
- if (StringEqualsLiteral(key, "calendar")) {
+ if (StringEqualsLiteral(linearKey, "calendar")) {
list = AvailableCalendars(cx);
- } else if (StringEqualsLiteral(key, "collation")) {
+ } else if (StringEqualsLiteral(linearKey, "collation")) {
list = AvailableCollations(cx);
- } else if (StringEqualsLiteral(key, "currency")) {
+ } else if (StringEqualsLiteral(linearKey, "currency")) {
list = AvailableCurrencies(cx);
- } else if (StringEqualsLiteral(key, "numberingSystem")) {
+ } else if (StringEqualsLiteral(linearKey, "numberingSystem")) {
list = AvailableNumberingSystems(cx);
- } else if (StringEqualsLiteral(key, "timeZone")) {
+ } else if (StringEqualsLiteral(linearKey, "timeZone")) {
list = AvailableTimeZones(cx);
- } else if (StringEqualsLiteral(key, "unit")) {
+ } else if (StringEqualsLiteral(linearKey, "unit")) {
list = AvailableUnits(cx);
} else {
- ReportBadKey(cx, key);
+ if (UniqueChars chars = QuoteString(cx, linearKey, '"')) {
+ JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INVALID_KEY,
+ chars.get());
+ }
return false;
}
if (!list) {
return false;
}
+ // Step 9.
args.rval().setObject(*list);
return true;
}
@@ -544,8 +571,8 @@ static bool intl_toSource(JSContext* cx, unsigned argc, Value* vp) {
static const JSFunctionSpec intl_static_methods[] = {
JS_FN("toSource", intl_toSource, 0, 0),
- JS_SELF_HOSTED_FN("getCanonicalLocales", "Intl_getCanonicalLocales", 1, 0),
- JS_SELF_HOSTED_FN("supportedValuesOf", "Intl_supportedValuesOf", 1, 0),
+ JS_FN("getCanonicalLocales", intl_getCanonicalLocales, 1, 0),
+ JS_FN("supportedValuesOf", intl_supportedValuesOf, 1, 0),
JS_FS_END,
};
diff --git a/js/src/builtin/intl/IntlObject.h b/js/src/builtin/intl/IntlObject.h
@@ -57,16 +57,6 @@ extern const JSClass IntlClass;
*/
[[nodiscard]] extern bool intl_BestAvailableLocale(JSContext* cx, unsigned argc,
JS::Value* vp);
-
-/**
- * Returns the list of supported values for the given key. Throws a RangeError
- * if the key isn't one of {"calendar", "collation", "currency",
- * "numberingSystem", "timeZone", "unit"}.
- *
- * Usage: list = intl_SupportedValuesOf(key)
- */
-[[nodiscard]] extern bool intl_SupportedValuesOf(JSContext* cx, unsigned argc,
- JS::Value* vp);
} // namespace js
#endif /* builtin_intl_IntlObject_h */
diff --git a/js/src/builtin/intl/IntlObject.js b/js/src/builtin/intl/IntlObject.js
@@ -3,27 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
- * 8.2.1 Intl.getCanonicalLocales ( locales )
- *
- * ES2017 Intl draft rev 947aa9a0c853422824a0c9510d8f09be3eb416b9
- */
-function Intl_getCanonicalLocales(locales) {
- // Steps 1-2.
- return CanonicalizeLocaleList(locales);
-}
-
-/**
- * Intl.supportedValuesOf ( key )
- */
-function Intl_supportedValuesOf(key) {
- // Step 1.
- key = ToString(key);
-
- // Steps 2-9.
- return intl_SupportedValuesOf(key);
-}
-
-/**
* This function is a custom function in the style of the standard Intl.*
* functions, that isn't part of any spec or proposal yet.
*
diff --git a/js/src/builtin/intl/LocaleNegotiation.cpp b/js/src/builtin/intl/LocaleNegotiation.cpp
@@ -343,8 +343,8 @@ static bool SupportedLocales(JSContext* cx,
supportedLocales);
}
-static ArrayObject* LocalesListToArray(JSContext* cx,
- Handle<LocalesList> locales) {
+ArrayObject* js::intl::LocalesListToArray(JSContext* cx,
+ Handle<LocalesList> locales) {
auto* array = NewDenseFullyAllocatedArray(cx, locales.length());
if (!array) {
return nullptr;
diff --git a/js/src/builtin/intl/LocaleNegotiation.h b/js/src/builtin/intl/LocaleNegotiation.h
@@ -30,6 +30,8 @@ using LocalesList = JS::StackGCVector<JSLinearString*>;
bool CanonicalizeLocaleList(JSContext* cx, JS::Handle<JS::Value> locales,
JS::MutableHandle<LocalesList> result);
+ArrayObject* LocalesListToArray(JSContext* cx, JS::Handle<LocalesList> locales);
+
/**
* Compares a BCP 47 language tag against the locales in availableLocales and
* returns the best available match -- or |nullptr| if no match was found.
diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp
@@ -1939,7 +1939,6 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("intl_NumberFormat", intl_NumberFormat, 2, 0),
JS_FN("intl_SelectPluralRule", intl_SelectPluralRule, 2, 0),
JS_FN("intl_SelectPluralRuleRange", intl_SelectPluralRuleRange, 3, 0),
- JS_FN("intl_SupportedValuesOf", intl_SupportedValuesOf, 1, 0),
JS_FN("intl_TryValidateAndCanonicalizeLanguageTag",
intl_TryValidateAndCanonicalizeLanguageTag, 1, 0),
JS_FN("intl_ValidateAndCanonicalizeLanguageTag",