Diff
Modified: trunk/JSTests/ChangeLog (264638 => 264639)
--- trunk/JSTests/ChangeLog 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/JSTests/ChangeLog 2020-07-21 00:04:06 UTC (rev 264639)
@@ -1,3 +1,20 @@
+2020-07-20 Yusuke Suzuki <[email protected]>
+
+ [ECMA-402] Implement Intl.DisplayNames
+ https://bugs.webkit.org/show_bug.cgi?id=209779
+
+ Reviewed by Ross Kirsling.
+
+ * stress/intl-displaynames.js: Added.
+ (shouldBe):
+ (shouldThrow):
+ (vm.icuVersion):
+ * stress/intl-parse-unicode-subtags.js: Added.
+ (shouldBe):
+ (shouldThrow):
+ (vm.icuVersion):
+ * test262/config.yaml:
+
2020-07-20 Ross Kirsling <[email protected]>
[JSC] eval?.() should be indirect eval
Added: trunk/JSTests/stress/intl-displaynames.js (0 => 264639)
--- trunk/JSTests/stress/intl-displaynames.js (rev 0)
+++ trunk/JSTests/stress/intl-displaynames.js 2020-07-21 00:04:06 UTC (rev 264639)
@@ -0,0 +1,201 @@
+//@ runDefault("--useIntlDisplayNames=1")
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+function shouldThrow(func, errorMessage) {
+ var errorThrown = false;
+ var error = null;
+ try {
+ func();
+ } catch (e) {
+ errorThrown = true;
+ error = e;
+ }
+ if (!errorThrown)
+ throw new Error('not thrown');
+ if (String(error) !== errorMessage)
+ throw new Error(`bad error: ${String(error)}`);
+}
+
+if ($vm.icuVersion() >= 61) {
+ shouldBe(Intl.DisplayNames.length, 2);
+ shouldThrow(() => new Intl.DisplayNames, `TypeError: undefined is not an object (evaluating 'new Intl.DisplayNames')`);
+
+ // Get display names of region in English
+ var regionNames = new Intl.DisplayNames(['en'], {type: 'region'});
+ if ($vm.icuVersion() >= 64)
+ shouldBe(regionNames.of('419'), "Latin America");
+ shouldBe(regionNames.of('BZ'), "Belize");
+ shouldBe(regionNames.of('US'), "United States");
+ shouldBe(regionNames.of('BA'), "Bosnia & Herzegovina");
+ shouldBe(regionNames.of('MM'), "Myanmar (Burma)");
+
+ // Get display names of region in Traditional Chinese
+ regionNames = new Intl.DisplayNames(['zh-Hant'], {type: 'region'});
+ if ($vm.icuVersion() >= 64)
+ shouldBe(regionNames.of('419'), "拉丁美洲");
+ shouldBe(regionNames.of('BZ'), "貝里斯");
+ shouldBe(regionNames.of('US'), "美國");
+ shouldBe(regionNames.of('BA'), "波士尼亞與赫塞哥維納");
+ shouldBe(regionNames.of('MM'), "緬甸");
+
+ regionNames = new Intl.DisplayNames(['en'], {type: 'region', style: 'short'});
+ if ($vm.icuVersion() >= 64)
+ shouldBe(regionNames.of('419'), "Latin America");
+ shouldBe(regionNames.of('BZ'), "Belize");
+ shouldBe(regionNames.of('US'), "US");
+ shouldBe(regionNames.of('BA'), "Bosnia");
+ shouldBe(regionNames.of('MM'), "Myanmar");
+
+ regionNames = new Intl.DisplayNames(['en'], {type: 'region', style: 'narrow'});
+ if ($vm.icuVersion() >= 64)
+ shouldBe(regionNames.of('419'), "Latin America");
+ shouldBe(regionNames.of('BZ'), "Belize");
+ shouldBe(regionNames.of('US'), "US");
+ shouldBe(regionNames.of('BA'), "Bosnia");
+ shouldBe(regionNames.of('MM'), "Myanmar");
+
+ // Get display names of language in English
+ var languageNames = new Intl.DisplayNames(['en'], {type: 'language'});
+ shouldBe(languageNames.of('fr'), "French");
+ shouldBe(languageNames.of('de'), "German");
+ shouldBe(languageNames.of('fr-CA'), "Canadian French");
+ if ($vm.icuVersion() >= 64 && $vm.icuVersion() <= 66)
+ shouldBe(languageNames.of('zh-Hant'), "Chinese, Traditional");
+ else
+ shouldBe(languageNames.of('zh-Hant'), "Traditional Chinese");
+ shouldBe(languageNames.of('en-US'), "American English");
+ shouldBe(languageNames.of('zh-TW'), "Chinese (Taiwan)");
+
+ // Get display names of language in Traditional Chinese
+ languageNames = new Intl.DisplayNames(['zh-Hant'], {type: 'language'});
+ shouldBe(languageNames.of('fr'), "法文");
+ shouldBe(languageNames.of('zh'), "中文");
+ shouldBe(languageNames.of('de'), "德文");
+
+ languageNames = new Intl.DisplayNames(['en'], {type: 'language', style: 'short'});
+ shouldBe(languageNames.of('fr'), "French");
+ shouldBe(languageNames.of('de'), "German");
+ shouldBe(languageNames.of('fr-CA'), "Canadian French");
+ if ($vm.icuVersion() >= 64 && $vm.icuVersion() <= 66)
+ shouldBe(languageNames.of('zh-Hant'), "Chinese, Traditional");
+ else
+ shouldBe(languageNames.of('zh-Hant'), "Traditional Chinese");
+ shouldBe(languageNames.of('en-US'), "US English");
+ shouldBe(languageNames.of('zh-TW'), "Chinese (Taiwan)");
+
+ languageNames = new Intl.DisplayNames(['en'], {type: 'language', style: 'narrow'});
+ shouldBe(languageNames.of('fr'), "French");
+ shouldBe(languageNames.of('de'), "German");
+ shouldBe(languageNames.of('fr-CA'), "Canadian French");
+ if ($vm.icuVersion() >= 64 && $vm.icuVersion() <= 66)
+ shouldBe(languageNames.of('zh-Hant'), "Chinese, Traditional");
+ else
+ shouldBe(languageNames.of('zh-Hant'), "Traditional Chinese");
+ shouldBe(languageNames.of('en-US'), "US English");
+ shouldBe(languageNames.of('zh-TW'), "Chinese (Taiwan)");
+
+ // Get display names of script in English
+ var scriptNames = new Intl.DisplayNames(['en'], {type: 'script'});
+ // Get script names
+ shouldBe(scriptNames.of('Latn'), "Latin");
+ shouldBe(scriptNames.of('Arab'), "Arabic");
+ shouldBe(scriptNames.of('Kana'), "Katakana");
+
+ // Get display names of script in Traditional Chinese
+ scriptNames = new Intl.DisplayNames(['zh-Hant'], {type: 'script'});
+ shouldBe(scriptNames.of('Latn'), "拉丁文");
+ shouldBe(scriptNames.of('Arab'), "阿拉伯文");
+ shouldBe(scriptNames.of('Kana'), "片假名");
+
+ scriptNames = new Intl.DisplayNames(['en'], {type: 'script', style: 'short'});
+ shouldBe(scriptNames.of('Latn'), "Latin");
+ shouldBe(scriptNames.of('Arab'), "Arabic");
+ shouldBe(scriptNames.of('Kana'), "Katakana");
+
+ scriptNames = new Intl.DisplayNames(['en'], {type: 'script', style: 'narrow'});
+ shouldBe(scriptNames.of('Latn'), "Latin");
+ shouldBe(scriptNames.of('Arab'), "Arabic");
+ shouldBe(scriptNames.of('Kana'), "Katakana");
+
+ // Get display names of currency code in English
+ var currencyNames = new Intl.DisplayNames(['en'], {type: 'currency'});
+ // Get currency names
+ shouldBe(currencyNames.of('USD'), "US Dollar");
+ shouldBe(currencyNames.of('EUR'), "Euro");
+ shouldBe(currencyNames.of('TWD'), "New Taiwan Dollar");
+ shouldBe(currencyNames.of('CNY'), "Chinese Yuan");
+ shouldBe(currencyNames.of('JPY'), "Japanese Yen");
+
+ // Get display names of currency code in Traditional Chinese
+ currencyNames = new Intl.DisplayNames(['zh-Hant'], {type: 'currency'});
+ shouldBe(currencyNames.of('USD'), "美元");
+ shouldBe(currencyNames.of('EUR'), "歐元");
+ shouldBe(currencyNames.of('TWD'), "新台幣");
+ shouldBe(currencyNames.of('CNY'), "人民幣");
+ shouldBe(currencyNames.of('JPY'), "日圓");
+
+ // Get display names of currency code in English in short
+ currencyNames = new Intl.DisplayNames(['en'], {type: 'currency', style: 'short' });
+ shouldBe(currencyNames.of('USD'), "$");
+ shouldBe(currencyNames.of('EUR'), "€");
+ shouldBe(currencyNames.of('TWD'), "NT$");
+ shouldBe(currencyNames.of('CNY'), "CN¥");
+ shouldBe(currencyNames.of('JPY'), "¥");
+
+ // Get display names of currency code in English in narrow
+ currencyNames = new Intl.DisplayNames(['en'], {type: 'currency', style: 'narrow' });
+ shouldBe(currencyNames.of('USD'), "$");
+ shouldBe(currencyNames.of('EUR'), "€");
+ shouldBe(currencyNames.of('TWD'), "$");
+ shouldBe(currencyNames.of('CNY'), "¥");
+ shouldBe(currencyNames.of('JPY'), "¥");
+ shouldBe(currencyNames.of('JPZ'), "JPZ"); // Fallback code
+ shouldBe(JSON.stringify(currencyNames.resolvedOptions()), `{"locale":"en","style":"narrow","type":"currency","fallback":"code"}`);
+
+ currencyNames = new Intl.DisplayNames(['en'], {type: 'currency', style: 'narrow', fallback: 'none' });
+ shouldBe(currencyNames.of('JPZ'), undefined); // Fallback none
+ shouldBe(JSON.stringify(currencyNames.resolvedOptions()), `{"locale":"en","style":"narrow","type":"currency","fallback":"none"}`);
+
+ regionNames = new Intl.DisplayNames(['en'], {type: 'region'});
+ shouldBe(regionNames.of('999'), "999");
+ shouldBe(JSON.stringify(regionNames.resolvedOptions()), `{"locale":"en","style":"long","type":"region","fallback":"code"}`);
+
+ regionNames = new Intl.DisplayNames(['en'], {type: 'region', fallback:'none'});
+ if ($vm.icuVersion() > 64)
+ shouldBe(regionNames.of('999'), undefined);
+ shouldBe(JSON.stringify(regionNames.resolvedOptions()), `{"locale":"en","style":"long","type":"region","fallback":"none"}`);
+
+ languageNames = new Intl.DisplayNames(['en'], {type: 'language'});
+ if ($vm.icuVersion() > 64) {
+ shouldBe(languageNames.of('en-AA'), "en-AA");
+ var object = {
+ toString() {
+ return 'en-AA';
+ }
+ };
+ shouldBe(languageNames.of(object), object);
+ }
+
+ languageNames = new Intl.DisplayNames(['en'], {type: 'language', fallback: 'none'});
+ if ($vm.icuVersion() > 64) {
+ shouldBe(languageNames.of('en-AA'), undefined);
+ shouldBe(languageNames.of(object), undefined);
+ }
+
+ shouldBe(Intl.DisplayNames.prototype[Symbol.toStringTag], `Intl.DisplayNames`);
+ shouldBe(JSON.stringify(Intl.DisplayNames.supportedLocalesOf("en")), `["en"]`);
+ shouldBe(JSON.stringify(Intl.DisplayNames.supportedLocalesOf("ja-JP")), `["ja-JP"]`);
+ shouldBe(JSON.stringify(Intl.DisplayNames.supportedLocalesOf({ length: 4, 1: 'en', 0: 'es', 3: 'de' })), '["es","en","de"]');
+ shouldThrow(() => Intl.DisplayNames.supportedLocalesOf(""), `RangeError: invalid language tag: `)
+
+ shouldThrow(() => {
+ Intl.DisplayNames.prototype.of.call({});
+ }, `TypeError: Intl.DisplayNames.prototype.of called on value that's not an object initialized as a DisplayNames`);
+
+ shouldThrow(() => {
+ Intl.DisplayNames.prototype.resolvedOptions.call({});
+ }, `TypeError: Intl.DisplayNames.prototype.resolvedOptions called on value that's not an object initialized as a DisplayNames`);
+}
Added: trunk/JSTests/stress/intl-parse-unicode-subtags.js (0 => 264639)
--- trunk/JSTests/stress/intl-parse-unicode-subtags.js (rev 0)
+++ trunk/JSTests/stress/intl-parse-unicode-subtags.js 2020-07-21 00:04:06 UTC (rev 264639)
@@ -0,0 +1,92 @@
+//@ runDefault("--useIntlDisplayNames=1")
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+function shouldThrow(func, errorMessage) {
+ var errorThrown = false;
+ var error = null;
+ try {
+ func();
+ } catch (e) {
+ errorThrown = true;
+ error = e;
+ }
+ if (!errorThrown)
+ throw new Error('not thrown');
+ if (String(error) !== errorMessage)
+ throw new Error(`bad error: ${String(error)}`);
+}
+
+if ($vm.icuVersion() >= 61) {
+ var regionNames = new Intl.DisplayNames(['en'], {type: 'region'});
+ shouldThrow(() => regionNames.of(""), `RangeError: argument is not a region subtag`);
+ shouldThrow(() => regionNames.of("-"), `RangeError: argument is not a region subtag`);
+ shouldThrow(() => regionNames.of("0"), `RangeError: argument is not a region subtag`);
+ shouldThrow(() => regionNames.of("00"), `RangeError: argument is not a region subtag`);
+ shouldThrow(() => regionNames.of("0000"), `RangeError: argument is not a region subtag`);
+ shouldThrow(() => regionNames.of("a"), `RangeError: argument is not a region subtag`);
+ shouldThrow(() => regionNames.of("aaa"), `RangeError: argument is not a region subtag`);
+ if ($vm.icuVersion() >= 64)
+ shouldBe(regionNames.of("419"), `Latin America`);
+ shouldBe(regionNames.of("JP"), `Japan`);
+ shouldBe(regionNames.of("US"), `United States`);
+
+ var languageNames = new Intl.DisplayNames(['en'], {type: 'language'});
+ shouldThrow(() => languageNames.of(""), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("-"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("--"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("en-"), `RangeError: argument is not a language id`);
+ shouldBe(languageNames.of("en-US"), `American English`);
+ shouldThrow(() => languageNames.of("en_US"), `RangeError: argument is not a language id`);
+ shouldBe(languageNames.of("en-us"), `American English`);
+ shouldThrow(() => languageNames.of("root"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("root-US"), `RangeError: argument is not a language id`);
+ if ($vm.icuVersion() >= 64)
+ shouldBe(languageNames.of("es-419"), `Latin American Spanish`);
+ if ($vm.icuVersion() >= 64 && $vm.icuVersion() <= 66) {
+ shouldBe(languageNames.of('zh-Hant'), `Chinese, Traditional`);
+ shouldBe(languageNames.of('zh-Hans-HK'), `Chinese, Simplified (Hong Kong)`);
+ } else {
+ shouldBe(languageNames.of('zh-Hant'), `Traditional Chinese`);
+ shouldBe(languageNames.of('zh-Hans-HK'), `Simplified Chinese (Hong Kong)`);
+ }
+ shouldThrow(() => languageNames.of("Hant"), `RangeError: argument is not a language id`); // Script only
+ shouldBe(languageNames.of('sr-Latn'), `Serbian (Latin)`); // Language-Script
+ shouldBe(languageNames.of('sr-Cyrl'), `Serbian (Cyrillic)`); // Language-Script
+ shouldThrow(() => languageNames.of("zh-HK-Hans"), `RangeError: argument is not a language id`);
+ shouldBe(languageNames.of('sl-rozaj'), `Slovenian (Resian)`); // Language-Variant
+ shouldThrow(() => languageNames.of("sl_rozaj"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("sl-rozaj-Cyrl"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("sl-rozaj-"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("sl-_rozaj"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("sl-Cyrl-"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("-sl-Cyrl-"), `RangeError: argument is not a language id`);
+ shouldBe(languageNames.of('hy-Latn-IT-arevela'), `Armenian (Latin, Italy, Eastern Armenian)`); // Language-Script-Region-Variant
+ shouldBe(languageNames.of('hy-Latn-IT'), `Armenian (Latin, Italy)`); // Language-Script-Region
+ shouldBe(languageNames.of('hy-Latn-arevela'), `Armenian (Latin, Eastern Armenian)`); // Language-Script-Variant
+ shouldThrow(() => languageNames.of("hy-Latn-ITZ-arevela"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("hy-Latn-00-arevela"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("hy-Latn-arevelazzzzzzzzzzz"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("hy-Latn-arevelazzzzzzzzzzz"), `RangeError: argument is not a language id`);
+ shouldThrow(() => languageNames.of("hyzzzzzzzzz-Latn-arevela"), `RangeError: argument is not a language id`);
+
+ var scriptNames = new Intl.DisplayNames(['en'], {type: 'script'});
+ shouldThrow(() => scriptNames.of(""), `RangeError: argument is not a script subtag`);
+ shouldThrow(() => scriptNames.of("-"), `RangeError: argument is not a script subtag`);
+ shouldThrow(() => scriptNames.of("Latn0"), `RangeError: argument is not a script subtag`);
+ shouldThrow(() => scriptNames.of("Lan0"), `RangeError: argument is not a script subtag`);
+ shouldThrow(() => scriptNames.of("Lan"), `RangeError: argument is not a script subtag`);
+ shouldBe(scriptNames.of("Latn"), `Latin`);
+ shouldBe(scriptNames.of("latn"), `Latin`); // Canonicalization can make it work.
+
+ var currencyNames = new Intl.DisplayNames(['en'], {type: 'currency'});
+ shouldThrow(() => currencyNames.of(""), `RangeError: argument is not a well-formed currency code`);
+ shouldThrow(() => currencyNames.of("-"), `RangeError: argument is not a well-formed currency code`);
+ shouldThrow(() => currencyNames.of("ab"), `RangeError: argument is not a well-formed currency code`);
+ shouldThrow(() => currencyNames.of("jpyx"), `RangeError: argument is not a well-formed currency code`);
+ shouldThrow(() => currencyNames.of("jp0"), `RangeError: argument is not a well-formed currency code`);
+ shouldBe(currencyNames.of("jpy"), `Japanese Yen`);
+ shouldBe(currencyNames.of("JPY"), `Japanese Yen`);
+}
Modified: trunk/JSTests/test262/config.yaml (264638 => 264639)
--- trunk/JSTests/test262/config.yaml 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/JSTests/test262/config.yaml 2020-07-21 00:04:06 UTC (rev 264639)
@@ -6,6 +6,7 @@
FinalizationRegistry: useWeakRefs
class-fields-public: usePublicClassFields
class-fields-private: usePrivateClassFields
+ Intl.DisplayNames: useIntlDisplayNames
skip:
features:
- SharedArrayBuffer
@@ -26,7 +27,6 @@
- Intl.DateTimeFormat-dayPeriod
- Intl.DateTimeFormat-formatRange
- Intl.DateTimeFormat-fractionalSecondDigits
- - Intl.DisplayNames
- Intl.ListFormat
- Intl.NumberFormat-unified
- Intl.Segmenter
Modified: trunk/JSTests/test262/expectations.yaml (264638 => 264639)
--- trunk/JSTests/test262/expectations.yaml 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/JSTests/test262/expectations.yaml 2020-07-21 00:04:06 UTC (rev 264639)
@@ -1575,6 +1575,9 @@
test/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-default.js:
default: 'Test262Error: Expected SameValue(«h24», «h23») to be true'
strict mode: 'Test262Error: Expected SameValue(«h24», «h23») to be true'
+test/intl402/DisplayNames/length.js:
+ default: 'Test262Error: descriptor value should be 0'
+ strict mode: 'Test262Error: descriptor value should be 0'
test/intl402/Intl/getCanonicalLocales/canonicalized-tags.js:
default: 'Test262Error: Expected SameValue(«cmn», «zh») to be true'
strict mode: 'Test262Error: Expected SameValue(«cmn», «zh») to be true'
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (264638 => 264639)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2020-07-21 00:04:06 UTC (rev 264639)
@@ -70,6 +70,8 @@
runtime/IntlCollatorPrototype.cpp
runtime/IntlDateTimeFormatConstructor.cpp
runtime/IntlDateTimeFormatPrototype.cpp
+ runtime/IntlDisplayNamesConstructor.cpp
+ runtime/IntlDisplayNamesPrototype.cpp
runtime/IntlLocalePrototype.cpp
runtime/IntlNumberFormatConstructor.cpp
runtime/IntlNumberFormatPrototype.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (264638 => 264639)
--- trunk/Source/_javascript_Core/ChangeLog 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-07-21 00:04:06 UTC (rev 264639)
@@ -1,3 +1,84 @@
+2020-07-20 Yusuke Suzuki <[email protected]>
+
+ [ECMA-402] Implement Intl.DisplayNames
+ https://bugs.webkit.org/show_bug.cgi?id=209779
+
+ Reviewed by Ross Kirsling.
+
+ This patch implements Intl.DisplayNames behind useIntlDisplayNames=1 flag.
+ Intl.DisplayNames can offer readable "display-name" for ICU language, script, region, currency codes.
+ For example, it can offer "United States" string for "US" region code.
+ We use ICU ULocaleDisplayNames to implement it, except for currency since ULocaleDisplayNames is not supporting
+ currency correctly: it ignores "long", "short", and "narrow" style configurations. We need to call ucurr_getName
+ directly.
+
+ This patch appropriately adds unicode-language-id parsing in IntlLocale.cpp so that we can validate language id
+ when it is passed to `Intl.DisplayNames#of` as defined in the spec.
+
+ * CMakeLists.txt:
+ * DerivedSources-input.xcfilelist:
+ * DerivedSources-output.xcfilelist:
+ * DerivedSources.make:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * Sources.txt:
+ * runtime/CommonIdentifiers.h:
+ * runtime/IntlDisplayNames.cpp: Added.
+ (JSC::IntlDisplayNames::create):
+ (JSC::IntlDisplayNames::createStructure):
+ (JSC::IntlDisplayNames::IntlDisplayNames):
+ (JSC::IntlDisplayNames::finishCreation):
+ (JSC::IntlDisplayNames::initializeDisplayNames):
+ (JSC::IntlDisplayNames::of const):
+ (JSC::IntlDisplayNames::resolvedOptions const):
+ (JSC::IntlDisplayNames::styleString):
+ (JSC::IntlDisplayNames::typeString):
+ (JSC::IntlDisplayNames::fallbackString):
+ * runtime/IntlDisplayNames.h: Copied from Source/_javascript_Core/runtime/IntlRelativeTimeFormat.h.
+ * runtime/IntlDisplayNamesConstructor.cpp: Added.
+ (JSC::IntlDisplayNamesConstructor::create):
+ (JSC::IntlDisplayNamesConstructor::createStructure):
+ (JSC::IntlDisplayNamesConstructor::IntlDisplayNamesConstructor):
+ (JSC::IntlDisplayNamesConstructor::finishCreation):
+ (JSC::constructIntlDisplayNames):
+ (JSC::callIntlDisplayNames):
+ (JSC::IntlDisplayNamesConstructorSupportedLocalesOf):
+ * runtime/IntlDisplayNamesConstructor.h: Added.
+ * runtime/IntlDisplayNamesPrototype.cpp: Added.
+ (JSC::IntlDisplayNamesPrototype::create):
+ (JSC::IntlDisplayNamesPrototype::createStructure):
+ (JSC::IntlDisplayNamesPrototype::IntlDisplayNamesPrototype):
+ (JSC::IntlDisplayNamesPrototype::finishCreation):
+ (JSC::IntlDisplayNamesPrototypeFuncOf):
+ (JSC::IntlDisplayNamesPrototypeFuncResolvedOptions):
+ * runtime/IntlDisplayNamesPrototype.h: Added.
+ * runtime/IntlLocale.cpp:
+ (JSC::isUnicodeLanguageSubtag): Deleted.
+ (JSC::isUnicodeScriptSubtag): Deleted.
+ (JSC::isUnicodeRegionSubtag): Deleted.
+ * runtime/IntlNumberFormat.cpp:
+ (JSC::IntlNumberFormat::initializeNumberFormat):
+ * runtime/IntlObject.cpp:
+ (JSC::createDisplayNamesConstructor):
+ (JSC::IntlObject::finishCreation):
+ (JSC::isUnicodeLanguageSubtag):
+ (JSC::isUnicodeScriptSubtag):
+ (JSC::isUnicodeRegionSubtag):
+ (JSC::isUnicodeVariantSubtag):
+ (JSC::isUnicodeLanguageId):
+ (JSC::isWellFormedCurrencyCode):
+ * runtime/IntlObject.h:
+ (JSC::intlDisplayNamesAvailableLocales):
+ * runtime/IntlRelativeTimeFormat.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init):
+ (JSC::JSGlobalObject::visitChildren):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::displayNamesStructure):
+ * runtime/OptionsList.h:
+ * runtime/VM.cpp:
+ (JSC::VM::VM):
+ * runtime/VM.h:
+
2020-07-20 Geoffrey Garen <[email protected]>
REGRESSION (r264242): [ macOS ] imported/w3c/web-platform-tests/wasm/jsapi/constructor/instantiate.any.html is a flaky crash
Modified: trunk/Source/_javascript_Core/DerivedSources-input.xcfilelist (264638 => 264639)
--- trunk/Source/_javascript_Core/DerivedSources-input.xcfilelist 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/DerivedSources-input.xcfilelist 2020-07-21 00:04:06 UTC (rev 264639)
@@ -137,6 +137,8 @@
$(PROJECT_DIR)/runtime/IntlCollatorPrototype.cpp
$(PROJECT_DIR)/runtime/IntlDateTimeFormatConstructor.cpp
$(PROJECT_DIR)/runtime/IntlDateTimeFormatPrototype.cpp
+$(PROJECT_DIR)/runtime/IntlDisplayNamesConstructor.cpp
+$(PROJECT_DIR)/runtime/IntlDisplayNamesPrototype.cpp
$(PROJECT_DIR)/runtime/IntlLocalePrototype.cpp
$(PROJECT_DIR)/runtime/IntlNumberFormatConstructor.cpp
$(PROJECT_DIR)/runtime/IntlNumberFormatPrototype.cpp
Modified: trunk/Source/_javascript_Core/DerivedSources-output.xcfilelist (264638 => 264639)
--- trunk/Source/_javascript_Core/DerivedSources-output.xcfilelist 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/DerivedSources-output.xcfilelist 2020-07-21 00:04:06 UTC (rev 264639)
@@ -27,6 +27,8 @@
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/IntlCollatorPrototype.lut.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/IntlDateTimeFormatConstructor.lut.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/IntlDateTimeFormatPrototype.lut.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/IntlDisplayNamesConstructor.lut.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/IntlDisplayNamesPrototype.lut.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/IntlLocalePrototype.lut.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/IntlNumberFormatConstructor.lut.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/IntlNumberFormatPrototype.lut.h
Modified: trunk/Source/_javascript_Core/DerivedSources.make (264638 => 264639)
--- trunk/Source/_javascript_Core/DerivedSources.make 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/DerivedSources.make 2020-07-21 00:04:06 UTC (rev 264639)
@@ -158,6 +158,8 @@
IntlCollatorPrototype.lut.h \
IntlDateTimeFormatConstructor.lut.h \
IntlDateTimeFormatPrototype.lut.h \
+ IntlDisplayNamesConstructor.lut.h \
+ IntlDisplayNamesPrototype.lut.h \
IntlLocalePrototype.lut.h \
IntlNumberFormatConstructor.lut.h \
IntlNumberFormatPrototype.lut.h \
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (264638 => 264639)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2020-07-21 00:04:06 UTC (rev 264639)
@@ -1823,6 +1823,9 @@
E34EDBF71DB5FFC900DC87A5 /* FrameTracers.h in Headers */ = {isa = PBXBuildFile; fileRef = E34EDBF61DB5FFC100DC87A5 /* FrameTracers.h */; settings = {ATTRIBUTES = (Private, ); }; };
E34F930E2322D882002B8DB4 /* JSGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = E34F930C2322D881002B8DB4 /* JSGenerator.h */; };
E350708A1DC49BBF0089BCD6 /* DOMJITSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = E35070891DC49BB60089BCD6 /* DOMJITSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E353C11D24AA4CB7003FBDF3 /* IntlDisplayNames.h in Headers */ = {isa = PBXBuildFile; fileRef = E353C11724AA4CB6003FBDF3 /* IntlDisplayNames.h */; };
+ E353C11E24AA4CB7003FBDF3 /* IntlDisplayNamesConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = E353C11824AA4CB6003FBDF3 /* IntlDisplayNamesConstructor.h */; };
+ E353C12124AA4CB7003FBDF3 /* IntlDisplayNamesPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = E353C11B24AA4CB7003FBDF3 /* IntlDisplayNamesPrototype.h */; };
E354622B1B6065D100545386 /* ConstructAbility.h in Headers */ = {isa = PBXBuildFile; fileRef = E354622A1B6065D100545386 /* ConstructAbility.h */; settings = {ATTRIBUTES = (Private, ); }; };
E3555B8A1DAE03A500F36921 /* DOMJITCallDOMGetterSnippet.h in Headers */ = {isa = PBXBuildFile; fileRef = E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterSnippet.h */; settings = {ATTRIBUTES = (Private, ); }; };
E355D38F22446877008F1AD6 /* GlobalExecutable.h in Headers */ = {isa = PBXBuildFile; fileRef = E355D38D2244686B008F1AD6 /* GlobalExecutable.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1832,6 +1835,8 @@
E35CA1561DBC3A5F00F83516 /* DOMJITAbstractHeap.h in Headers */ = {isa = PBXBuildFile; fileRef = E35CA1501DBC3A5600F83516 /* DOMJITAbstractHeap.h */; settings = {ATTRIBUTES = (Private, ); }; };
E35E03601B7AB43E0073AD2A /* InspectorInstrumentationObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E35E035E1B7AB43E0073AD2A /* InspectorInstrumentationObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
E3637EE9236E56B00096BD0A /* LinkTimeConstant.h in Headers */ = {isa = PBXBuildFile; fileRef = E3637EE7236E56B00096BD0A /* LinkTimeConstant.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E365F33A24AA623900C991B2 /* IntlDisplayNamesConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E365F33924AA621200C991B2 /* IntlDisplayNamesConstructor.lut.h */; };
+ E365F33B24AA623B00C991B2 /* IntlDisplayNamesPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E365F33824AA621100C991B2 /* IntlDisplayNamesPrototype.lut.h */; };
E36B767022F8D61900D09818 /* WasmOMGForOSREntryPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = E36B766F22F8D61100D09818 /* WasmOMGForOSREntryPlan.h */; };
E36CC9472086314F0051FFD6 /* WasmCreationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = E36CC9462086314F0051FFD6 /* WasmCreationMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
E3794E761B77EB97005543AE /* ModuleAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = E3794E741B77EB97005543AE /* ModuleAnalyzer.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4995,6 +5000,12 @@
E34F930B2322D881002B8DB4 /* JSGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGenerator.cpp; sourceTree = "<group>"; };
E34F930C2322D881002B8DB4 /* JSGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenerator.h; sourceTree = "<group>"; };
E35070891DC49BB60089BCD6 /* DOMJITSignature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITSignature.h; sourceTree = "<group>"; };
+ E353C11624AA4CB5003FBDF3 /* IntlDisplayNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlDisplayNames.cpp; sourceTree = "<group>"; };
+ E353C11724AA4CB6003FBDF3 /* IntlDisplayNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDisplayNames.h; sourceTree = "<group>"; };
+ E353C11824AA4CB6003FBDF3 /* IntlDisplayNamesConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDisplayNamesConstructor.h; sourceTree = "<group>"; };
+ E353C11924AA4CB6003FBDF3 /* IntlDisplayNamesPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlDisplayNamesPrototype.cpp; sourceTree = "<group>"; };
+ E353C11A24AA4CB6003FBDF3 /* IntlDisplayNamesConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntlDisplayNamesConstructor.cpp; sourceTree = "<group>"; };
+ E353C11B24AA4CB7003FBDF3 /* IntlDisplayNamesPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDisplayNamesPrototype.h; sourceTree = "<group>"; };
E354622A1B6065D100545386 /* ConstructAbility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstructAbility.h; sourceTree = "<group>"; };
E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterSnippet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITCallDOMGetterSnippet.h; sourceTree = "<group>"; };
E355D38D2244686B008F1AD6 /* GlobalExecutable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GlobalExecutable.h; sourceTree = "<group>"; };
@@ -5011,6 +5022,8 @@
E35E03611B7AB4850073AD2A /* InspectorInstrumentationObject.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = InspectorInstrumentationObject.js; sourceTree = "<group>"; };
E3637EE7236E56B00096BD0A /* LinkTimeConstant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkTimeConstant.h; sourceTree = "<group>"; };
E3637EE8236E56B00096BD0A /* LinkTimeConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinkTimeConstant.cpp; sourceTree = "<group>"; };
+ E365F33824AA621100C991B2 /* IntlDisplayNamesPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDisplayNamesPrototype.lut.h; sourceTree = "<group>"; };
+ E365F33924AA621200C991B2 /* IntlDisplayNamesConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDisplayNamesConstructor.lut.h; sourceTree = "<group>"; };
E36B480123E9573800E4A66E /* UnlinkedCodeBlockGenerator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkedCodeBlockGenerator.cpp; sourceTree = "<group>"; };
E36B766E22F8D61100D09818 /* WasmOMGForOSREntryPlan.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmOMGForOSREntryPlan.cpp; sourceTree = "<group>"; };
E36B766F22F8D61100D09818 /* WasmOMGForOSREntryPlan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmOMGForOSREntryPlan.h; sourceTree = "<group>"; };
@@ -6777,6 +6790,8 @@
A18193E21B4E0CDB00FC1029 /* IntlCollatorPrototype.lut.h */,
A1587D731B4DC1C600D69849 /* IntlDateTimeFormatConstructor.lut.h */,
A1587D741B4DC1C600D69849 /* IntlDateTimeFormatPrototype.lut.h */,
+ E365F33924AA621200C991B2 /* IntlDisplayNamesConstructor.lut.h */,
+ E365F33824AA621100C991B2 /* IntlDisplayNamesPrototype.lut.h */,
A125846C1B45A36000CC7F6C /* IntlNumberFormatConstructor.lut.h */,
A125846D1B45A36000CC7F6C /* IntlNumberFormatPrototype.lut.h */,
A7D801A61880D6A80026C39B /* JSCBuiltins.cpp */,
@@ -7280,6 +7295,12 @@
A1587D6A1B4DC14100D69849 /* IntlDateTimeFormatConstructor.h */,
A1587D6B1B4DC14100D69849 /* IntlDateTimeFormatPrototype.cpp */,
A1587D6C1B4DC14100D69849 /* IntlDateTimeFormatPrototype.h */,
+ E353C11624AA4CB5003FBDF3 /* IntlDisplayNames.cpp */,
+ E353C11724AA4CB6003FBDF3 /* IntlDisplayNames.h */,
+ E353C11A24AA4CB6003FBDF3 /* IntlDisplayNamesConstructor.cpp */,
+ E353C11824AA4CB6003FBDF3 /* IntlDisplayNamesConstructor.h */,
+ E353C11924AA4CB6003FBDF3 /* IntlDisplayNamesPrototype.cpp */,
+ E353C11B24AA4CB7003FBDF3 /* IntlDisplayNamesPrototype.h */,
A3AFF92D245A3CFA00C9BA3B /* IntlLocale.cpp */,
A3AFF92B245A3CF900C9BA3B /* IntlLocale.h */,
A3AFF92F245A3CFB00C9BA3B /* IntlLocaleConstructor.cpp */,
@@ -9777,6 +9798,11 @@
A1587D751B4DC1C600D69849 /* IntlDateTimeFormatConstructor.lut.h in Headers */,
A1587D721B4DC14100D69849 /* IntlDateTimeFormatPrototype.h in Headers */,
A1587D761B4DC1C600D69849 /* IntlDateTimeFormatPrototype.lut.h in Headers */,
+ E353C11D24AA4CB7003FBDF3 /* IntlDisplayNames.h in Headers */,
+ E353C11E24AA4CB7003FBDF3 /* IntlDisplayNamesConstructor.h in Headers */,
+ E365F33A24AA623900C991B2 /* IntlDisplayNamesConstructor.lut.h in Headers */,
+ E353C12124AA4CB7003FBDF3 /* IntlDisplayNamesPrototype.h in Headers */,
+ E365F33B24AA623B00C991B2 /* IntlDisplayNamesPrototype.lut.h in Headers */,
A1D792FD1B43864B004516F5 /* IntlNumberFormat.h in Headers */,
A1D792FF1B43864B004516F5 /* IntlNumberFormatConstructor.h in Headers */,
A125846E1B45A36000CC7F6C /* IntlNumberFormatConstructor.lut.h in Headers */,
Modified: trunk/Source/_javascript_Core/Sources.txt (264638 => 264639)
--- trunk/Source/_javascript_Core/Sources.txt 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/Sources.txt 2020-07-21 00:04:06 UTC (rev 264639)
@@ -816,6 +816,9 @@
runtime/IntlDateTimeFormat.cpp
runtime/IntlDateTimeFormatConstructor.cpp
runtime/IntlDateTimeFormatPrototype.cpp
+runtime/IntlDisplayNames.cpp
+runtime/IntlDisplayNamesConstructor.cpp
+runtime/IntlDisplayNamesPrototype.cpp
runtime/IntlLocale.cpp
runtime/IntlLocaleConstructor.cpp
runtime/IntlLocalePrototype.cpp
Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (264638 => 264639)
--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2020-07-21 00:04:06 UTC (rev 264639)
@@ -34,6 +34,7 @@
macro(Collator) \
macro(Date) \
macro(DateTimeFormat) \
+ macro(DisplayNames) \
macro(Error) \
macro(EvalError) \
macro(FinalizationRegistry) \
Added: trunk/Source/_javascript_Core/runtime/IntlDisplayNames.cpp (0 => 264639)
--- trunk/Source/_javascript_Core/runtime/IntlDisplayNames.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/IntlDisplayNames.cpp 2020-07-21 00:04:06 UTC (rev 264639)
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IntlDisplayNames.h"
+
+#include "IntlObjectInlines.h"
+#include "JSCInlines.h"
+#include "ObjectConstructor.h"
+#include <unicode/uloc.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
+
+namespace JSC {
+
+const ClassInfo IntlDisplayNames::s_info = { "Object", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(IntlDisplayNames) };
+
+IntlDisplayNames* IntlDisplayNames::create(VM& vm, Structure* structure)
+{
+ auto* object = new (NotNull, allocateCell<IntlDisplayNames>(vm.heap)) IntlDisplayNames(vm, structure);
+ object->finishCreation(vm);
+ return object;
+}
+
+Structure* IntlDisplayNames::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+}
+
+IntlDisplayNames::IntlDisplayNames(VM& vm, Structure* structure)
+ : Base(vm, structure)
+{
+}
+
+void IntlDisplayNames::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(vm, info()));
+}
+
+// https://tc39.es/ecma402/#sec-Intl.DisplayNames
+void IntlDisplayNames::initializeDisplayNames(JSGlobalObject* globalObject, JSValue locales, JSValue optionsValue)
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto requestedLocales = canonicalizeLocaleList(globalObject, locales);
+ RETURN_IF_EXCEPTION(scope, void());
+
+ JSObject* options = optionsValue.toObject(globalObject);
+ RETURN_IF_EXCEPTION(scope, void());
+
+ // Does not set either of "ca" or "nu".
+ // https://tc39.es/proposal-intl-displaynames/#sec-intl-displaynames-constructor
+ ResolveLocaleOptions localeOptions;
+
+ LocaleMatcher localeMatcher = intlOption<LocaleMatcher>(globalObject, options, vm.propertyNames->localeMatcher, { { "lookup"_s, LocaleMatcher::Lookup }, { "best fit"_s, LocaleMatcher::BestFit } }, "localeMatcher must be either \"lookup\" or \"best fit\""_s, LocaleMatcher::BestFit);
+ RETURN_IF_EXCEPTION(scope, void());
+
+ auto localeData = [](const String&, RelevantExtensionKey) -> Vector<String> {
+ return { };
+ };
+
+ auto& availableLocales = intlNumberFormatAvailableLocales();
+ auto resolved = resolveLocale(globalObject, availableLocales, requestedLocales, localeMatcher, localeOptions, { }, localeData);
+
+ m_locale = resolved.locale;
+ if (m_locale.isEmpty()) {
+ throwTypeError(globalObject, scope, "failed to initialize DisplayName due to invalid locale"_s);
+ return;
+ }
+
+ m_style = intlOption<Style>(globalObject, options, vm.propertyNames->style, { { "narrow"_s, Style::Narrow }, { "short"_s, Style::Short }, { "long"_s, Style::Long } }, "style must be either \"narrow\", \"short\", or \"long\""_s, Style::Long);
+ RETURN_IF_EXCEPTION(scope, void());
+
+ auto type = intlOption<Optional<Type>>(globalObject, options, vm.propertyNames->type, { { "language"_s, Type::Language }, { "region"_s, Type::Region }, { "script"_s, Type::Script }, { "currency"_s, Type::Currency } }, "type must be either \"language\", \"region\", \"script\", or \"currency\""_s, WTF::nullopt);
+ RETURN_IF_EXCEPTION(scope, void());
+ if (!type) {
+ throwTypeError(globalObject, scope, "type must not be undefined"_s);
+ return;
+ }
+ m_type = type.value();
+
+ m_fallback = intlOption<Fallback>(globalObject, options, Identifier::fromString(vm, "fallback"), { { "code"_s, Fallback::Code }, { "none"_s, Fallback::None } }, "fallback must be either \"code\" or \"none\""_s, Fallback::Code);
+ RETURN_IF_EXCEPTION(scope, void());
+
+#if HAVE(ICU_U_LOCALE_DISPLAY_NAMES)
+ UErrorCode status = U_ZERO_ERROR;
+
+ UDisplayContext contexts[] = {
+ // en_GB displays as 'English (United Kingdom)' (Standard Names) or 'British English' (Dialect Names).
+ // We use Dialect Names here, aligned to the examples in the spec draft and V8's behavior.
+ // https://github.com/tc39/proposal-intl-displaynames#language-display-names
+ UDISPCTX_DIALECT_NAMES,
+
+ // Capitailization mode can be picked from several options. Possibly either UDISPCTX_CAPITALIZATION_NONE or UDISPCTX_CAPITALIZATION_FOR_STANDALONE is
+ // preferable in Intl.DisplayNames. We use UDISPCTX_CAPITALIZATION_FOR_STANDALONE because it makes standalone date format better (fr "Juillet 2008" in ICU test suites),
+ // and DisplayNames will support date formats too.
+ UDISPCTX_CAPITALIZATION_FOR_STANDALONE,
+
+ // Narrow becomes UDISPCTX_LENGTH_SHORT. But in currency case, we handle differently instead of using ULocaleDisplayNames.
+ m_style == Style::Long ? UDISPCTX_LENGTH_FULL : UDISPCTX_LENGTH_SHORT,
+
+ // Always disable ICU SUBSTITUTE since it does not match against what the spec defines. ICU has some special substitute rules, for example, language "en-AA"
+ // returns "English (AA)" (while AA country code is not defined), but we would like to return either input value or undefined, so we do not want to have ICU substitute rules.
+ // Note that this is effective after ICU 65.
+ // https://github.com/unicode-org/icu/commit/53dd621e3a5cff3b78b557c405f1b1d6f125b468
+ UDISPCTX_NO_SUBSTITUTE,
+ };
+ m_localeCString = m_locale.utf8();
+ m_displayNames = std::unique_ptr<ULocaleDisplayNames, ULocaleDisplayNamesDeleter>(uldn_openForContext(m_localeCString.data(), contexts, WTF_ARRAY_LENGTH(contexts), &status));
+ if (U_FAILURE(status)) {
+ throwTypeError(globalObject, scope, "failed to initialize DisplayNames"_s);
+ return;
+ }
+#else
+ throwTypeError(globalObject, scope, "Failed to initialize Intl.DisplayNames since used feature is not supported in the linked ICU version"_s);
+ return;
+#endif
+}
+
+// https://tc39.es/proposal-intl-displaynames/#sec-Intl.DisplayNames.prototype.of
+JSValue IntlDisplayNames::of(JSGlobalObject* globalObject, JSValue codeValue) const
+{
+
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+#if HAVE(ICU_U_LOCALE_DISPLAY_NAMES)
+ ASSERT(m_displayNames);
+ auto code = codeValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, { });
+
+ Vector<UChar, 32> buffer;
+ UErrorCode status = U_ZERO_ERROR;
+
+ if (m_type == Type::Currency) {
+ // We do not use uldn_keyValueDisplayName + "currency". This is because of the following reasons.
+ // 1. ICU does not respect UDISPCTX_LENGTH_FULL / UDISPCTX_LENGTH_SHORT in its implementation.
+ // 2. There is no way to set "narrow" style in ULocaleDisplayNames while currency have "narrow" symbol style.
+
+ // CanonicalCodeForDisplayNames
+ // https://tc39.es/proposal-intl-displaynames/#sec-canonicalcodefordisplaynames
+ // 5. If ! IsWellFormedCurrencyCode(code) is false, throw a RangeError exception.
+ if (!isWellFormedCurrencyCode(code)) {
+ throwRangeError(globalObject, scope, "argument is not a well-formed currency code"_s);
+ return { };
+ }
+ ASSERT(code.isAllASCII());
+
+ UCurrNameStyle style = UCURR_LONG_NAME;
+ switch (m_style) {
+ case Style::Long:
+ style = UCURR_LONG_NAME;
+ break;
+ case Style::Short:
+ style = UCURR_SYMBOL_NAME;
+ break;
+ case Style::Narrow:
+ style = UCURR_NARROW_SYMBOL_NAME;
+ break;
+ }
+
+ // 6. Let code be the result of mapping code to upper case as described in 6.1.
+ const UChar currency[4] = {
+ toASCIIUpper(code[0]),
+ toASCIIUpper(code[1]),
+ toASCIIUpper(code[2]),
+ u'\0'
+ };
+ // The result of ucurr_getName is static string so that we do not need to free the result.
+ int32_t length = 0;
+ UBool isChoiceFormat = false; // We need to pass this, otherwise, we will see crash in ICU 64.
+ const UChar* result = ucurr_getName(currency, m_localeCString.data(), style, &isChoiceFormat, &length, &status);
+ if (U_FAILURE(status))
+ return throwTypeError(globalObject, scope, "Failed to query a display name."_s);
+ // ucurr_getName returns U_USING_DEFAULT_WARNING if the display-name is not found. But U_USING_DEFAULT_WARNING is returned even if
+ // narrow and short results are the same: narrow "USD" is "$" with U_USING_DEFAULT_WARNING since short "USD" is also "$". We need to check
+ // result == currency to check whether ICU actually failed to find the corresponding display-name. This pointer comparison is ensured by
+ // ICU API document.
+ // > Returns pointer to display string of 'len' UChars. If the resource data contains no entry for 'currency', then 'currency' itself is returned.
+ if (status == U_USING_DEFAULT_WARNING && result == currency)
+ return (m_fallback == Fallback::None) ? jsUndefined() : codeValue;
+ return jsString(vm, String(result, length));
+ }
+
+ // https://tc39.es/proposal-intl-displaynames/#sec-canonicalcodefordisplaynames
+ auto canonicalizeCodeForDisplayNames = [](Type type, const String& code) -> CString {
+ ASSERT(code.isAllASCII());
+ auto result = code.ascii();
+ char* mutableData = result.mutableData();
+ switch (type) {
+ case Type::Language: {
+ // Let code be the result of mapping code to lower case as described in 6.1.
+ for (unsigned index = 0; index < result.length(); ++index)
+ mutableData[index] = toASCIILower(mutableData[index]);
+ break;
+ }
+ case Type::Region: {
+ // Let code be the result of mapping code to upper case as described in 6.1.
+ for (unsigned index = 0; index < result.length(); ++index)
+ mutableData[index] = toASCIIUpper(mutableData[index]);
+ break;
+ }
+ case Type::Script: {
+ // Let code be the result of mapping the first character in code to upper case, and mapping the second, third and fourth character in code to lower case, as described in 6.1.
+ if (result.length() >= 1)
+ mutableData[0] = toASCIIUpper(mutableData[0]);
+ for (unsigned index = 1; index < result.length(); ++index)
+ mutableData[index] = toASCIILower(mutableData[index]);
+ break;
+ }
+ case Type::Currency:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ return result;
+ };
+
+ switch (m_type) {
+ case Type::Language: {
+ // If code does not matches the unicode_language_id production, throw a RangeError exception
+ if (!isUnicodeLanguageId(code)) {
+ throwRangeError(globalObject, scope, "argument is not a language id"_s);
+ return { };
+ }
+ auto language = canonicalizeCodeForDisplayNames(m_type, code);
+ // Do not use uldn_languageDisplayName since it is not expected one for this "language" type. It returns "en-US" for "en-US" code, instead of "American English".
+ status = callBufferProducingFunction(uldn_localeDisplayName, m_displayNames.get(), language.data(), buffer);
+ break;
+ }
+ case Type::Region: {
+ // If code does not matches the unicode_region_subtag production, throw a RangeError exception
+ if (!isUnicodeRegionSubtag(code)) {
+ throwRangeError(globalObject, scope, "argument is not a region subtag"_s);
+ return { };
+ }
+ auto region = canonicalizeCodeForDisplayNames(m_type, code);
+ status = callBufferProducingFunction(uldn_regionDisplayName, m_displayNames.get(), region.data(), buffer);
+ break;
+ }
+ case Type::Script: {
+ // If code does not matches the unicode_script_subtag production, throw a RangeError exception
+ if (!isUnicodeScriptSubtag(code)) {
+ throwRangeError(globalObject, scope, "argument is not a script subtag"_s);
+ return { };
+ }
+ auto script = canonicalizeCodeForDisplayNames(m_type, code);
+ status = callBufferProducingFunction(uldn_scriptDisplayName, m_displayNames.get(), script.data(), buffer);
+ break;
+ }
+ case Type::Currency:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ if (U_FAILURE(status)) {
+ // uldn_localeDisplayName, uldn_regionDisplayName, and uldn_scriptDisplayName return U_ILLEGAL_ARGUMENT_ERROR if the display-name is not found.
+ // We should return undefined if fallback is "none". Otherwise, we should return input value.
+ if (status == U_ILLEGAL_ARGUMENT_ERROR)
+ return (m_fallback == Fallback::None) ? jsUndefined() : codeValue;
+ return throwTypeError(globalObject, scope, "Failed to query a display name."_s);
+ }
+ return jsString(vm, String(buffer));
+#else
+ UNUSED_PARAM(codeValue);
+ throwTypeError(globalObject, scope, "Failed to initialize Intl.DisplayNames since used feature is not supported in the linked ICU version"_s);
+ return { };
+#endif
+}
+
+// https://tc39.es/proposal-intl-displaynames/#sec-Intl.DisplayNames.prototype.resolvedOptions
+JSObject* IntlDisplayNames::resolvedOptions(JSGlobalObject* globalObject) const
+{
+ VM& vm = globalObject->vm();
+ JSObject* options = constructEmptyObject(globalObject);
+ options->putDirect(vm, vm.propertyNames->locale, jsString(vm, m_locale));
+ options->putDirect(vm, vm.propertyNames->style, jsNontrivialString(vm, styleString(m_style)));
+ options->putDirect(vm, vm.propertyNames->type, jsNontrivialString(vm, typeString(m_type)));
+ options->putDirect(vm, Identifier::fromString(vm, "fallback"), jsNontrivialString(vm, fallbackString(m_fallback)));
+ return options;
+}
+
+ASCIILiteral IntlDisplayNames::styleString(Style style)
+{
+ switch (style) {
+ case Style::Narrow:
+ return "narrow"_s;
+ case Style::Short:
+ return "short"_s;
+ case Style::Long:
+ return "long"_s;
+ }
+ ASSERT_NOT_REACHED();
+ return ASCIILiteral::null();
+}
+
+ASCIILiteral IntlDisplayNames::typeString(Type type)
+{
+ switch (type) {
+ case Type::Language:
+ return "language"_s;
+ case Type::Region:
+ return "region"_s;
+ case Type::Script:
+ return "script"_s;
+ case Type::Currency:
+ return "currency"_s;
+ }
+ ASSERT_NOT_REACHED();
+ return ASCIILiteral::null();
+}
+
+ASCIILiteral IntlDisplayNames::fallbackString(Fallback fallback)
+{
+ switch (fallback) {
+ case Fallback::Code:
+ return "code"_s;
+ case Fallback::None:
+ return "none"_s;
+ }
+ ASSERT_NOT_REACHED();
+ return ASCIILiteral::null();
+}
+
+} // namespace JSC
Copied: trunk/Source/_javascript_Core/runtime/IntlDisplayNames.h (from rev 264638, trunk/Source/_javascript_Core/runtime/IntlRelativeTimeFormat.h) (0 => 264639)
--- trunk/Source/_javascript_Core/runtime/IntlDisplayNames.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/IntlDisplayNames.h 2020-07-21 00:04:06 UTC (rev 264639)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSObject.h"
+#include <unicode/uldnames.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
+
+namespace JSC {
+
+#if !defined(HAVE_ICU_U_LOCALE_DISPLAY_NAMES)
+// We need 61 or later since part of implementation uses UCURR_NARROW_SYMBOL_NAME.
+#if U_ICU_VERSION_MAJOR_NUM >= 61
+#define HAVE_ICU_U_LOCALE_DISPLAY_NAMES 1
+#endif
+#endif
+
+enum class RelevantExtensionKey : uint8_t;
+
+class IntlDisplayNames final : public JSNonFinalObject {
+public:
+ using Base = JSNonFinalObject;
+
+ static constexpr bool needsDestruction = true;
+
+ static void destroy(JSCell* cell)
+ {
+ static_cast<IntlDisplayNames*>(cell)->IntlDisplayNames::~IntlDisplayNames();
+ }
+
+ template<typename CellType, SubspaceAccess mode>
+ static IsoSubspace* subspaceFor(VM& vm)
+ {
+ return vm.intlDisplayNamesSpace<mode>();
+ }
+
+ static IntlDisplayNames* create(VM&, Structure*);
+ static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
+
+ DECLARE_INFO;
+
+ void initializeDisplayNames(JSGlobalObject*, JSValue localesValue, JSValue optionsValue);
+
+ JSValue of(JSGlobalObject*, JSValue) const;
+ JSObject* resolvedOptions(JSGlobalObject*) const;
+
+private:
+ IntlDisplayNames(VM&, Structure*);
+ void finishCreation(VM&);
+
+ enum class Style : uint8_t { Narrow, Short, Long };
+ enum class Type : uint8_t { Language, Region, Script, Currency };
+ enum class Fallback : uint8_t { Code, None };
+
+ static ASCIILiteral styleString(Style);
+ static ASCIILiteral typeString(Type);
+ static ASCIILiteral fallbackString(Fallback);
+
+ using ULocaleDisplayNamesDeleter = ICUDeleter<uldn_close>;
+ std::unique_ptr<ULocaleDisplayNames, ULocaleDisplayNamesDeleter> m_displayNames;
+ String m_locale;
+ // FIXME: We should store it only when m_type is Currency.
+ // https://bugs.webkit.org/show_bug.cgi?id=213773
+ CString m_localeCString;
+ Style m_style { Style::Long };
+ Type m_type { Type::Language };
+ Fallback m_fallback { Fallback::Code };
+};
+
+} // namespace JSC
Added: trunk/Source/_javascript_Core/runtime/IntlDisplayNamesConstructor.cpp (0 => 264639)
--- trunk/Source/_javascript_Core/runtime/IntlDisplayNamesConstructor.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/IntlDisplayNamesConstructor.cpp 2020-07-21 00:04:06 UTC (rev 264639)
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IntlDisplayNamesConstructor.h"
+
+#include "IntlDisplayNames.h"
+#include "IntlDisplayNamesPrototype.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(IntlDisplayNamesConstructor);
+
+static EncodedJSValue JSC_HOST_CALL IntlDisplayNamesConstructorSupportedLocalesOf(JSGlobalObject*, CallFrame*);
+
+}
+
+#include "IntlDisplayNamesConstructor.lut.h"
+
+namespace JSC {
+
+const ClassInfo IntlDisplayNamesConstructor::s_info = { "Function", &Base::s_info, &displayNamesConstructorTable, nullptr, CREATE_METHOD_TABLE(IntlDisplayNamesConstructor) };
+
+/* Source for IntlDisplayNamesConstructor.lut.h
+@begin displayNamesConstructorTable
+ supportedLocalesOf IntlDisplayNamesConstructorSupportedLocalesOf DontEnum|Function 1
+@end
+*/
+
+IntlDisplayNamesConstructor* IntlDisplayNamesConstructor::create(VM& vm, Structure* structure, IntlDisplayNamesPrototype* displayNamesPrototype)
+{
+ auto* constructor = new (NotNull, allocateCell<IntlDisplayNamesConstructor>(vm.heap)) IntlDisplayNamesConstructor(vm, structure);
+ constructor->finishCreation(vm, displayNamesPrototype);
+ return constructor;
+}
+
+Structure* IntlDisplayNamesConstructor::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+ return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
+}
+
+static EncodedJSValue JSC_HOST_CALL callIntlDisplayNames(JSGlobalObject*, CallFrame*);
+static EncodedJSValue JSC_HOST_CALL constructIntlDisplayNames(JSGlobalObject*, CallFrame*);
+
+IntlDisplayNamesConstructor::IntlDisplayNamesConstructor(VM& vm, Structure* structure)
+ : Base(vm, structure, callIntlDisplayNames, constructIntlDisplayNames)
+{
+}
+
+void IntlDisplayNamesConstructor::finishCreation(VM& vm, IntlDisplayNamesPrototype* displayNamesPrototype)
+{
+ Base::finishCreation(vm, "DisplayNames"_s, NameAdditionMode::WithoutStructureTransition);
+ putDirectWithoutTransition(vm, vm.propertyNames->prototype, displayNamesPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
+ putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(2), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
+ displayNamesPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, this, static_cast<unsigned>(PropertyAttribute::DontEnum));
+}
+
+// https://tc39.es/ecma402/#sec-Intl.DisplayNames
+static EncodedJSValue JSC_HOST_CALL constructIntlDisplayNames(JSGlobalObject* globalObject, CallFrame* callFrame)
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ JSObject* newTarget = asObject(callFrame->newTarget());
+ Structure* structure = newTarget == callFrame->jsCallee()
+ ? globalObject->displayNamesStructure()
+ : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->displayNamesStructure());
+ RETURN_IF_EXCEPTION(scope, { });
+
+ IntlDisplayNames* displayNames = IntlDisplayNames::create(vm, structure);
+ ASSERT(displayNames);
+
+ scope.release();
+ displayNames->initializeDisplayNames(globalObject, callFrame->argument(0), callFrame->argument(1));
+ return JSValue::encode(displayNames);
+}
+
+// https://tc39.es/ecma402/#sec-Intl.DisplayNames
+static EncodedJSValue JSC_HOST_CALL callIntlDisplayNames(JSGlobalObject* globalObject, CallFrame*)
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(globalObject, scope, "DisplayNames"));
+}
+
+EncodedJSValue JSC_HOST_CALL IntlDisplayNamesConstructorSupportedLocalesOf(JSGlobalObject* globalObject, CallFrame* callFrame)
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ // Intl.DisplayNames.supportedLocalesOf(locales [, options]) (ECMA-402 2.0)
+ // https://tc39.es/proposal-intl-displaynames/#sec-Intl.DisplayNames.supportedLocalesOf
+
+ // 1. Let availableLocales be %DisplayNames%.[[availableLocales]].
+ const HashSet<String>& availableLocales = intlDisplayNamesAvailableLocales();
+
+ // 2. Let requestedLocales be CanonicalizeLocaleList(locales).
+ Vector<String> requestedLocales = canonicalizeLocaleList(globalObject, callFrame->argument(0));
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+ // 3. Return SupportedLocales(availableLocales, requestedLocales, options).
+ RELEASE_AND_RETURN(scope, JSValue::encode(supportedLocales(globalObject, availableLocales, requestedLocales, callFrame->argument(1))));
+}
+
+
+} // namespace JSC
Added: trunk/Source/_javascript_Core/runtime/IntlDisplayNamesConstructor.h (0 => 264639)
--- trunk/Source/_javascript_Core/runtime/IntlDisplayNamesConstructor.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/IntlDisplayNamesConstructor.h 2020-07-21 00:04:06 UTC (rev 264639)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "InternalFunction.h"
+#include "IntlObject.h"
+
+namespace JSC {
+
+class IntlDisplayNamesPrototype;
+
+class IntlDisplayNamesConstructor final : public InternalFunction {
+public:
+ using Base = InternalFunction;
+ static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
+
+ static IntlDisplayNamesConstructor* create(VM&, Structure*, IntlDisplayNamesPrototype*);
+ static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
+
+ DECLARE_INFO;
+
+private:
+ IntlDisplayNamesConstructor(VM&, Structure*);
+ void finishCreation(VM&, IntlDisplayNamesPrototype*);
+};
+STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(IntlDisplayNamesConstructor, InternalFunction);
+
+} // namespace JSC
Added: trunk/Source/_javascript_Core/runtime/IntlDisplayNamesPrototype.cpp (0 => 264639)
--- trunk/Source/_javascript_Core/runtime/IntlDisplayNamesPrototype.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/IntlDisplayNamesPrototype.cpp 2020-07-21 00:04:06 UTC (rev 264639)
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IntlDisplayNamesPrototype.h"
+
+#include "IntlDisplayNames.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+static EncodedJSValue JSC_HOST_CALL IntlDisplayNamesPrototypeFuncOf(JSGlobalObject*, CallFrame*);
+static EncodedJSValue JSC_HOST_CALL IntlDisplayNamesPrototypeFuncResolvedOptions(JSGlobalObject*, CallFrame*);
+
+}
+
+#include "IntlDisplayNamesPrototype.lut.h"
+
+namespace JSC {
+
+const ClassInfo IntlDisplayNamesPrototype::s_info = { "Intl.DisplayNames", &Base::s_info, &displayNamesPrototypeTable, nullptr, CREATE_METHOD_TABLE(IntlDisplayNamesPrototype) };
+
+/* Source for IntlDisplayNamesPrototype.lut.h
+@begin displayNamesPrototypeTable
+ of IntlDisplayNamesPrototypeFuncOf DontEnum|Function 1
+ resolvedOptions IntlDisplayNamesPrototypeFuncResolvedOptions DontEnum|Function 0
+@end
+*/
+
+IntlDisplayNamesPrototype* IntlDisplayNamesPrototype::create(VM& vm, Structure* structure)
+{
+ auto* object = new (NotNull, allocateCell<IntlDisplayNamesPrototype>(vm.heap)) IntlDisplayNamesPrototype(vm, structure);
+ object->finishCreation(vm);
+ return object;
+}
+
+Structure* IntlDisplayNamesPrototype::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+}
+
+IntlDisplayNamesPrototype::IntlDisplayNamesPrototype(VM& vm, Structure* structure)
+ : Base(vm, structure)
+{
+}
+
+void IntlDisplayNamesPrototype::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(vm, info()));
+ JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
+}
+
+// https://tc39.es/proposal-intl-displaynames/#sec-Intl.DisplayNames.prototype.of
+EncodedJSValue JSC_HOST_CALL IntlDisplayNamesPrototypeFuncOf(JSGlobalObject* globalObject, CallFrame* callFrame)
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto* displayNames = jsDynamicCast<IntlDisplayNames*>(vm, callFrame->thisValue());
+ if (!displayNames)
+ return throwVMTypeError(globalObject, scope, "Intl.DisplayNames.prototype.of called on value that's not an object initialized as a DisplayNames"_s);
+
+ RELEASE_AND_RETURN(scope, JSValue::encode(displayNames->of(globalObject, callFrame->argument(0))));
+}
+
+// https://tc39.es/proposal-intl-displaynames/#sec-Intl.DisplayNames.prototype.resolvedOptions
+EncodedJSValue JSC_HOST_CALL IntlDisplayNamesPrototypeFuncResolvedOptions(JSGlobalObject* globalObject, CallFrame* callFrame)
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto* displayNames = jsDynamicCast<IntlDisplayNames*>(vm, callFrame->thisValue());
+ if (!displayNames)
+ return throwVMTypeError(globalObject, scope, "Intl.DisplayNames.prototype.resolvedOptions called on value that's not an object initialized as a DisplayNames"_s);
+
+ RELEASE_AND_RETURN(scope, JSValue::encode(displayNames->resolvedOptions(globalObject)));
+}
+
+} // namespace JSC
Added: trunk/Source/_javascript_Core/runtime/IntlDisplayNamesPrototype.h (0 => 264639)
--- trunk/Source/_javascript_Core/runtime/IntlDisplayNamesPrototype.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/IntlDisplayNamesPrototype.h 2020-07-21 00:04:06 UTC (rev 264639)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class IntlDisplayNamesPrototype final : public JSNonFinalObject {
+public:
+ using Base = JSNonFinalObject;
+ static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
+
+ template<typename CellType, SubspaceAccess>
+ static IsoSubspace* subspaceFor(VM& vm)
+ {
+ STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(IntlDisplayNamesPrototype, Base);
+ return &vm.plainObjectSpace;
+ }
+
+ static IntlDisplayNamesPrototype* create(VM&, Structure*);
+ static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
+
+ DECLARE_INFO;
+
+private:
+ IntlDisplayNamesPrototype(VM&, Structure*);
+ void finishCreation(VM&);
+};
+
+} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/IntlLocale.cpp (264638 => 264639)
--- trunk/Source/_javascript_Core/runtime/IntlLocale.cpp 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/runtime/IntlLocale.cpp 2020-07-21 00:04:06 UTC (rev 264639)
@@ -191,27 +191,6 @@
return value ? String(value) : emptyString();
}
-// unicode_language_subtag = alpha{2,3} | alpha{5,8} ;
-static bool isUnicodeLanguageSubtag(StringView string)
-{
- auto length = string.length();
- return length >= 2 && length <= 8 && length != 4 && string.isAllSpecialCharacters<isASCIIAlpha>();
-}
-
-// unicode_script_subtag = alpha{4} ;
-static bool isUnicodeScriptSubtag(StringView string)
-{
- return string.length() == 4 && string.isAllSpecialCharacters<isASCIIAlpha>();
-}
-
-// unicode_region_subtag = alpha{2} | digit{3} ;
-static bool isUnicodeRegionSubtag(StringView string)
-{
- auto length = string.length();
- return (length == 2 && string.isAllSpecialCharacters<isASCIIAlpha>())
- || (length == 3 && string.isAllSpecialCharacters<isASCIIDigit>());
-}
-
// https://tc39.es/ecma402/#sec-Intl.Locale
void IntlLocale::initializeLocale(JSGlobalObject* globalObject, JSValue tagValue, JSValue optionsValue)
{
Modified: trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp (264638 => 264639)
--- trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp 2020-07-21 00:04:06 UTC (rev 264639)
@@ -202,7 +202,7 @@
String currency = intlStringOption(globalObject, options, Identifier::fromString(vm, "currency"), { }, nullptr, nullptr);
RETURN_IF_EXCEPTION(scope, void());
if (!currency.isNull()) {
- if (currency.length() != 3 || !currency.isAllSpecialCharacters<isASCIIAlpha>()) {
+ if (!isWellFormedCurrencyCode(currency)) {
throwException(globalObject, scope, createRangeError(globalObject, "currency is not a well-formed currency code"_s));
return;
}
Modified: trunk/Source/_javascript_Core/runtime/IntlObject.cpp (264638 => 264639)
--- trunk/Source/_javascript_Core/runtime/IntlObject.cpp 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/runtime/IntlObject.cpp 2020-07-21 00:04:06 UTC (rev 264639)
@@ -35,6 +35,9 @@
#include "IntlCollatorPrototype.h"
#include "IntlDateTimeFormatConstructor.h"
#include "IntlDateTimeFormatPrototype.h"
+#include "IntlDisplayNames.h"
+#include "IntlDisplayNamesConstructor.h"
+#include "IntlDisplayNamesPrototype.h"
#include "IntlLocale.h"
#include "IntlLocaleConstructor.h"
#include "IntlLocalePrototype.h"
@@ -78,6 +81,13 @@
return IntlDateTimeFormatConstructor::create(vm, IntlDateTimeFormatConstructor::createStructure(vm, globalObject, globalObject->functionPrototype()), jsCast<IntlDateTimeFormatPrototype*>(globalObject->dateTimeFormatStructure()->storedPrototypeObject()));
}
+static JSValue createDisplayNamesConstructor(VM& vm, JSObject* object)
+{
+ IntlObject* intlObject = jsCast<IntlObject*>(object);
+ JSGlobalObject* globalObject = intlObject->globalObject(vm);
+ return IntlDisplayNamesConstructor::create(vm, IntlDisplayNamesConstructor::createStructure(vm, globalObject, globalObject->functionPrototype()), jsCast<IntlDisplayNamesPrototype*>(globalObject->displayNamesStructure()->storedPrototypeObject()));
+}
+
static JSValue createLocaleConstructor(VM& vm, JSObject* object)
{
IntlObject* intlObject = jsCast<IntlObject*>(object);
@@ -153,6 +163,12 @@
void IntlObject::finishCreation(VM& vm, JSGlobalObject*)
{
Base::finishCreation(vm);
+#if HAVE(ICU_U_LOCALE_DISPLAY_NAMES)
+ if (Options::useIntlDisplayNames())
+ putDirectWithoutTransition(vm, vm.propertyNames->DisplayNames, createDisplayNamesConstructor(vm, this), static_cast<unsigned>(PropertyAttribute::DontEnum));
+#else
+ UNUSED_PARAM(createDisplayNamesConstructor);
+#endif
}
Structure* IntlObject::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
@@ -815,6 +831,76 @@
return numberingSystems;
}
+// unicode_language_subtag = alpha{2,3} | alpha{5,8} ;
+bool isUnicodeLanguageSubtag(StringView string)
+{
+ auto length = string.length();
+ return length >= 2 && length <= 8 && length != 4 && string.isAllSpecialCharacters<isASCIIAlpha>();
+}
+
+// unicode_script_subtag = alpha{4} ;
+bool isUnicodeScriptSubtag(StringView string)
+{
+ return string.length() == 4 && string.isAllSpecialCharacters<isASCIIAlpha>();
+}
+
+// unicode_region_subtag = alpha{2} | digit{3} ;
+bool isUnicodeRegionSubtag(StringView string)
+{
+ auto length = string.length();
+ return (length == 2 && string.isAllSpecialCharacters<isASCIIAlpha>())
+ || (length == 3 && string.isAllSpecialCharacters<isASCIIDigit>());
+}
+
+// unicode_variant_subtag = (alphanum{5,8} | digit alphanum{3}) ;
+bool isUnicodeVariantSubtag(StringView string)
+{
+ auto length = string.length();
+ if (length >= 5 && length <= 8)
+ return string.isAllSpecialCharacters<isASCIIAlphanumeric>();
+ return length == 4 && isASCIIDigit(string[0]) && string.substring(1).isAllSpecialCharacters<isASCIIAlphanumeric>();
+}
+
+// unicode_language_id, but intersection of BCP47 and UTS35.
+// unicode_language_id =
+// | unicode_language_subtag (sep unicode_script_subtag)? (sep unicode_region_subtag)? (sep unicode_variant_subtag)* ;
+// https://github.com/tc39/proposal-intl-displaynames/issues/79
+bool isUnicodeLanguageId(StringView string)
+{
+ Vector<StringView, 4> subtags;
+ for (auto subtag : string.splitAllowingEmptyEntries('-'))
+ subtags.append(subtag);
+
+ ASSERT(subtags.size() >= 1);
+ unsigned cursor = 0;
+ if (!isUnicodeLanguageSubtag(subtags[cursor]))
+ return false;
+ ++cursor;
+
+ if (cursor == subtags.size())
+ return true;
+ if (isUnicodeScriptSubtag(subtags[cursor]))
+ ++cursor;
+
+ if (cursor == subtags.size())
+ return true;
+ if (isUnicodeRegionSubtag(subtags[cursor]))
+ ++cursor;
+
+ while (true) {
+ if (cursor == subtags.size())
+ return true;
+ if (!isUnicodeVariantSubtag(subtags[cursor]))
+ return false;
+ ++cursor;
+ }
+}
+
+bool isWellFormedCurrencyCode(StringView currency)
+{
+ return currency.length() == 3 && currency.isAllSpecialCharacters<isASCIIAlpha>();
+}
+
EncodedJSValue JSC_HOST_CALL intlObjectFuncGetCanonicalLocales(JSGlobalObject* globalObject, CallFrame* callFrame)
{
// Intl.getCanonicalLocales(locales)
Modified: trunk/Source/_javascript_Core/runtime/IntlObject.h (264638 => 264639)
--- trunk/Source/_javascript_Core/runtime/IntlObject.h 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/runtime/IntlObject.h 2020-07-21 00:04:06 UTC (rev 264639)
@@ -82,6 +82,7 @@
const HashSet<String>& intlAvailableLocales();
const HashSet<String>& intlCollatorAvailableLocales();
inline const HashSet<String>& intlDateTimeFormatAvailableLocales() { return intlAvailableLocales(); }
+inline const HashSet<String>& intlDisplayNamesAvailableLocales() { return intlAvailableLocales(); }
inline const HashSet<String>& intlNumberFormatAvailableLocales() { return intlAvailableLocales(); }
inline const HashSet<String>& intlPluralRulesAvailableLocales() { return intlAvailableLocales(); }
inline const HashSet<String>& intlRelativeTimeFormatAvailableLocales() { return intlAvailableLocales(); }
@@ -111,6 +112,14 @@
bool isUnicodeLocaleIdentifierType(StringView);
+bool isUnicodeLanguageSubtag(StringView);
+bool isUnicodeScriptSubtag(StringView);
+bool isUnicodeRegionSubtag(StringView);
+bool isUnicodeVariantSubtag(StringView);
+bool isUnicodeLanguageId(StringView);
+
+bool isWellFormedCurrencyCode(StringView);
+
struct UFieldPositionIteratorDeleter {
void operator()(UFieldPositionIterator*) const;
};
Modified: trunk/Source/_javascript_Core/runtime/IntlRelativeTimeFormat.h (264638 => 264639)
--- trunk/Source/_javascript_Core/runtime/IntlRelativeTimeFormat.h 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/runtime/IntlRelativeTimeFormat.h 2020-07-21 00:04:06 UTC (rev 264639)
@@ -33,6 +33,8 @@
enum class RelevantExtensionKey : uint8_t;
+enum class RelevantExtensionKey : uint8_t;
+
class IntlRelativeTimeFormat final : public JSNonFinalObject {
public:
using Base = JSNonFinalObject;
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (264638 => 264639)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2020-07-21 00:04:06 UTC (rev 264639)
@@ -75,6 +75,8 @@
#include "IntlCollatorPrototype.h"
#include "IntlDateTimeFormat.h"
#include "IntlDateTimeFormatPrototype.h"
+#include "IntlDisplayNames.h"
+#include "IntlDisplayNamesPrototype.h"
#include "IntlLocale.h"
#include "IntlLocalePrototype.h"
#include "IntlNumberFormat.h"
@@ -985,6 +987,12 @@
IntlDateTimeFormatPrototype* dateTimeFormatPrototype = IntlDateTimeFormatPrototype::create(init.vm, globalObject, IntlDateTimeFormatPrototype::createStructure(init.vm, globalObject, globalObject->objectPrototype()));
init.set(IntlDateTimeFormat::createStructure(init.vm, globalObject, dateTimeFormatPrototype));
});
+ m_displayNamesStructure.initLater(
+ [] (const Initializer<Structure>& init) {
+ JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(init.owner);
+ IntlDisplayNamesPrototype* displayNamesPrototype = IntlDisplayNamesPrototype::create(init.vm, IntlDisplayNamesPrototype::createStructure(init.vm, globalObject, globalObject->objectPrototype()));
+ init.set(IntlDisplayNames::createStructure(init.vm, globalObject, displayNamesPrototype));
+ });
m_localeStructure.initLater(
[] (const Initializer<Structure>& init) {
JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(init.owner);
@@ -1836,6 +1844,7 @@
thisObject->m_defaultCollator.visit(visitor);
thisObject->m_collatorStructure.visit(visitor);
thisObject->m_dateTimeFormatStructure.visit(visitor);
+ thisObject->m_displayNamesStructure.visit(visitor);
thisObject->m_numberFormatStructure.visit(visitor);
thisObject->m_localeStructure.visit(visitor);
thisObject->m_pluralRulesStructure.visit(visitor);
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (264638 => 264639)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2020-07-21 00:04:06 UTC (rev 264639)
@@ -297,6 +297,7 @@
LazyProperty<JSGlobalObject, IntlCollator> m_defaultCollator;
LazyProperty<JSGlobalObject, Structure> m_collatorStructure;
LazyProperty<JSGlobalObject, Structure> m_dateTimeFormatStructure;
+ LazyProperty<JSGlobalObject, Structure> m_displayNamesStructure;
LazyProperty<JSGlobalObject, Structure> m_localeStructure;
LazyProperty<JSGlobalObject, Structure> m_numberFormatStructure;
LazyProperty<JSGlobalObject, Structure> m_pluralRulesStructure;
@@ -799,6 +800,7 @@
#endif // ENABLE(WEBASSEMBLY)
Structure* collatorStructure() { return m_collatorStructure.get(this); }
Structure* dateTimeFormatStructure() { return m_dateTimeFormatStructure.get(this); }
+ Structure* displayNamesStructure() { return m_displayNamesStructure.get(this); }
Structure* numberFormatStructure() { return m_numberFormatStructure.get(this); }
Structure* localeStructure() { return m_localeStructure.get(this); }
Structure* pluralRulesStructure() { return m_pluralRulesStructure.get(this); }
Modified: trunk/Source/_javascript_Core/runtime/OptionsList.h (264638 => 264639)
--- trunk/Source/_javascript_Core/runtime/OptionsList.h 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/runtime/OptionsList.h 2020-07-21 00:04:06 UTC (rev 264639)
@@ -489,6 +489,7 @@
/* FIXME: We should make sure finalizers don't run for detached windows before enabling WeakRefs by default. https://bugs.webkit.org/show_bug.cgi?id=214508 */ \
v(Bool, useWeakRefs, false, Normal, "Expose the WeakRef constructor.") \
v(Bool, useBigInt, true, Normal, "If true, we will enable BigInt support.") \
+ v(Bool, useIntlDisplayNames, false, Normal, "Expose the Intl.DisplayNames constructor.") \
v(Bool, useArrayAllocationProfiling, true, Normal, "If true, we will use our normal array allocation profiling. If false, the allocation profile will always claim to be undecided.") \
v(Bool, forcePolyProto, false, Normal, "If true, create_this will always create an object with a poly proto structure.") \
v(Bool, forceMiniVMMode, false, Normal, "If true, it will force mini VM mode on.") \
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (264638 => 264639)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2020-07-21 00:04:06 UTC (rev 264639)
@@ -66,6 +66,7 @@
#include "Interpreter.h"
#include "IntlCollator.h"
#include "IntlDateTimeFormat.h"
+#include "IntlDisplayNames.h"
#include "IntlLocale.h"
#include "IntlNumberFormat.h"
#include "IntlPluralRules.h"
@@ -308,6 +309,7 @@
#endif
, intlCollatorHeapCellType(IsoHeapCellType::create<IntlCollator>())
, intlDateTimeFormatHeapCellType(IsoHeapCellType::create<IntlDateTimeFormat>())
+ , intlDisplayNamesHeapCellType(IsoHeapCellType::create<IntlDisplayNames>())
, intlLocaleHeapCellType(IsoHeapCellType::create<IntlLocale>())
, intlNumberFormatHeapCellType(IsoHeapCellType::create<IntlNumberFormat>())
, intlPluralRulesHeapCellType(IsoHeapCellType::create<IntlPluralRules>())
@@ -1512,6 +1514,7 @@
#endif
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(intlCollatorSpace, intlCollatorHeapCellType.get(), IntlCollator)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(intlDateTimeFormatSpace, intlDateTimeFormatHeapCellType.get(), IntlDateTimeFormat)
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(intlDisplayNamesSpace, intlDisplayNamesHeapCellType.get(), IntlDisplayNames)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(intlLocaleSpace, intlLocaleHeapCellType.get(), IntlLocale)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(intlNumberFormatSpace, intlNumberFormatHeapCellType.get(), IntlNumberFormat)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(intlPluralRulesSpace, intlPluralRulesHeapCellType.get(), IntlPluralRules)
Modified: trunk/Source/_javascript_Core/runtime/VM.h (264638 => 264639)
--- trunk/Source/_javascript_Core/runtime/VM.h 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2020-07-21 00:04:06 UTC (rev 264639)
@@ -126,6 +126,7 @@
class Interpreter;
class IntlCollator;
class IntlDateTimeFormat;
+class IntlDisplayNames;
class IntlLocale;
class IntlNumberFormat;
class IntlPluralRules;
@@ -402,6 +403,7 @@
#endif
std::unique_ptr<IsoHeapCellType> intlCollatorHeapCellType;
std::unique_ptr<IsoHeapCellType> intlDateTimeFormatHeapCellType;
+ std::unique_ptr<IsoHeapCellType> intlDisplayNamesHeapCellType;
std::unique_ptr<IsoHeapCellType> intlLocaleHeapCellType;
std::unique_ptr<IsoHeapCellType> intlNumberFormatHeapCellType;
std::unique_ptr<IsoHeapCellType> intlPluralRulesHeapCellType;
@@ -560,6 +562,7 @@
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(withScopeSpace)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(intlCollatorSpace)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(intlDateTimeFormatSpace)
+ DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(intlDisplayNamesSpace)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(intlLocaleSpace)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(intlNumberFormatSpace)
DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(intlPluralRulesSpace)
Modified: trunk/Source/WTF/ChangeLog (264638 => 264639)
--- trunk/Source/WTF/ChangeLog 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/WTF/ChangeLog 2020-07-21 00:04:06 UTC (rev 264639)
@@ -1,3 +1,12 @@
+2020-07-20 Yusuke Suzuki <[email protected]>
+
+ [ECMA-402] Implement Intl.DisplayNames
+ https://bugs.webkit.org/show_bug.cgi?id=209779
+
+ Reviewed by Ross Kirsling.
+
+ * wtf/text/StringView.h:
+
2020-07-20 Adrian Perez de Castro <[email protected]>
Non unified build fixes, midsummer 2020 edition
Modified: trunk/Source/WTF/wtf/text/StringView.h (264638 => 264639)
--- trunk/Source/WTF/wtf/text/StringView.h 2020-07-20 23:54:06 UTC (rev 264638)
+++ trunk/Source/WTF/wtf/text/StringView.h 2020-07-21 00:04:06 UTC (rev 264639)
@@ -759,6 +759,12 @@
class StringView::SplitResult::Iterator {
WTF_MAKE_FAST_ALLOCATED;
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = StringView;
+ using difference_type = ptrdiff_t;
+ using pointer = value_type*;
+ using reference = value_type&;
+
StringView operator*() const;
WTF_EXPORT_PRIVATE Iterator& operator++();