Changeset 281513 in webkit
- Timestamp:
- Aug 24, 2021 12:28:30 PM (11 months ago)
- Location:
- trunk
- Files:
-
- 1 added
- 13 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/stress/intl-datetimeformat.js (modified) (2 diffs)
-
JSTests/stress/intl-enumeration.js (added)
-
JSTests/stress/intl-locale-info.js (modified) (3 diffs)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/IntlLocale.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IntlNumberFormat.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IntlObject.cpp (modified) (7 diffs)
-
Source/JavaScriptCore/runtime/IntlObject.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/OptionsList.h (modified) (1 diff)
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/wtf/text/StringImpl.cpp (modified) (1 diff)
-
Source/WTF/wtf/text/StringImpl.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r281500 r281513 1 2021-08-24 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Add Intl Enumeration APIs 4 https://bugs.webkit.org/show_bug.cgi?id=214795 5 6 Reviewed by Ross Kirsling. 7 8 * stress/intl-datetimeformat.js: 9 * stress/intl-enumeration.js: Added. 10 (shouldBe): 11 (shouldThrow): 12 * stress/intl-locale-info.js: 13 (let.l.new.Intl.Locale.shouldBe): 14 (shouldBe): 15 1 16 2021-08-24 Keith Miller <keith_miller@apple.com> 2 17 -
trunk/JSTests/stress/intl-datetimeformat.js
r276285 r281513 315 315 shouldBe(Intl.DateTimeFormat('en-u-ca-coptic').resolvedOptions().calendar, 'coptic'); 316 316 shouldBe(Intl.DateTimeFormat('en-u-ca-dangi').resolvedOptions().calendar, 'dangi'); 317 shouldBeForICUVersion(62, Intl.DateTimeFormat('en-u-ca-ethioaa').resolvedOptions().calendar, 'ethio pic-amete-alem');317 shouldBeForICUVersion(62, Intl.DateTimeFormat('en-u-ca-ethioaa').resolvedOptions().calendar, 'ethioaa'); 318 318 shouldBe(Intl.DateTimeFormat('en-u-ca-ethiopic').resolvedOptions().calendar, 'ethiopic'); 319 319 shouldBe(Intl.DateTimeFormat('ar-SA-u-ca-gregory').resolvedOptions().calendar, 'gregory'); … … 326 326 shouldBe(Intl.DateTimeFormat('en-u-ca-persian').resolvedOptions().calendar, 'persian'); 327 327 shouldBe(Intl.DateTimeFormat('en-u-ca-roc').resolvedOptions().calendar, 'roc'); 328 shouldBeForICUVersion(62, Intl.DateTimeFormat('en-u-ca-ethiopic-amete-alem').resolvedOptions().calendar, 'ethio pic-amete-alem');328 shouldBeForICUVersion(62, Intl.DateTimeFormat('en-u-ca-ethiopic-amete-alem').resolvedOptions().calendar, 'ethioaa'); 329 329 shouldBe(Intl.DateTimeFormat('en-u-ca-islamic-umalqura').resolvedOptions().calendar, 'islamic-umalqura'); 330 330 shouldBe(Intl.DateTimeFormat('en-u-ca-islamic-tbla').resolvedOptions().calendar, 'islamic-tbla'); -
trunk/JSTests/stress/intl-locale-info.js
r281421 r281513 18 18 { 19 19 let locale = new Intl.Locale("ar") 20 shouldBe(JSON.stringify(locale.calendars), `["gregory","coptic","islamic","islamic c","islamic-tbla"]`);20 shouldBe(JSON.stringify(locale.calendars), `["gregory","coptic","islamic","islamic-civil","islamic-tbla"]`); 21 21 shouldBe(JSON.stringify(locale.collations), `["compat","emoji","eor"]`); 22 22 shouldBe(JSON.stringify(locale.hourCycles), `["h12"]`); … … 27 27 { 28 28 let locale = new Intl.Locale("ar-EG") 29 shouldBe(JSON.stringify(locale.calendars), `["gregory","coptic","islamic","islamic c","islamic-tbla"]`);29 shouldBe(JSON.stringify(locale.calendars), `["gregory","coptic","islamic","islamic-civil","islamic-tbla"]`); 30 30 shouldBe(JSON.stringify(locale.collations), `["compat","emoji","eor"]`); 31 31 shouldBe(JSON.stringify(locale.hourCycles), `["h12"]`); … … 100 100 { 101 101 let locale = new Intl.Locale("fa") 102 shouldBe(JSON.stringify(locale.calendars), `["persian","gregory","islamic","islamic c","islamic-tbla"]`);102 shouldBe(JSON.stringify(locale.calendars), `["persian","gregory","islamic","islamic-civil","islamic-tbla"]`); 103 103 shouldBe(JSON.stringify(locale.collations), `["emoji","eor"]`); 104 104 shouldBe(JSON.stringify(locale.hourCycles), `["h23"]`); -
trunk/Source/JavaScriptCore/ChangeLog
r281500 r281513 1 2021-08-24 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Add Intl Enumeration APIs 4 https://bugs.webkit.org/show_bug.cgi?id=214795 5 6 Reviewed by Ross Kirsling. 7 8 This patch implements Intl enumeration API[1] which is in stage-3. 9 Supported keys are, "calendar", "collation", "currency", "numberingSystem", "timeZone", and "unit". 10 11 [1]: https://github.com/tc39/proposal-intl-enumeration 12 13 * runtime/IntlDateTimeFormat.cpp: 14 (JSC::IntlDateTimeFormat::localeData): 15 (JSC::IntlDateTimeFormat::initializeDateTimeFormat): 16 * runtime/IntlLocale.cpp: 17 (JSC::createArrayFromStringVector): Deleted. 18 * runtime/IntlNumberFormat.cpp: 19 (JSC::sanctionedSimpleUnitIdentifier): 20 * runtime/IntlObject.cpp: 21 (JSC::IntlObject::finishCreation): 22 (JSC::mapICUCalendarKeywordToBCP47): 23 (JSC::availableCalendars): 24 (JSC::availableCollations): 25 (JSC::availableCurrencies): 26 (JSC::availableNumberingSystems): 27 (JSC::canonicalizeTimeZoneNameFromICUTimeZone): 28 (JSC::availableTimeZones): 29 (JSC::availableUnits): 30 (JSC::JSC_DEFINE_HOST_FUNCTION): 31 (JSC::createArrayFromStringVector): 32 * runtime/IntlObject.h: 33 * runtime/OptionsList.h: 34 1 35 2021-08-24 Keith Miller <keith_miller@apple.com> 2 36 -
trunk/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
r281383 r281513 166 166 String calendar = String(availableName, nameLength); 167 167 keyLocaleData.append(calendar); 168 // Adding "islamicc" candidate for backward compatibility. 169 if (calendar == "islamic-civil"_s) 170 keyLocaleData.append("islamicc"_s); 168 171 if (auto mapped = mapICUCalendarKeywordToBCP47(calendar)) 169 172 keyLocaleData.append(WTFMove(mapped.value())); … … 580 583 } 581 584 582 m_calendar = resolved.extensions[static_cast<unsigned>(RelevantExtensionKey::Ca)];583 if (m_calendar == "gregorian")584 m_calendar = "gregory"_s;585 else if (m_calendar == "islamicc")586 m_calendar = "islamic-civil"_s;587 else if (m_calendar == "ethioaa")588 m_calendar = "ethiopic-amete-alem"_s;585 { 586 String calendar = resolved.extensions[static_cast<unsigned>(RelevantExtensionKey::Ca)]; 587 if (auto mapped = mapICUCalendarKeywordToBCP47(calendar)) 588 m_calendar = WTFMove(mapped.value()); 589 else 590 m_calendar = WTFMove(calendar); 591 } 589 592 590 593 hourCycle = parseHourCycle(resolved.extensions[static_cast<unsigned>(RelevantExtensionKey::Hc)]); -
trunk/Source/JavaScriptCore/runtime/IntlLocale.cpp
r281374 r281513 538 538 } 539 539 540 static inline JSArray* createArrayFromStringVector(JSGlobalObject* globalObject, Vector<String, 1>&& elements)541 {542 VM& vm = globalObject->vm();543 auto scope = DECLARE_THROW_SCOPE(vm);544 545 JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), elements.size());546 if (!result) {547 throwOutOfMemoryError(globalObject, scope);548 return nullptr;549 }550 for (unsigned index = 0; index < elements.size(); ++index) {551 result->putDirectIndex(globalObject, index, jsString(vm, WTFMove(elements[index])));552 RETURN_IF_EXCEPTION(scope, { });553 }554 return result;555 }556 557 540 JSArray* IntlLocale::calendars(JSGlobalObject* globalObject) 558 541 { -
trunk/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp
r278697 r281513 152 152 } 153 153 154 // Create MeasureUnit like ICU4J.155 struct MeasureUnit {156 ASCIILiteral type;157 ASCIILiteral subType;158 };159 160 154 static std::optional<MeasureUnit> sanctionedSimpleUnitIdentifier(StringView unitIdentifier) 161 155 { 162 static constexpr MeasureUnit simpleUnits[] = {163 { "area"_s, "acre"_s },164 { "digital"_s, "bit"_s },165 { "digital"_s, "byte"_s },166 { "temperature"_s, "celsius"_s },167 { "length"_s, "centimeter"_s },168 { "duration"_s, "day"_s },169 { "angle"_s, "degree"_s },170 { "temperature"_s, "fahrenheit"_s },171 { "volume"_s, "fluid-ounce"_s },172 { "length"_s, "foot"_s },173 { "volume"_s, "gallon"_s },174 { "digital"_s, "gigabit"_s },175 { "digital"_s, "gigabyte"_s },176 { "mass"_s, "gram"_s },177 { "area"_s, "hectare"_s },178 { "duration"_s, "hour"_s },179 { "length"_s, "inch"_s },180 { "digital"_s, "kilobit"_s },181 { "digital"_s, "kilobyte"_s },182 { "mass"_s, "kilogram"_s },183 { "length"_s, "kilometer"_s },184 { "volume"_s, "liter"_s },185 { "digital"_s, "megabit"_s },186 { "digital"_s, "megabyte"_s },187 { "length"_s, "meter"_s },188 { "length"_s, "mile"_s },189 { "length"_s, "mile-scandinavian"_s },190 { "volume"_s, "milliliter"_s },191 { "length"_s, "millimeter"_s },192 { "duration"_s, "millisecond"_s },193 { "duration"_s, "minute"_s },194 { "duration"_s, "month"_s },195 { "mass"_s, "ounce"_s },196 { "concentr"_s, "percent"_s },197 { "digital"_s, "petabyte"_s },198 { "mass"_s, "pound"_s },199 { "duration"_s, "second"_s },200 { "mass"_s, "stone"_s },201 { "digital"_s, "terabit"_s },202 { "digital"_s, "terabyte"_s },203 { "duration"_s, "week"_s },204 { "length"_s, "yard"_s },205 { "duration"_s, "year"_s },206 };207 156 ASSERT( 208 157 std::is_sorted(std::begin(simpleUnits), std::end(simpleUnits), -
trunk/Source/JavaScriptCore/runtime/IntlObject.cpp
r281375 r281513 59 59 #include "Options.h" 60 60 #include <unicode/ubrk.h> 61 #include <unicode/ucal.h> 61 62 #include <unicode/ucol.h> 62 63 #include <unicode/ufieldpositer.h> … … 76 77 77 78 static JSC_DECLARE_HOST_FUNCTION(intlObjectFuncGetCanonicalLocales); 79 static JSC_DECLARE_HOST_FUNCTION(intlObjectFuncSupportedValuesOf); 78 80 79 81 static JSValue createCollatorConstructor(VM& vm, JSObject* object) … … 173 175 } 174 176 177 const MeasureUnit simpleUnits[43] = { 178 { "area"_s, "acre"_s }, 179 { "digital"_s, "bit"_s }, 180 { "digital"_s, "byte"_s }, 181 { "temperature"_s, "celsius"_s }, 182 { "length"_s, "centimeter"_s }, 183 { "duration"_s, "day"_s }, 184 { "angle"_s, "degree"_s }, 185 { "temperature"_s, "fahrenheit"_s }, 186 { "volume"_s, "fluid-ounce"_s }, 187 { "length"_s, "foot"_s }, 188 { "volume"_s, "gallon"_s }, 189 { "digital"_s, "gigabit"_s }, 190 { "digital"_s, "gigabyte"_s }, 191 { "mass"_s, "gram"_s }, 192 { "area"_s, "hectare"_s }, 193 { "duration"_s, "hour"_s }, 194 { "length"_s, "inch"_s }, 195 { "digital"_s, "kilobit"_s }, 196 { "digital"_s, "kilobyte"_s }, 197 { "mass"_s, "kilogram"_s }, 198 { "length"_s, "kilometer"_s }, 199 { "volume"_s, "liter"_s }, 200 { "digital"_s, "megabit"_s }, 201 { "digital"_s, "megabyte"_s }, 202 { "length"_s, "meter"_s }, 203 { "length"_s, "mile"_s }, 204 { "length"_s, "mile-scandinavian"_s }, 205 { "volume"_s, "milliliter"_s }, 206 { "length"_s, "millimeter"_s }, 207 { "duration"_s, "millisecond"_s }, 208 { "duration"_s, "minute"_s }, 209 { "duration"_s, "month"_s }, 210 { "mass"_s, "ounce"_s }, 211 { "concentr"_s, "percent"_s }, 212 { "digital"_s, "petabyte"_s }, 213 { "mass"_s, "pound"_s }, 214 { "duration"_s, "second"_s }, 215 { "mass"_s, "stone"_s }, 216 { "digital"_s, "terabit"_s }, 217 { "digital"_s, "terabyte"_s }, 218 { "duration"_s, "week"_s }, 219 { "length"_s, "yard"_s }, 220 { "duration"_s, "year"_s }, 221 }; 222 175 223 IntlObject::IntlObject(VM& vm, Structure* structure) 176 224 : Base(vm, structure) … … 185 233 } 186 234 187 void IntlObject::finishCreation(VM& vm, JSGlobalObject* )235 void IntlObject::finishCreation(VM& vm, JSGlobalObject* globalObject) 188 236 { 189 237 Base::finishCreation(vm); … … 200 248 UNUSED_PARAM(&createListFormatConstructor); 201 249 #endif 250 if (Options::useIntlEnumeration()) 251 JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("supportedValuesOf", intlObjectFuncSupportedValuesOf, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); 202 252 } 203 253 … … 1469 1519 if (calendar == "gregorian"_s) 1470 1520 return "gregory"_s; 1471 if (calendar == "islamic-civil"_s)1472 return "islamicc"_s;1521 // islamicc is deprecated in BCP47, and islamic-civil is preferred. 1522 // https://github.com/unicode-org/cldr/blob/master/common/bcp47/calendar.xml 1473 1523 if (calendar == "ethiopic-amete-alem"_s) 1474 1524 return "ethioaa"_s; … … 1525 1575 } 1526 1576 1577 // https://tc39.es/proposal-intl-enumeration/#sec-availablecalendars 1578 static JSArray* availableCalendars(JSGlobalObject* globalObject) 1579 { 1580 VM& vm = globalObject->vm(); 1581 auto scope = DECLARE_THROW_SCOPE(vm); 1582 1583 UErrorCode status = U_ZERO_ERROR; 1584 auto enumeration = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(ucal_getKeywordValuesForLocale("calendars", "und", false, &status)); 1585 if (U_FAILURE(status)) { 1586 throwTypeError(globalObject, scope, "failed to enumerate available calendars"_s); 1587 return { }; 1588 } 1589 1590 int32_t count = uenum_count(enumeration.get(), &status); 1591 if (U_FAILURE(status)) { 1592 throwTypeError(globalObject, scope, "failed to enumerate available calendars"_s); 1593 return { }; 1594 } 1595 1596 Vector<String, 1> elements; 1597 elements.reserveInitialCapacity(count); 1598 for (int32_t index = 0; index < count; ++index) { 1599 int32_t length = 0; 1600 const char* pointer = uenum_next(enumeration.get(), &length, &status); 1601 if (U_FAILURE(status)) { 1602 throwTypeError(globalObject, scope, "failed to enumerate available calendars"_s); 1603 return { }; 1604 } 1605 String calendar(pointer, length); 1606 if (auto mapped = mapICUCalendarKeywordToBCP47(calendar)) 1607 elements.append(WTFMove(mapped.value())); 1608 else 1609 elements.append(WTFMove(calendar)); 1610 } 1611 1612 // The AvailableCalendars abstract operation returns a List, ordered as if an Array of the same 1613 // values had been sorted using %Array.prototype.sort% using undefined as comparefn 1614 std::sort(elements.begin(), elements.end(), 1615 [](const String& a, const String& b) { 1616 return WTF::codePointCompare(a, b) < 0; 1617 }); 1618 1619 return createArrayFromStringVector(globalObject, WTFMove(elements)); 1620 } 1621 1622 // https://tc39.es/proposal-intl-enumeration/#sec-availablecollations 1623 static JSArray* availableCollations(JSGlobalObject* globalObject) 1624 { 1625 VM& vm = globalObject->vm(); 1626 auto scope = DECLARE_THROW_SCOPE(vm); 1627 1628 UErrorCode status = U_ZERO_ERROR; 1629 auto enumeration = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(ucol_getKeywordValues("collation", &status)); 1630 if (U_FAILURE(status)) { 1631 throwTypeError(globalObject, scope, "failed to enumerate available collations"_s); 1632 return { }; 1633 } 1634 1635 int32_t count = uenum_count(enumeration.get(), &status); 1636 if (U_FAILURE(status)) { 1637 throwTypeError(globalObject, scope, "failed to enumerate available collations"_s); 1638 return { }; 1639 } 1640 1641 Vector<String, 1> elements; 1642 elements.reserveInitialCapacity(count); 1643 for (int32_t index = 0; index < count; ++index) { 1644 int32_t length = 0; 1645 const char* pointer = uenum_next(enumeration.get(), &length, &status); 1646 if (U_FAILURE(status)) { 1647 throwTypeError(globalObject, scope, "failed to enumerate available collations"_s); 1648 return { }; 1649 } 1650 String collation(pointer, length); 1651 if (collation == "standard"_s || collation == "search"_s) 1652 continue; 1653 if (auto mapped = mapICUCollationKeywordToBCP47(collation)) 1654 elements.append(WTFMove(mapped.value())); 1655 else 1656 elements.append(WTFMove(collation)); 1657 } 1658 1659 // The AvailableCollations abstract operation returns a List, ordered as if an Array of the same 1660 // values had been sorted using %Array.prototype.sort% using undefined as comparefn 1661 std::sort(elements.begin(), elements.end(), 1662 [](const String& a, const String& b) { 1663 return WTF::codePointCompare(a, b) < 0; 1664 }); 1665 1666 return createArrayFromStringVector(globalObject, WTFMove(elements)); 1667 } 1668 1669 // https://tc39.es/proposal-intl-enumeration/#sec-availablecurrencies 1670 static JSArray* availableCurrencies(JSGlobalObject* globalObject) 1671 { 1672 VM& vm = globalObject->vm(); 1673 auto scope = DECLARE_THROW_SCOPE(vm); 1674 1675 UErrorCode status = U_ZERO_ERROR; 1676 auto enumeration = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(ucurr_openISOCurrencies(UCURR_COMMON | UCURR_NON_DEPRECATED, &status)); 1677 if (U_FAILURE(status)) { 1678 throwTypeError(globalObject, scope, "failed to enumerate available currencies"_s); 1679 return { }; 1680 } 1681 1682 int32_t count = uenum_count(enumeration.get(), &status); 1683 if (U_FAILURE(status)) { 1684 throwTypeError(globalObject, scope, "failed to enumerate available currencies"_s); 1685 return { }; 1686 } 1687 1688 Vector<String, 1> elements; 1689 elements.reserveInitialCapacity(count); 1690 for (int32_t index = 0; index < count; ++index) { 1691 int32_t length = 0; 1692 const char* currency = uenum_next(enumeration.get(), &length, &status); 1693 if (U_FAILURE(status)) { 1694 throwTypeError(globalObject, scope, "failed to enumerate available currencies"_s); 1695 return { }; 1696 } 1697 elements.constructAndAppend(currency, length); 1698 } 1699 1700 // The AvailableCurrencies abstract operation returns a List, ordered as if an Array of the same 1701 // values had been sorted using %Array.prototype.sort% using undefined as comparefn 1702 std::sort(elements.begin(), elements.end(), 1703 [](const String& a, const String& b) { 1704 return WTF::codePointCompare(a, b) < 0; 1705 }); 1706 1707 return createArrayFromStringVector(globalObject, WTFMove(elements)); 1708 } 1709 1710 // https://tc39.es/proposal-intl-enumeration/#sec-availablenumberingsystems 1711 static JSArray* availableNumberingSystems(JSGlobalObject* globalObject) 1712 { 1713 VM& vm = globalObject->vm(); 1714 auto scope = DECLARE_THROW_SCOPE(vm); 1715 1716 UErrorCode status = U_ZERO_ERROR; 1717 auto enumeration = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(unumsys_openAvailableNames(&status)); 1718 if (U_FAILURE(status)) { 1719 throwTypeError(globalObject, scope, "failed to enumerate available numbering systems"_s); 1720 return { }; 1721 } 1722 1723 int32_t count = uenum_count(enumeration.get(), &status); 1724 if (U_FAILURE(status)) { 1725 throwTypeError(globalObject, scope, "failed to enumerate available numbering systems"_s); 1726 return { }; 1727 } 1728 1729 Vector<String, 1> elements; 1730 elements.reserveInitialCapacity(count); 1731 for (int32_t index = 0; index < count; ++index) { 1732 int32_t length = 0; 1733 const char* numberingSystem = uenum_next(enumeration.get(), &length, &status); 1734 if (U_FAILURE(status)) { 1735 throwTypeError(globalObject, scope, "failed to enumerate available numbering systems"_s); 1736 return { }; 1737 } 1738 elements.constructAndAppend(numberingSystem, length); 1739 } 1740 1741 // The AvailableNumberingSystems abstract operation returns a List, ordered as if an Array of the same 1742 // values had been sorted using %Array.prototype.sort% using undefined as comparefn 1743 std::sort(elements.begin(), elements.end(), 1744 [](const String& a, const String& b) { 1745 return WTF::codePointCompare(a, b) < 0; 1746 }); 1747 1748 return createArrayFromStringVector(globalObject, WTFMove(elements)); 1749 } 1750 1751 // https://tc39.es/proposal-intl-enumeration/#sec-canonicalizetimezonename 1752 static std::optional<String> canonicalizeTimeZoneNameFromICUTimeZone(const String& timeZoneName) 1753 { 1754 // Some time zone names are included in ICU, but they are not included in the IANA Time Zone Database. 1755 // We need to filter them out. 1756 if (timeZoneName.startsWith("SystemV/")) 1757 return std::nullopt; 1758 if (timeZoneName.startsWith("Etc/")) 1759 return std::nullopt; 1760 // IANA time zone names include '/'. Some of them are not including, but it is in backward links. 1761 // And ICU already resolved these backward links. 1762 if (!timeZoneName.contains('/')) 1763 return std::nullopt; 1764 1765 return timeZoneName; 1766 } 1767 1768 // https://tc39.es/proposal-intl-enumeration/#sec-availabletimezones 1769 static JSArray* availableTimeZones(JSGlobalObject* globalObject) 1770 { 1771 VM& vm = globalObject->vm(); 1772 auto scope = DECLARE_THROW_SCOPE(vm); 1773 1774 UErrorCode status = U_ZERO_ERROR; 1775 auto enumeration = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, nullptr, nullptr, &status)); 1776 if (U_FAILURE(status)) { 1777 throwTypeError(globalObject, scope, "failed to enumerate available timezones"_s); 1778 return { }; 1779 } 1780 1781 int32_t count = uenum_count(enumeration.get(), &status); 1782 if (U_FAILURE(status)) { 1783 throwTypeError(globalObject, scope, "failed to enumerate available timezones"_s); 1784 return { }; 1785 } 1786 1787 Vector<String, 1> elements; 1788 elements.reserveInitialCapacity(count); 1789 for (int32_t index = 0; index < count; ++index) { 1790 int32_t length = 0; 1791 const char* pointer = uenum_next(enumeration.get(), &length, &status); 1792 if (U_FAILURE(status)) { 1793 throwTypeError(globalObject, scope, "failed to enumerate available timezones"_s); 1794 return { }; 1795 } 1796 String timeZone(pointer, length); 1797 if (auto mapped = canonicalizeTimeZoneNameFromICUTimeZone(timeZone)) 1798 elements.append(WTFMove(mapped.value())); 1799 } 1800 1801 // 4. Sort result in order as if an Array of the same values had been sorted using %Array.prototype.sort% using undefined as comparefn. 1802 std::sort(elements.begin(), elements.end(), 1803 [](const String& a, const String& b) { 1804 return WTF::codePointCompare(a, b) < 0; 1805 }); 1806 1807 return createArrayFromStringVector(globalObject, WTFMove(elements)); 1808 } 1809 1810 // https://tc39.es/proposal-intl-enumeration/#sec-availableunits 1811 static JSArray* availableUnits(JSGlobalObject* globalObject) 1812 { 1813 VM& vm = globalObject->vm(); 1814 auto scope = DECLARE_THROW_SCOPE(vm); 1815 1816 JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), std::size(simpleUnits)); 1817 if (!result) { 1818 throwOutOfMemoryError(globalObject, scope); 1819 return { }; 1820 } 1821 1822 ASSERT( 1823 std::is_sorted(std::begin(simpleUnits), std::end(simpleUnits), 1824 [](const MeasureUnit& a, const MeasureUnit& b) { 1825 return WTF::codePointCompare(StringView(a.subType), StringView(b.subType)) < 0; 1826 })); 1827 1828 int32_t index = 0; 1829 for (const MeasureUnit& unit : simpleUnits) { 1830 result->putDirectIndex(globalObject, index++, jsString(vm, StringImpl::createFromLiteral(unit.subType))); 1831 RETURN_IF_EXCEPTION(scope, { }); 1832 } 1833 return result; 1834 } 1835 1836 // https://tc39.es/proposal-intl-enumeration/#sec-intl.supportedvaluesof 1837 JSC_DEFINE_HOST_FUNCTION(intlObjectFuncSupportedValuesOf, (JSGlobalObject* globalObject, CallFrame* callFrame)) 1838 { 1839 VM& vm = globalObject->vm(); 1840 auto scope = DECLARE_THROW_SCOPE(vm); 1841 1842 String key = callFrame->argument(0).toWTFString(globalObject); 1843 RETURN_IF_EXCEPTION(scope, { }); 1844 1845 if (key == "calendar"_s) 1846 RELEASE_AND_RETURN(scope, JSValue::encode(availableCalendars(globalObject))); 1847 1848 if (key == "collation"_s) 1849 RELEASE_AND_RETURN(scope, JSValue::encode(availableCollations(globalObject))); 1850 1851 if (key == "currency"_s) 1852 RELEASE_AND_RETURN(scope, JSValue::encode(availableCurrencies(globalObject))); 1853 1854 if (key == "numberingSystem"_s) 1855 RELEASE_AND_RETURN(scope, JSValue::encode(availableNumberingSystems(globalObject))); 1856 1857 if (key == "timeZone"_s) 1858 RELEASE_AND_RETURN(scope, JSValue::encode(availableTimeZones(globalObject))); 1859 1860 if (key == "unit"_s) 1861 RELEASE_AND_RETURN(scope, JSValue::encode(availableUnits(globalObject))); 1862 1863 throwRangeError(globalObject, scope, "Unknown key for Intl.supportedValuesOf"_s); 1864 return { }; 1865 } 1866 1867 JSArray* createArrayFromStringVector(JSGlobalObject* globalObject, Vector<String, 1>&& elements) 1868 { 1869 VM& vm = globalObject->vm(); 1870 auto scope = DECLARE_THROW_SCOPE(vm); 1871 1872 JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), elements.size()); 1873 if (!result) { 1874 throwOutOfMemoryError(globalObject, scope); 1875 return nullptr; 1876 } 1877 for (unsigned index = 0; index < elements.size(); ++index) { 1878 result->putDirectIndex(globalObject, index, jsString(vm, WTFMove(elements[index]))); 1879 RETURN_IF_EXCEPTION(scope, { }); 1880 } 1881 return result; 1882 } 1883 1527 1884 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/IntlObject.h
r281375 r281513 60 60 static constexpr uint8_t numberOfRelevantExtensionKeys = 0 JSC_INTL_RELEVANT_EXTENSION_KEYS(JSC_COUNT_INTL_RELEVANT_EXTENSION_KEYS); 61 61 #undef JSC_COUNT_INTL_RELEVANT_EXTENSION_KEYS 62 63 struct MeasureUnit { 64 ASCIILiteral type; 65 ASCIILiteral subType; 66 }; 67 68 extern JS_EXPORT_PRIVATE const MeasureUnit simpleUnits[43]; 62 69 63 70 class IntlObject final : public JSNonFinalObject { … … 142 149 std::optional<String> mapBCP47ToICUCalendarKeyword(const String&); 143 150 151 JSArray* createArrayFromStringVector(JSGlobalObject*, Vector<String, 1>&&); 152 144 153 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/OptionsList.h
r281438 r281513 542 542 v(Bool, useTemporal, false, Normal, "Expose the Temporal object.") \ 543 543 v(Bool, useArrayFindLastMethod, true, Normal, "Expose the findLast() and findLastIndex() methods on Array and %TypedArray%.") \ 544 v(Bool, useIntlEnumeration, true, Normal, "Expose the Intl enumeration APIs.") \ 544 545 545 546 -
trunk/Source/WTF/ChangeLog
r281490 r281513 1 2021-08-24 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Add Intl Enumeration APIs 4 https://bugs.webkit.org/show_bug.cgi?id=214795 5 6 Reviewed by Ross Kirsling. 7 8 * wtf/text/StringImpl.cpp: 9 (WTF::StringImpl::createFromLiteral): 10 * wtf/text/StringImpl.h: 11 1 12 2021-08-24 Tim Nguyen <ntim@apple.com> 2 13 -
trunk/Source/WTF/wtf/text/StringImpl.cpp
r277355 r281513 162 162 { 163 163 return createFromLiteral(characters, strlen(characters)); 164 } 165 166 Ref<StringImpl> StringImpl::createFromLiteral(ASCIILiteral literal) 167 { 168 return createFromLiteral(literal.characters(), literal.length()); 164 169 } 165 170 -
trunk/Source/WTF/wtf/text/StringImpl.h
r281091 r281513 34 34 #include <wtf/Vector.h> 35 35 #include <wtf/text/ASCIIFastPath.h> 36 #include <wtf/text/ASCIILiteral.h> 36 37 #include <wtf/text/ConversionMode.h> 37 38 #include <wtf/text/StringBuffer.h> … … 250 251 WTF_EXPORT_PRIVATE static Ref<StringImpl> createFromLiteral(const char*, unsigned length); 251 252 WTF_EXPORT_PRIVATE static Ref<StringImpl> createFromLiteral(const char*); 253 WTF_EXPORT_PRIVATE static Ref<StringImpl> createFromLiteral(ASCIILiteral); 252 254 253 255 WTF_EXPORT_PRIVATE static Ref<StringImpl> createWithoutCopying(const UChar*, unsigned length);
Note: See TracChangeset
for help on using the changeset viewer.