diff options
author | Martok <martok@martoks-place.de> | 2023-02-12 23:27:21 +0100 |
---|---|---|
committer | Martok <martok@martoks-place.de> | 2023-02-12 23:27:21 +0100 |
commit | 3091ff4e57b5dad13f80d36fc14f0fa3fb17c4eb (patch) | |
tree | 6a7ec0874dc6b87d4240027cb7582496fb273a39 /js/src | |
parent | 8ca01873c0a34af32f952e4bc9dff94685b79477 (diff) | |
download | uxp-3091ff4e57b5dad13f80d36fc14f0fa3fb17c4eb.tar.gz |
Issue #2046 - Move functionality used in the implementation of multiple Intl.* constructors into builtin/intl/CommonFunctions.*
Diffstat (limited to 'js/src')
-rw-r--r-- | js/src/builtin/Intl.cpp | 363 | ||||
-rw-r--r-- | js/src/builtin/intl/CommonFunctions.cpp | 116 | ||||
-rw-r--r-- | js/src/builtin/intl/CommonFunctions.h | 105 | ||||
-rw-r--r-- | js/src/moz.build | 1 |
4 files changed, 341 insertions, 244 deletions
diff --git a/js/src/builtin/Intl.cpp b/js/src/builtin/Intl.cpp index f24a221fdb..28533129ed 100644 --- a/js/src/builtin/Intl.cpp +++ b/js/src/builtin/Intl.cpp @@ -22,6 +22,7 @@ #include "jscntxt.h" #include "jsobj.h" +#include "builtin/intl/CommonFunctions.h" #include "builtin/intl/ScopedICUObject.h" #include "builtin/IntlTimeZoneData.h" #include "ds/Sort.h" @@ -56,137 +57,11 @@ using mozilla::IsNaN; using mozilla::IsNegativeZero; using mozilla::PodCopy; +using js::intl::GetAvailableLocales; +using js::intl::IcuLocale; +using js::intl::INITIAL_CHAR_BUFFER_SIZE; +using js::intl::StringsAreEqual; -/* - * Pervasive note: ICU functions taking a UErrorCode in/out parameter always - * test that parameter before doing anything, and will return immediately if - * the value indicates that a failure occurred in a prior ICU call, - * without doing anything else. See - * http://userguide.icu-project.org/design#TOC-Error-Handling - */ - -/******************** Common to Intl constructors ********************/ - -static bool -IntlInitialize(JSContext* cx, HandleObject obj, Handle<PropertyName*> initializer, - HandleValue locales, HandleValue options) -{ - RootedValue initializerValue(cx); - if (!GlobalObject::getIntrinsicValue(cx, cx->global(), initializer, &initializerValue)) - return false; - MOZ_ASSERT(initializerValue.isObject()); - MOZ_ASSERT(initializerValue.toObject().is<JSFunction>()); - - FixedInvokeArgs<3> args(cx); - - args[0].setObject(*obj); - args[1].set(locales); - args[2].set(options); - - RootedValue thisv(cx, NullValue()); - RootedValue ignored(cx); - return js::Call(cx, initializerValue, thisv, args, &ignored); -} - -static bool -CreateDefaultOptions(JSContext* cx, MutableHandleValue defaultOptions) -{ - RootedObject options(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr)); - if (!options) - return false; - defaultOptions.setObject(*options); - return true; -} - -// CountAvailable and GetAvailable describe the signatures used for ICU API -// to determine available locales for various functionality. -typedef int32_t -(* CountAvailable)(); - -typedef const char* -(* GetAvailable)(int32_t localeIndex); - -static bool -intl_availableLocales(JSContext* cx, CountAvailable countAvailable, - GetAvailable getAvailable, MutableHandleValue result) -{ - RootedObject locales(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr)); - if (!locales) - return false; - - uint32_t count = countAvailable(); - RootedValue t(cx, BooleanValue(true)); - for (uint32_t i = 0; i < count; i++) { - const char* locale = getAvailable(i); - auto lang = DuplicateString(cx, locale); - if (!lang) - return false; - char* p; - while ((p = strchr(lang.get(), '_'))) - *p = '-'; - RootedAtom a(cx, Atomize(cx, lang.get(), strlen(lang.get()))); - if (!a) - return false; - if (!DefineProperty(cx, locales, a->asPropertyName(), t, nullptr, nullptr, - JSPROP_ENUMERATE)) - { - return false; - } - } - - result.setObject(*locales); - return true; -} - -/** - * Returns the object holding the internal properties for obj. - */ -static JSObject* -GetInternals(JSContext* cx, HandleObject obj) -{ - RootedValue getInternalsValue(cx); - if (!GlobalObject::getIntrinsicValue(cx, cx->global(), cx->names().getInternals, - &getInternalsValue)) - { - return nullptr; - } - MOZ_ASSERT(getInternalsValue.isObject()); - MOZ_ASSERT(getInternalsValue.toObject().is<JSFunction>()); - - FixedInvokeArgs<1> args(cx); - - args[0].setObject(*obj); - - RootedValue v(cx, NullValue()); - if (!js::Call(cx, getInternalsValue, v, args, &v)) - return nullptr; - - return &v.toObject(); -} - -static bool -equal(const char* s1, const char* s2) -{ - return !strcmp(s1, s2); -} - -static bool -equal(JSAutoByteString& s1, const char* s2) -{ - return !strcmp(s1.ptr(), s2); -} - -static const char* -icuLocale(const char* locale) -{ - if (equal(locale, "und")) - return ""; // ICU root locale - return locale; -} - - -// The inline capacity we use for the char16_t Vectors. -static const size_t INITIAL_CHAR_BUFFER_SIZE = 32; /******************** Collator ********************/ @@ -295,7 +170,7 @@ Collator(JSContext* cx, const CallArgs& args, bool construct) RootedValue options(cx, args.length() > 1 ? args[1] : UndefinedValue()); // Step 6. - if (!IntlInitialize(cx, obj, cx->names().InitializeCollator, locales, options)) + if (!intl::InitializeObject(cx, obj, cx->names().InitializeCollator, locales, options)) return false; args.rval().setObject(*obj); @@ -376,11 +251,11 @@ CreateCollatorPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObject*> } RootedValue options(cx); - if (!CreateDefaultOptions(cx, &options)) + if (!intl::CreateDefaultOptions(cx, &options)) return nullptr; // 10.2.1 and 10.3 - if (!IntlInitialize(cx, proto, cx->names().InitializeCollator, UndefinedHandleValue, options)) + if (!intl::InitializeObject(cx, proto, cx->names().InitializeCollator, UndefinedHandleValue, options)) return nullptr; // 8.1 @@ -398,7 +273,7 @@ js::intl_Collator_availableLocales(JSContext* cx, unsigned argc, Value* vp) MOZ_ASSERT(args.length() == 0); RootedValue result(cx); - if (!intl_availableLocales(cx, ucol_countAvailable, ucol_getAvailable, &result)) + if (!GetAvailableLocales(cx, ucol_countAvailable, ucol_getAvailable, &result)) return false; args.rval().set(result); return true; @@ -417,14 +292,14 @@ js::intl_availableCollations(JSContext* cx, unsigned argc, Value* vp) UErrorCode status = U_ZERO_ERROR; UEnumeration* values = ucol_getKeywordValuesForLocale("co", locale.ptr(), false, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } ScopedICUObject<UEnumeration, uenum_close> toClose(values); uint32_t count = uenum_count(values, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -436,7 +311,7 @@ js::intl_availableCollations(JSContext* cx, unsigned argc, Value* vp) for (uint32_t i = 0; i < count; i++) { const char* collation = uenum_next(values, nullptr, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -444,18 +319,18 @@ js::intl_availableCollations(JSContext* cx, unsigned argc, Value* vp) // "The values 'standard' and 'search' must not be used as elements in // any [[sortLocaleData]][locale].co and [[searchLocaleData]][locale].co // array." - if (equal(collation, "standard") || equal(collation, "search")) + if (StringsAreEqual(collation, "standard") || StringsAreEqual(collation, "search")) continue; // ICU returns old-style keyword values; map them to BCP 47 equivalents // (see http://bugs.icu-project.org/trac/ticket/9620). - if (equal(collation, "dictionary")) + if (StringsAreEqual(collation, "dictionary")) collation = "dict"; - else if (equal(collation, "gb2312han")) + else if (StringsAreEqual(collation, "gb2312han")) collation = "gb2312"; - else if (equal(collation, "phonebook")) + else if (StringsAreEqual(collation, "phonebook")) collation = "phonebk"; - else if (equal(collation, "traditional")) + else if (StringsAreEqual(collation, "traditional")) collation = "trad"; RootedString jscollation(cx, JS_NewStringCopyZ(cx, collation)); @@ -479,7 +354,7 @@ NewUCollator(JSContext* cx, HandleObject collator) { RootedValue value(cx); - RootedObject internals(cx, GetInternals(cx, collator)); + RootedObject internals(cx, intl::GetInternalsObject(cx, collator)); if (!internals) return nullptr; @@ -503,7 +378,7 @@ NewUCollator(JSContext* cx, HandleObject collator) JSAutoByteString usage(cx, value.toString()); if (!usage) return nullptr; - if (equal(usage, "search")) { + if (StringsAreEqual(usage, "search")) { // ICU expects search as a Unicode locale extension on locale. // Unicode locale extensions must occur before private use extensions. const char* oldLocale = locale.ptr(); @@ -542,15 +417,15 @@ NewUCollator(JSContext* cx, HandleObject collator) JSAutoByteString sensitivity(cx, value.toString()); if (!sensitivity) return nullptr; - if (equal(sensitivity, "base")) { + if (StringsAreEqual(sensitivity, "base")) { uStrength = UCOL_PRIMARY; - } else if (equal(sensitivity, "accent")) { + } else if (StringsAreEqual(sensitivity, "accent")) { uStrength = UCOL_SECONDARY; - } else if (equal(sensitivity, "case")) { + } else if (StringsAreEqual(sensitivity, "case")) { uStrength = UCOL_PRIMARY; uCaseLevel = UCOL_ON; } else { - MOZ_ASSERT(equal(sensitivity, "variant")); + MOZ_ASSERT(StringsAreEqual(sensitivity, "variant")); uStrength = UCOL_TERTIARY; } @@ -575,18 +450,18 @@ NewUCollator(JSContext* cx, HandleObject collator) JSAutoByteString caseFirst(cx, value.toString()); if (!caseFirst) return nullptr; - if (equal(caseFirst, "upper")) + if (StringsAreEqual(caseFirst, "upper")) uCaseFirst = UCOL_UPPER_FIRST; - else if (equal(caseFirst, "lower")) + else if (StringsAreEqual(caseFirst, "lower")) uCaseFirst = UCOL_LOWER_FIRST; else - MOZ_ASSERT(equal(caseFirst, "false")); + MOZ_ASSERT(StringsAreEqual(caseFirst, "false")); } UErrorCode status = U_ZERO_ERROR; - UCollator* coll = ucol_open(icuLocale(locale.ptr()), &status); + UCollator* coll = ucol_open(IcuLocale(locale.ptr()), &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return nullptr; } @@ -598,7 +473,7 @@ NewUCollator(JSContext* cx, HandleObject collator) ucol_setAttribute(coll, UCOL_CASE_FIRST, uCaseFirst, &status); if (U_FAILURE(status)) { ucol_close(coll); - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return nullptr; } @@ -799,7 +674,7 @@ NumberFormat(JSContext* cx, const CallArgs& args, bool construct) RootedValue options(cx, args.length() > 1 ? args[1] : UndefinedValue()); // Step 3. - if (!IntlInitialize(cx, obj, cx->names().InitializeNumberFormat, locales, options)) + if (!intl::InitializeObject(cx, obj, cx->names().InitializeNumberFormat, locales, options)) return false; args.rval().setObject(*obj); @@ -885,11 +760,11 @@ CreateNumberFormatPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObjec } RootedValue options(cx); - if (!CreateDefaultOptions(cx, &options)) + if (!intl::CreateDefaultOptions(cx, &options)) return nullptr; // 11.2.1 and 11.3 - if (!IntlInitialize(cx, proto, cx->names().InitializeNumberFormat, UndefinedHandleValue, + if (!intl::InitializeObject(cx, proto, cx->names().InitializeNumberFormat, UndefinedHandleValue, options)) { return nullptr; @@ -910,7 +785,7 @@ js::intl_NumberFormat_availableLocales(JSContext* cx, unsigned argc, Value* vp) MOZ_ASSERT(args.length() == 0); RootedValue result(cx); - if (!intl_availableLocales(cx, unum_countAvailable, unum_getAvailable, &result)) + if (!GetAvailableLocales(cx, unum_countAvailable, unum_getAvailable, &result)) return false; args.rval().set(result); return true; @@ -928,9 +803,9 @@ js::intl_numberingSystem(JSContext* cx, unsigned argc, Value* vp) return false; UErrorCode status = U_ZERO_ERROR; - UNumberingSystem* numbers = unumsys_open(icuLocale(locale.ptr()), &status); + UNumberingSystem* numbers = unumsys_open(IcuLocale(locale.ptr()), &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -957,7 +832,7 @@ js::intl_numberingSystem(JSContext* cx, unsigned argc, Value* vp) static UNumberFormat* NewUNumberFormatForPluralRules(JSContext* cx, HandleObject pluralRules) { - RootedObject internals(cx, GetInternals(cx, pluralRules)); + RootedObject internals(cx, intl::GetInternalsObject(cx, pluralRules)); if (!internals) return nullptr; @@ -1007,9 +882,9 @@ NewUNumberFormatForPluralRules(JSContext* cx, HandleObject pluralRules) } UErrorCode status = U_ZERO_ERROR; - UNumberFormat* nf = unum_open(UNUM_DECIMAL, nullptr, 0, icuLocale(locale.ptr()), nullptr, &status); + UNumberFormat* nf = unum_open(UNUM_DECIMAL, nullptr, 0, IcuLocale(locale.ptr()), nullptr, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return nullptr; } ScopedICUObject<UNumberFormat, unum_close> toClose(nf); @@ -1037,7 +912,7 @@ NewUNumberFormat(JSContext* cx, HandleObject numberFormat) { RootedValue value(cx); - RootedObject internals(cx, GetInternals(cx, numberFormat)); + RootedObject internals(cx, intl::GetInternalsObject(cx, numberFormat)); if (!internals) return nullptr; @@ -1070,7 +945,7 @@ NewUNumberFormat(JSContext* cx, HandleObject numberFormat) if (!style) return nullptr; - if (equal(style, "currency")) { + if (StringsAreEqual(style, "currency")) { if (!GetProperty(cx, internals, internals, cx->names().currency, &value)) return nullptr; currency = value.toString(); @@ -1088,18 +963,18 @@ NewUNumberFormat(JSContext* cx, HandleObject numberFormat) JSAutoByteString currencyDisplay(cx, value.toString()); if (!currencyDisplay) return nullptr; - if (equal(currencyDisplay, "code")) { + if (StringsAreEqual(currencyDisplay, "code")) { uStyle = UNUM_CURRENCY_ISO; - } else if (equal(currencyDisplay, "symbol")) { + } else if (StringsAreEqual(currencyDisplay, "symbol")) { uStyle = UNUM_CURRENCY; } else { - MOZ_ASSERT(equal(currencyDisplay, "name")); + MOZ_ASSERT(StringsAreEqual(currencyDisplay, "name")); uStyle = UNUM_CURRENCY_PLURAL; } - } else if (equal(style, "percent")) { + } else if (StringsAreEqual(style, "percent")) { uStyle = UNUM_PERCENT; } else { - MOZ_ASSERT(equal(style, "decimal")); + MOZ_ASSERT(StringsAreEqual(style, "decimal")); uStyle = UNUM_DECIMAL; } @@ -1136,9 +1011,9 @@ NewUNumberFormat(JSContext* cx, HandleObject numberFormat) uUseGrouping = value.toBoolean(); UErrorCode status = U_ZERO_ERROR; - UNumberFormat* nf = unum_open(uStyle, nullptr, 0, icuLocale(locale.ptr()), nullptr, &status); + UNumberFormat* nf = unum_open(uStyle, nullptr, 0, IcuLocale(locale.ptr()), nullptr, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return nullptr; } ScopedICUObject<UNumberFormat, unum_close> toClose(nf); @@ -1146,7 +1021,7 @@ NewUNumberFormat(JSContext* cx, HandleObject numberFormat) if (uCurrency) { unum_setTextAttribute(nf, UNUM_CURRENCY_CODE, uCurrency, 3, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return nullptr; } } @@ -1197,7 +1072,7 @@ PartitionNumberPattern(JSContext* cx, UNumberFormat* nf, double* x, MOZ_ASSERT(size == resultSize); } if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -1296,7 +1171,7 @@ intl_FormatNumberToParts(JSContext* cx, UNumberFormat* nf, double x, MutableHand UFieldPositionIterator* fpositer = ufieldpositer_open(&status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -1782,7 +1657,7 @@ DateTimeFormat(JSContext* cx, const CallArgs& args, bool construct) RootedValue options(cx, args.length() > 1 ? args[1] : UndefinedValue()); // Step 3. - if (!IntlInitialize(cx, obj, cx->names().InitializeDateTimeFormat, locales, options)) + if (!intl::InitializeObject(cx, obj, cx->names().InitializeDateTimeFormat, locales, options)) return false; args.rval().setObject(*obj); @@ -1866,11 +1741,11 @@ CreateDateTimeFormatPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObj } RootedValue options(cx); - if (!CreateDefaultOptions(cx, &options)) + if (!intl::CreateDefaultOptions(cx, &options)) return nullptr; // 12.2.1 and 12.3 - if (!IntlInitialize(cx, proto, cx->names().InitializeDateTimeFormat, UndefinedHandleValue, + if (!intl::InitializeObject(cx, proto, cx->names().InitializeDateTimeFormat, UndefinedHandleValue, options)) { return nullptr; @@ -1891,7 +1766,7 @@ js::intl_DateTimeFormat_availableLocales(JSContext* cx, unsigned argc, Value* vp MOZ_ASSERT(args.length() == 0); RootedValue result(cx); - if (!intl_availableLocales(cx, udat_countAvailable, udat_getAvailable, &result)) + if (!GetAvailableLocales(cx, udat_countAvailable, udat_getAvailable, &result)) return false; args.rval().set(result); return true; @@ -1902,11 +1777,11 @@ js::intl_DateTimeFormat_availableLocales(JSContext* cx, unsigned argc, Value* vp static const char* bcp47CalendarName(const char* icuName) { - if (equal(icuName, "ethiopic-amete-alem")) + if (StringsAreEqual(icuName, "ethiopic-amete-alem")) return "ethioaa"; - if (equal(icuName, "gregorian")) + if (StringsAreEqual(icuName, "gregorian")) return "gregory"; - if (equal(icuName, "islamic-civil")) + if (StringsAreEqual(icuName, "islamic-civil")) return "islamicc"; return icuName; } @@ -1938,7 +1813,7 @@ js::intl_availableCalendars(JSContext* cx, unsigned argc, Value* vp) const char* calendar = ucal_getType(cal, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -1954,21 +1829,21 @@ js::intl_availableCalendars(JSContext* cx, unsigned argc, Value* vp) // Now get the calendars that "would make a difference", i.e., not the default. UEnumeration* values = ucal_getKeywordValuesForLocale("ca", locale.ptr(), false, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } ScopedICUObject<UEnumeration, uenum_close> toClose(values); uint32_t count = uenum_count(values, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } for (; count > 0; count--) { const char* calendar = uenum_next(values, nullptr, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -2057,7 +1932,7 @@ static bool IsLegacyICUTimeZone(const char* timeZone) { for (const auto& legacyTimeZone : js::timezone::legacyICUTimeZones) { - if (equal(timeZone, legacyTimeZone)) + if (StringsAreEqual(timeZone, legacyTimeZone)) return true; } return false; @@ -2081,7 +1956,7 @@ js::SharedIntlData::ensureTimeZones(JSContext* cx) UErrorCode status = U_ZERO_ERROR; UEnumeration* values = ucal_openTimeZones(&status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } ScopedICUObject<UEnumeration, uenum_close> toClose(values); @@ -2091,7 +1966,7 @@ js::SharedIntlData::ensureTimeZones(JSContext* cx) int32_t size; const char* rawTimeZone = uenum_next(values, &size, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -2325,7 +2200,7 @@ js::intl_canonicalizeTimeZone(JSContext* cx, unsigned argc, Value* vp) Char16ToUChar(chars.begin()), size, isSystemID, &status); } if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -2363,7 +2238,7 @@ js::intl_defaultTimeZone(JSContext* cx, unsigned argc, Value* vp) ucal_getDefaultTimeZone(Char16ToUChar(chars.begin()), size, &status); } if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -2386,14 +2261,14 @@ js::intl_defaultTimeZoneOffset(JSContext* cx, unsigned argc, Value* vp) { const char* rootLocale = ""; UCalendar* cal = ucal_open(uTimeZone, uTimeZoneLength, rootLocale, UCAL_DEFAULT, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } ScopedICUObject<UCalendar, ucal_close> toClose(cal); int32_t offset = ucal_get(cal, UCAL_ZONE_OFFSET, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -2425,9 +2300,9 @@ js::intl_patternForSkeleton(JSContext* cx, unsigned argc, Value* vp) uint32_t skeletonLen = u_strlen(Char16ToUChar(skeletonChars.begin().get())); UErrorCode status = U_ZERO_ERROR; - UDateTimePatternGenerator* gen = udatpg_open(icuLocale(locale.ptr()), &status); + UDateTimePatternGenerator* gen = udatpg_open(IcuLocale(locale.ptr()), &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } ScopedICUObject<UDateTimePatternGenerator, udatpg_close> toClose(gen); @@ -2435,7 +2310,7 @@ js::intl_patternForSkeleton(JSContext* cx, unsigned argc, Value* vp) int32_t size = udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.begin().get()), skeletonLen, nullptr, 0, &status); if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } ScopedJSFreePtr<UChar> pattern(cx->pod_malloc<UChar>(size + 1)); @@ -2446,7 +2321,7 @@ js::intl_patternForSkeleton(JSContext* cx, unsigned argc, Value* vp) udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.begin().get()), skeletonLen, pattern, size, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -2466,7 +2341,7 @@ NewUDateFormat(JSContext* cx, HandleObject dateTimeFormat) { RootedValue value(cx); - RootedObject internals(cx, GetInternals(cx, dateTimeFormat)); + RootedObject internals(cx, intl::GetInternalsObject(cx, dateTimeFormat)); if (!internals) return nullptr; @@ -2504,10 +2379,10 @@ NewUDateFormat(JSContext* cx, HandleObject dateTimeFormat) UErrorCode status = U_ZERO_ERROR; UDateFormat* df = - udat_open(UDAT_PATTERN, UDAT_PATTERN, icuLocale(locale.ptr()), uTimeZone, uTimeZoneLength, + udat_open(UDAT_PATTERN, UDAT_PATTERN, IcuLocale(locale.ptr()), uTimeZone, uTimeZoneLength, uPattern, uPatternLength, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return nullptr; } @@ -2542,7 +2417,7 @@ intl_FormatDateTime(JSContext* cx, UDateFormat* df, double x, MutableHandleValue udat_format(df, x, Char16ToUChar(chars.begin()), size, nullptr, &status); } if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -2656,7 +2531,7 @@ intl_FormatToPartsDateTime(JSContext* cx, UDateFormat* df, double x, MutableHand UErrorCode status = U_ZERO_ERROR; UFieldPositionIterator* fpositer = ufieldpositer_open(&status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } ScopedICUObject<UFieldPositionIterator, ufieldpositer_close> toClose(fpositer); @@ -2671,7 +2546,7 @@ intl_FormatToPartsDateTime(JSContext* cx, UDateFormat* df, double x, MutableHand udat_formatForFields(df, x, Char16ToUChar(chars.begin()), resultSize, fpositer, &status); } if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -2899,7 +2774,7 @@ PluralRules(JSContext* cx, const CallArgs& args, bool construct) RootedValue locales(cx, args.get(0)); RootedValue options(cx, args.get(1)); - if (!IntlInitialize(cx, obj, cx->names().InitializePluralRules, locales, options)) + if (!intl::InitializeObject(cx, obj, cx->names().InitializePluralRules, locales, options)) return false; args.rval().setObject(*obj); @@ -2960,10 +2835,10 @@ CreatePluralRulesPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObject return nullptr; RootedValue options(cx); - if (!CreateDefaultOptions(cx, &options)) + if (!intl::CreateDefaultOptions(cx, &options)) return nullptr; - if (!IntlInitialize(cx, proto, cx->names().InitializePluralRules, UndefinedHandleValue, + if (!intl::InitializeObject(cx, proto, cx->names().InitializePluralRules, UndefinedHandleValue, options)) { return nullptr; @@ -2985,7 +2860,7 @@ js::intl_PluralRules_availableLocales(JSContext* cx, unsigned argc, Value* vp) RootedValue result(cx); // We're going to use ULocale availableLocales as per ICU recommendation: // https://ssl.icu-project.org/trac/ticket/12756 - if (!intl_availableLocales(cx, uloc_countAvailable, uloc_getAvailable, &result)) + if (!GetAvailableLocales(cx, uloc_countAvailable, uloc_getAvailable, &result)) return false; args.rval().set(result); return true; @@ -3004,7 +2879,7 @@ js::intl_SelectPluralRule(JSContext* cx, unsigned argc, Value* vp) ScopedICUObject<UNumberFormat, unum_close> closeNumberFormat(nf); - RootedObject internals(cx, GetInternals(cx, pluralRules)); + RootedObject internals(cx, intl::GetInternalsObject(cx, pluralRules)); if (!internals) return false; @@ -3046,7 +2921,7 @@ js::intl_SelectPluralRule(JSContext* cx, unsigned argc, Value* vp) UFormattable* fmt = unum_parseToUFormattable(nf, nullptr, uFmtNumValue, stableChars.twoByteRange().length(), 0, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -3054,22 +2929,22 @@ js::intl_SelectPluralRule(JSContext* cx, unsigned argc, Value* vp) double y = ufmt_getDouble(fmt, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } UPluralType category; - if (equal(type, "cardinal")) { + if (StringsAreEqual(type, "cardinal")) { category = UPLURAL_TYPE_CARDINAL; } else { - MOZ_ASSERT(equal(type, "ordinal")); + MOZ_ASSERT(StringsAreEqual(type, "ordinal")); category = UPLURAL_TYPE_ORDINAL; } - UPluralRules* pr = uplrules_openForType(icuLocale(locale.ptr()), category, &status); + UPluralRules* pr = uplrules_openForType(IcuLocale(locale.ptr()), category, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -3087,7 +2962,7 @@ js::intl_SelectPluralRule(JSContext* cx, unsigned argc, Value* vp) uplrules_select(pr, y, Char16ToUChar(chars.begin()), size, &status); } if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -3117,20 +2992,20 @@ js::intl_GetPluralCategories(JSContext* cx, unsigned argc, Value* vp) UPluralType category; - if (equal(type, "cardinal")) { + if (StringsAreEqual(type, "cardinal")) { category = UPLURAL_TYPE_CARDINAL; } else { - MOZ_ASSERT(equal(type, "ordinal")); + MOZ_ASSERT(StringsAreEqual(type, "ordinal")); category = UPLURAL_TYPE_ORDINAL; } UPluralRules* pr = uplrules_openForType( - icuLocale(locale.ptr()), + IcuLocale(locale.ptr()), category, &status ); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -3144,7 +3019,7 @@ js::intl_GetPluralCategories(JSContext* cx, unsigned argc, Value* vp) UEnumeration* ue = uenum_openFromStringEnumeration(kwenum, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -3162,7 +3037,7 @@ js::intl_GetPluralCategories(JSContext* cx, unsigned argc, Value* vp) do { cat = uenum_next(ue, &catSize, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -3271,7 +3146,7 @@ RelativeTimeFormat(JSContext* cx, unsigned argc, Value* vp) RootedValue options(cx, args.get(1)); // Step 3. - if (!IntlInitialize(cx, relativeTimeFormat, cx->names().InitializeRelativeTimeFormat, locales, options)) + if (!intl::InitializeObject(cx, relativeTimeFormat, cx->names().InitializeRelativeTimeFormat, locales, options)) return false; args.rval().setObject(*relativeTimeFormat); @@ -3320,10 +3195,10 @@ CreateRelativeTimeFormatPrototype(JSContext* cx, HandleObject Intl, Handle<Globa return nullptr; RootedValue options(cx); - if (!CreateDefaultOptions(cx, &options)) + if (!intl::CreateDefaultOptions(cx, &options)) return nullptr; - if (!IntlInitialize(cx, proto, cx->names().InitializeRelativeTimeFormat, UndefinedHandleValue, + if (!intl::InitializeObject(cx, proto, cx->names().InitializeRelativeTimeFormat, UndefinedHandleValue, options)) { return nullptr; @@ -3346,7 +3221,7 @@ js::intl_RelativeTimeFormat_availableLocales(JSContext* cx, unsigned argc, Value RootedValue result(cx); // We're going to use ULocale availableLocales as per ICU recommendation: // https://ssl.icu-project.org/trac/ticket/12756 - if (!intl_availableLocales(cx, uloc_countAvailable, uloc_getAvailable, &result)) + if (!GetAvailableLocales(cx, uloc_countAvailable, uloc_getAvailable, &result)) return false; args.rval().set(result); return true; @@ -3374,7 +3249,7 @@ js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp) RootedObject relativeTimeFormat(cx, &args[0].toObject()); - RootedObject internals(cx, GetInternals(cx, relativeTimeFormat)); + RootedObject internals(cx, intl::GetInternalsObject(cx, relativeTimeFormat)); if (!internals) return false; @@ -3452,10 +3327,10 @@ js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp) return false; UErrorCode status = U_ZERO_ERROR; URelativeDateTimeFormatter* rtf = - ureldatefmt_open(icuLocale(locale.ptr()), nullptr, relDateTimeStyle, + ureldatefmt_open(IcuLocale(locale.ptr()), nullptr, relDateTimeStyle, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -3495,7 +3370,7 @@ js::intl_GetCalendarInfo(JSContext* cx, unsigned argc, Value* vp) int32_t uTimeZoneLength = 0; UCalendar* cal = ucal_open(uTimeZone, uTimeZoneLength, locale.ptr(), UCAL_DEFAULT, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } ScopedICUObject<UCalendar, ucal_close> toClose(cal); @@ -3518,7 +3393,7 @@ js::intl_GetCalendarInfo(JSContext* cx, unsigned argc, Value* vp) UCalendarWeekdayType prevDayType = ucal_getDayOfWeekType(cal, UCAL_SATURDAY, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -3528,7 +3403,7 @@ js::intl_GetCalendarInfo(JSContext* cx, unsigned argc, Value* vp) UCalendarDaysOfWeek dayOfWeek = static_cast<UCalendarDaysOfWeek>(i); UCalendarWeekdayType type = ucal_getDayOfWeekType(cal, dayOfWeek, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -3548,7 +3423,7 @@ js::intl_GetCalendarInfo(JSContext* cx, unsigned argc, Value* vp) // At the time this code was added, ICU apparently never behaves this way, // so just throw, so that users will report a bug and we can decide what to // do. - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; default: break; @@ -3614,19 +3489,19 @@ js::intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp) UErrorCode status = U_ZERO_ERROR; UDateFormat* fmt = - udat_open(UDAT_DEFAULT, UDAT_DEFAULT, icuLocale(locale.ptr()), + udat_open(UDAT_DEFAULT, UDAT_DEFAULT, IcuLocale(locale.ptr()), nullptr, 0, nullptr, 0, &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } ScopedICUObject<UDateFormat, udat_close> datToClose(fmt); // UDateTimePatternGenerator will be needed for translations of date and // time fields like "month", "week", "day" etc. - UDateTimePatternGenerator* dtpg = udatpg_open(icuLocale(locale.ptr()), &status); + UDateTimePatternGenerator* dtpg = udatpg_open(IcuLocale(locale.ptr()), &status); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } ScopedICUObject<UDateTimePatternGenerator, udatpg_close> datPgToClose(dtpg); @@ -3703,7 +3578,7 @@ js::intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp) const UChar* value = udatpg_getAppendItemName(dtpg, fieldType, &resultSize); if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } @@ -3727,12 +3602,12 @@ js::intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp) return false; } - if (equal(style, "narrow")) { + if (StringsAreEqual(style, "narrow")) { symbolType = UDAT_STANDALONE_NARROW_MONTHS; - } else if (equal(style, "short")) { + } else if (StringsAreEqual(style, "short")) { symbolType = UDAT_STANDALONE_SHORT_MONTHS; } else { - MOZ_ASSERT(equal(style, "long")); + MOZ_ASSERT(StringsAreEqual(style, "long")); symbolType = UDAT_STANDALONE_MONTHS; } @@ -3770,12 +3645,12 @@ js::intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp) return false; } - if (equal(style, "narrow")) { + if (StringsAreEqual(style, "narrow")) { symbolType = UDAT_STANDALONE_NARROW_WEEKDAYS; - } else if (equal(style, "short")) { + } else if (StringsAreEqual(style, "short")) { symbolType = UDAT_STANDALONE_SHORT_WEEKDAYS; } else { - MOZ_ASSERT(equal(style, "long")); + MOZ_ASSERT(StringsAreEqual(style, "long")); symbolType = UDAT_STANDALONE_WEEKDAYS; } @@ -3835,7 +3710,7 @@ js::intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp) resultSize, &status); } if (U_FAILURE(status)) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR); + intl::ReportInternalError(cx); return false; } diff --git a/js/src/builtin/intl/CommonFunctions.cpp b/js/src/builtin/intl/CommonFunctions.cpp new file mode 100644 index 0000000000..6a006246b0 --- /dev/null +++ b/js/src/builtin/intl/CommonFunctions.cpp @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * 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/. */
+
+/* Operations used to implement multiple Intl.* classes. */
+
+#include "builtin/intl/CommonFunctions.h"
+
+#include "mozilla/Assertions.h"
+
+#include "jscntxt.h"
+#include "jsfriendapi.h" // for GetErrorMessage, JSMSG_INTERNAL_INTL_ERROR
+#include "jsobj.h"
+
+#include "js/Value.h"
+#include "vm/SelfHosting.h"
+#include "vm/Stack.h"
+
+#include "jsobjinlines.h"
+
+bool
+js::intl::CreateDefaultOptions(JSContext* cx, MutableHandleValue defaultOptions)
+{
+ RootedObject options(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr));
+ if (!options)
+ return false;
+ defaultOptions.setObject(*options);
+ return true;
+}
+
+bool
+js::intl::InitializeObject(JSContext* cx, HandleObject obj, Handle<PropertyName*> initializer,
+ HandleValue locales, HandleValue options)
+{
+ RootedValue initializerValue(cx);
+ if (!GlobalObject::getIntrinsicValue(cx, cx->global(), initializer, &initializerValue))
+ return false;
+ MOZ_ASSERT(initializerValue.isObject());
+ MOZ_ASSERT(initializerValue.toObject().is<JSFunction>());
+
+ FixedInvokeArgs<3> args(cx);
+
+ args[0].setObject(*obj);
+ args[1].set(locales);
+ args[2].set(options);
+
+ RootedValue thisv(cx, NullValue());
+ RootedValue ignored(cx);
+ return js::Call(cx, initializerValue, thisv, args, &ignored);
+}
+
+/**
+ * Returns the object holding the internal properties for obj.
+ */
+JSObject*
+js::intl::GetInternalsObject(JSContext* cx, HandleObject obj)
+{
+ RootedValue getInternalsValue(cx);
+ if (!GlobalObject::getIntrinsicValue(cx, cx->global(), cx->names().getInternals,
+ &getInternalsValue))
+ {
+ return nullptr;
+ }
+ MOZ_ASSERT(getInternalsValue.isObject());
+ MOZ_ASSERT(getInternalsValue.toObject().is<JSFunction>());
+
+ FixedInvokeArgs<1> args(cx);
+
+ args[0].setObject(*obj);
+
+ RootedValue v(cx, NullValue());
+ if (!js::Call(cx, getInternalsValue, v, args, &v))
+ return nullptr;
+
+ return &v.toObject();
+}
+
+void
+js::intl::ReportInternalError(JSContext* cx)
+{
+ JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
+}
+
+bool
+js::intl::GetAvailableLocales(JSContext* cx, CountAvailable countAvailable,
+ GetAvailable getAvailable, MutableHandleValue result)
+{
+ RootedObject locales(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr));
+ if (!locales)
+ return false;
+
+ uint32_t count = countAvailable();
+ RootedValue t(cx, BooleanValue(true));
+ for (uint32_t i = 0; i < count; i++) {
+ const char* locale = getAvailable(i);
+ auto lang = DuplicateString(cx, locale);
+ if (!lang)
+ return false;
+ char* p;
+ while ((p = strchr(lang.get(), '_')))
+ *p = '-';
+ RootedAtom a(cx, Atomize(cx, lang.get(), strlen(lang.get())));
+ if (!a)
+ return false;
+ if (!DefineProperty(cx, locales, a->asPropertyName(), t, nullptr, nullptr,
+ JSPROP_ENUMERATE))
+ {
+ return false;
+ }
+ }
+
+ result.setObject(*locales);
+ return true;
+}
diff --git a/js/src/builtin/intl/CommonFunctions.h b/js/src/builtin/intl/CommonFunctions.h new file mode 100644 index 0000000000..1132333309 --- /dev/null +++ b/js/src/builtin/intl/CommonFunctions.h @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * 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/. */
+
+#ifndef builtin_intl_CommonFunctions_h
+#define builtin_intl_CommonFunctions_h
+
+#include "mozilla/Assertions.h"
+#include "mozilla/TypeTraits.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "js/RootingAPI.h"
+#include "js/Vector.h"
+#include "vm/String.h"
+
+namespace JS { class Value; }
+
+class JSObject;
+
+namespace js {
+
+namespace intl {
+
+/**
+ * Setup the |options| argument of |IntlInitialize|
+ */
+extern bool
+CreateDefaultOptions(JSContext* cx, MutableHandleValue defaultOptions);
+
+/**
+ * Initialize a new Intl.* object using the named self-hosted function.
+ */
+extern bool
+InitializeObject(JSContext* cx, HandleObject obj, Handle<PropertyName*> initializer,
+ HandleValue locales, HandleValue options);
+
+/**
+ * Returns the object holding the internal properties for obj.
+ */
+extern JSObject*
+GetInternalsObject(JSContext* cx, JS::Handle<JSObject*> obj);
+
+/** Report an Intl internal error not directly tied to a spec step. */
+extern void
+ReportInternalError(JSContext* cx);
+
+static inline bool
+StringsAreEqual(const char* s1, const char* s2)
+{
+ return !strcmp(s1, s2);
+}
+
+static inline bool
+StringsAreEqual(JSAutoByteString& s1, const char* s2)
+{
+ return !strcmp(s1.ptr(), s2);
+}
+
+static inline const char*
+IcuLocale(const char* locale)
+{
+ if (StringsAreEqual(locale, "und"))
+ return ""; // ICU root locale
+
+ return 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.
+static const size_t INITIAL_CHAR_BUFFER_SIZE = 32;
+
+// CountAvailable and GetAvailable describe the signatures used for ICU API
+// to determine available locales for various functionality.
+using CountAvailable = int32_t (*)();
+using GetAvailable = const char* (*)(int32_t localeIndex);
+
+/**
+ * Return an object whose own property names are the locales indicated as
+ * available by |countAvailable| that provides an overall count, and by
+ * |getAvailable| that when called passing a number less than that count,
+ * returns the corresponding locale as a borrowed string. For example:
+ *
+ * RootedValue v(cx);
+ * if (!GetAvailableLocales(cx, unum_countAvailable, unum_getAvailable, &v))
+ * return false;
+ */
+extern bool
+GetAvailableLocales(JSContext* cx, CountAvailable countAvailable, GetAvailable getAvailable,
+ JS::MutableHandle<JS::Value> result);
+
+} // namespace intl
+
+} // namespace js
+
+#endif /* builtin_intl_CommonFunctions_h */
\ No newline at end of file diff --git a/js/src/moz.build b/js/src/moz.build index 948840139c..165ccd2d0c 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -115,6 +115,7 @@ UNIFIED_SOURCES += [ 'builtin/AtomicsObject.cpp', 'builtin/Eval.cpp', 'builtin/Intl.cpp', + 'builtin/intl/CommonFunctions.cpp', 'builtin/MapObject.cpp', 'builtin/ModuleObject.cpp', 'builtin/Object.cpp', |