diff --git a/src/flags/flag-definitions.h b/src/flags/flag-definitions.h index 9f16930bee..2ae76f25d9 100644 --- a/src/flags/flag-definitions.h +++ b/src/flags/flag-definitions.h @@ -280,7 +280,7 @@ DEFINE_BOOL(harmony_shipping, true, "enable all shipped harmony features") #ifdef V8_INTL_SUPPORT #define HARMONY_INPROGRESS(V) \ HARMONY_INPROGRESS_BASE(V) \ - V(harmony_intl_displaynames_date_types, "Intl.DisplayNames date types") + V(harmony_intl_displaynames_v2, "Intl.DisplayNames v2") #else #define HARMONY_INPROGRESS(V) HARMONY_INPROGRESS_BASE(V) #endif diff --git a/src/init/bootstrapper.cc b/src/init/bootstrapper.cc index 9a1abc5929..59d043328d 100644 --- a/src/init/bootstrapper.cc +++ b/src/init/bootstrapper.cc @@ -4417,7 +4417,7 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_error_cause) #ifdef V8_INTL_SUPPORT EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_best_fit_matcher) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_displaynames_date_types) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_displaynames_v2) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_dateformat_day_period) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_more_timezone) #endif // V8_INTL_SUPPORT diff --git a/src/init/heap-symbols.h b/src/init/heap-symbols.h index 4d0213e8d1..6033c49122 100644 --- a/src/init/heap-symbols.h +++ b/src/init/heap-symbols.h @@ -28,6 +28,7 @@ V(_, day_string, "day") \ V(_, dayPeriod_string, "dayPeriod") \ V(_, decimal_string, "decimal") \ + V(_, dialect_string, "dialect") \ V(_, direction_string, "direction") \ V(_, endRange_string, "endRange") \ V(_, engineering_string, "engineering") \ @@ -62,6 +63,7 @@ V(_, isWordLike_string, "isWordLike") \ V(_, kana_string, "kana") \ V(_, language_string, "language") \ + V(_, languageDisplay_string, "languageDisplay") \ V(_, letter_string, "letter") \ V(_, list_string, "list") \ V(_, literal_string, "literal") \ diff --git a/src/objects/js-display-names-inl.h b/src/objects/js-display-names-inl.h index 5cc5b0b066..d5c5553cf6 100644 --- a/src/objects/js-display-names-inl.h +++ b/src/objects/js-display-names-inl.h @@ -35,15 +35,23 @@ inline JSDisplayNames::Style JSDisplayNames::style() const { inline void JSDisplayNames::set_fallback(Fallback fallback) { DCHECK_GE(FallbackBit::kMax, fallback); - int hints = flags(); - hints = FallbackBit::update(hints, fallback); - set_flags(hints); + set_flags(FallbackBit::update(flags(), fallback)); } inline JSDisplayNames::Fallback JSDisplayNames::fallback() const { return FallbackBit::decode(flags()); } +inline void JSDisplayNames::set_language_display( + LanguageDisplay language_display) { + DCHECK_GE(LanguageDisplayBit::kMax, language_display); + set_flags(LanguageDisplayBit::update(flags(), language_display)); +} + +inline JSDisplayNames::LanguageDisplay JSDisplayNames::language_display() + const { + return LanguageDisplayBit::decode(flags()); +} } // namespace internal } // namespace v8 diff --git a/src/objects/js-display-names.cc b/src/objects/js-display-names.cc index f95d90fcda..ed9e840fc8 100644 --- a/src/objects/js-display-names.cc +++ b/src/objects/js-display-names.cc @@ -6,22 +6,22 @@ #error Internationalization is expected to be enabled. #endif // V8_INTL_SUPPORT +#include "src/objects/js-display-names.h" + #include #include -#include "src/objects/js-display-names-inl.h" -#include "src/objects/js-display-names.h" - #include "src/execution/isolate.h" #include "src/heap/factory.h" #include "src/objects/intl-objects.h" +#include "src/objects/js-display-names-inl.h" #include "src/objects/managed.h" #include "src/objects/objects-inl.h" - #include "unicode/dtfmtsym.h" #include "unicode/dtptngen.h" #include "unicode/localebuilder.h" #include "unicode/locdspnm.h" +#include "unicode/measfmt.h" #include "unicode/timezone.h" #include "unicode/tznames.h" #include "unicode/uloc.h" @@ -41,10 +41,7 @@ enum class Type { kRegion, kScript, kCurrency, - kWeekday, - kMonth, - kQuarter, - kDayPeriod, + kCalendar, kDateTimeField }; @@ -83,7 +80,6 @@ class DisplayNamesInternal { virtual icu::Locale locale() const = 0; virtual Maybe of(Isolate* isolate, const char* code) const = 0; - virtual const char* calendar() const { return nullptr; } }; namespace { @@ -91,12 +87,15 @@ namespace { class LocaleDisplayNamesCommon : public DisplayNamesInternal { public: LocaleDisplayNamesCommon(const icu::Locale& locale, - JSDisplayNames::Style style, bool fallback) + JSDisplayNames::Style style, bool fallback, + bool dialect) : style_(style) { UDisplayContext sub = fallback ? UDISPCTX_SUBSTITUTE : UDISPCTX_NO_SUBSTITUTE; + UDisplayContext dialect_context = + dialect ? UDISPCTX_DIALECT_NAMES : UDISPCTX_STANDARD_NAMES; UDisplayContext display_context[] = {ToUDisplayContext(style_), - UDISPCTX_DIALECT_NAMES, + dialect_context, UDISPCTX_CAPITALIZATION_NONE, sub}; ldn_.reset( icu::LocaleDisplayNames::createInstance(locale, display_context, 4)); @@ -117,8 +116,8 @@ class LocaleDisplayNamesCommon : public DisplayNamesInternal { class LanguageNames : public LocaleDisplayNamesCommon { public: LanguageNames(const icu::Locale& locale, JSDisplayNames::Style style, - bool fallback) - : LocaleDisplayNamesCommon(locale, style, fallback) {} + bool fallback, bool dialect) + : LocaleDisplayNamesCommon(locale, style, fallback, dialect) {} ~LanguageNames() override = default; const char* type() const override { return "language"; } Maybe of(Isolate* isolate, @@ -151,8 +150,8 @@ class LanguageNames : public LocaleDisplayNamesCommon { class RegionNames : public LocaleDisplayNamesCommon { public: RegionNames(const icu::Locale& locale, JSDisplayNames::Style style, - bool fallback) - : LocaleDisplayNamesCommon(locale, style, fallback) {} + bool fallback, bool dialect) + : LocaleDisplayNamesCommon(locale, style, fallback, dialect) {} ~RegionNames() override = default; const char* type() const override { return "region"; } Maybe of(Isolate* isolate, @@ -173,8 +172,8 @@ class RegionNames : public LocaleDisplayNamesCommon { class ScriptNames : public LocaleDisplayNamesCommon { public: ScriptNames(const icu::Locale& locale, JSDisplayNames::Style style, - bool fallback) - : LocaleDisplayNamesCommon(locale, style, fallback) {} + bool fallback, bool dialect) + : LocaleDisplayNamesCommon(locale, style, fallback, dialect) {} ~ScriptNames() override = default; const char* type() const override { return "script"; } Maybe of(Isolate* isolate, @@ -192,13 +191,33 @@ class ScriptNames : public LocaleDisplayNamesCommon { } }; -class CurrencyNames : public LocaleDisplayNamesCommon { +class KeyValueDisplayNames : public LocaleDisplayNamesCommon { + public: + KeyValueDisplayNames(const icu::Locale& locale, JSDisplayNames::Style style, + bool fallback, bool dialect, const char* key) + : LocaleDisplayNamesCommon(locale, style, fallback, dialect), key_(key) {} + ~KeyValueDisplayNames() override = default; + const char* type() const override { return key_.c_str(); } + Maybe of(Isolate* isolate, + const char* code) const override { + std::string code_str(code); + icu::UnicodeString result; + locale_display_names()->keyValueDisplayName(key_.c_str(), code_str.c_str(), + result); + + return Just(result); + } + + private: + std::string key_; +}; + +class CurrencyNames : public KeyValueDisplayNames { public: CurrencyNames(const icu::Locale& locale, JSDisplayNames::Style style, - bool fallback) - : LocaleDisplayNamesCommon(locale, style, fallback) {} + bool fallback, bool dialect) + : KeyValueDisplayNames(locale, style, fallback, dialect, "currency") {} ~CurrencyNames() override = default; - const char* type() const override { return "currency"; } Maybe of(Isolate* isolate, const char* code) const override { std::string code_str(code); @@ -207,12 +226,23 @@ class CurrencyNames : public LocaleDisplayNamesCommon { isolate, NewRangeError(MessageTemplate::kInvalidArgument), Nothing()); } + return KeyValueDisplayNames::of(isolate, code); + } +}; - icu::UnicodeString result; - locale_display_names()->keyValueDisplayName("currency", code_str.c_str(), - result); - - return Just(result); +class CalendarNames : public KeyValueDisplayNames { + public: + CalendarNames(const icu::Locale& locale, JSDisplayNames::Style style, + bool fallback, bool dialect) + : KeyValueDisplayNames(locale, style, fallback, dialect, "calendar") {} + ~CalendarNames() override = default; + Maybe of(Isolate* isolate, + const char* code) const override { + return KeyValueDisplayNames::of(isolate, strcmp(code, "gregory") == 0 + ? "gregorian" + : strcmp(code, "ethioaa") == 0 + ? "ethiopic-amete-alem" + : code); } }; @@ -263,13 +293,16 @@ UDateTimePatternField StringToUDateTimePatternField(const char* code) { default: break; } - UNREACHABLE(); + return UDATPG_FIELD_COUNT; } class DateTimeFieldNames : public DisplayNamesInternal { public: - DateTimeFieldNames(const icu::Locale& locale, JSDisplayNames::Style style) - : locale_(locale), width_(StyleToUDateTimePGDisplayWidth(style)) { + DateTimeFieldNames(const icu::Locale& locale, JSDisplayNames::Style style, + bool fallback) + : locale_(locale), + width_(StyleToUDateTimePGDisplayWidth(style)), + fallback_(fallback) { UErrorCode status = U_ZERO_ERROR; generator_.reset( icu::DateTimePatternGenerator::createInstance(locale_, status)); @@ -282,6 +315,9 @@ class DateTimeFieldNames : public DisplayNamesInternal { const char* code) const override { UDateTimePatternField field = StringToUDateTimePatternField(code); if (field == UDATPG_FIELD_COUNT) { + if (fallback_) { + return Just(icu::UnicodeString(code, -1, US_INV)); + } THROW_NEW_ERROR_RETURN_VALUE( isolate, NewRangeError(MessageTemplate::kInvalidArgument), Nothing()); @@ -293,196 +329,25 @@ class DateTimeFieldNames : public DisplayNamesInternal { icu::Locale locale_; UDateTimePGDisplayWidth width_; std::unique_ptr generator_; + bool fallback_; }; -icu::DateFormatSymbols::DtWidthType StyleToDtWidthType( - JSDisplayNames::Style style, Type type) { - switch (style) { - case JSDisplayNames::Style::kLong: - return icu::DateFormatSymbols::WIDE; - case JSDisplayNames::Style::kShort: - return icu::DateFormatSymbols::SHORT; - case JSDisplayNames::Style::kNarrow: - if (type == Type::kQuarter) { - return icu::DateFormatSymbols::ABBREVIATED; - } else { - return icu::DateFormatSymbols::NARROW; - } - } -} - -class DateFormatSymbolsNames : public DisplayNamesInternal { - public: - DateFormatSymbolsNames(const char* type, const icu::Locale& locale, - const icu::UnicodeString* array, int32_t length, - const char* calendar) - : type_(type), - locale_(locale), - array_(array), - length_(length), - calendar_(calendar) {} - - ~DateFormatSymbolsNames() override = default; - - const char* type() const override { return type_; } - - icu::Locale locale() const override { return locale_; } - - const char* calendar() const override { - if (calendar_.empty()) { - return nullptr; - } - return calendar_.c_str(); - } - - virtual int32_t ComputeIndex(const char* code) const = 0; - - Maybe of(Isolate* isolate, - const char* code) const override { - int32_t index = ComputeIndex(code); - if (index < 0 || index >= length_) { - THROW_NEW_ERROR_RETURN_VALUE( - isolate, NewRangeError(MessageTemplate::kInvalidArgument), - Nothing()); - } - return Just(array_[index]); - } - - private: - const char* type_; - icu::Locale locale_; - const icu::UnicodeString* array_; - int32_t length_; - std::string calendar_; -}; - -class WeekdayNames : public DateFormatSymbolsNames { - public: - WeekdayNames(const char* type, const icu::Locale& locale, - const icu::UnicodeString* array, int32_t length, - const char* calendar) - : DateFormatSymbolsNames(type, locale, array, length, calendar) {} - ~WeekdayNames() override = default; - - int32_t ComputeIndex(const char* code) const override { - int32_t i = atoi(code); - if (i == 7) return 1; - if (i > 0 && i < 7) return i + 1; - return -1; - } -}; - -class MonthNames : public DateFormatSymbolsNames { - public: - MonthNames(const char* type, const icu::Locale& locale, - const icu::UnicodeString* array, int32_t length, - const char* calendar) - : DateFormatSymbolsNames(type, locale, array, length, calendar) {} - ~MonthNames() override = default; - - int32_t ComputeIndex(const char* code) const override { - return atoi(code) - 1; - } -}; - -class QuarterNames : public DateFormatSymbolsNames { - public: - QuarterNames(const char* type, const icu::Locale& locale, - const icu::UnicodeString* array, int32_t length, - const char* calendar) - : DateFormatSymbolsNames(type, locale, array, length, calendar) {} - ~QuarterNames() override = default; - - int32_t ComputeIndex(const char* code) const override { - return atoi(code) - 1; - } -}; - -class DayPeriodNames : public DateFormatSymbolsNames { - public: - DayPeriodNames(const char* type, const icu::Locale& locale, - const icu::UnicodeString* array, int32_t length, - const char* calendar) - : DateFormatSymbolsNames(type, locale, array, length, calendar) {} - ~DayPeriodNames() override = default; - - int32_t ComputeIndex(const char* code) const override { - if (strcmp("am", code) == 0) { - return 0; - } else if (strcmp("pm", code) == 0) { - return 1; - } else { - return -1; - } - } -}; - -const char* gWeekday = "weekday"; -const char* gMonth = "month"; -const char* gQuarter = "quarter"; -const char* gDayPeriod = "dayPeriod"; - -DateFormatSymbolsNames* CreateDateFormatSymbolsNames( - const icu::Locale& locale, JSDisplayNames::Style style, Type type) { - UErrorCode status = U_ZERO_ERROR; - std::unique_ptr symbols( - icu::DateFormatSymbols::createForLocale(locale, status)); - if (U_FAILURE(status)) { - return nullptr; - } - icu::DateFormatSymbols::DtWidthType width_type = - StyleToDtWidthType(style, type); - int32_t count = 0; - std::string calendar = - locale.getUnicodeKeywordValue("ca", status); - - switch (type) { - case Type::kMonth: - return new MonthNames( - gMonth, locale, - symbols->getMonths(count, icu::DateFormatSymbols::STANDALONE, - width_type), - count, calendar.c_str()); - case Type::kWeekday: - return new WeekdayNames( - gWeekday, locale, - symbols->getWeekdays(count, icu::DateFormatSymbols::STANDALONE, - width_type), - count, calendar.c_str()); - case Type::kQuarter: - return new QuarterNames( - gQuarter, locale, - symbols->getQuarters(count, icu::DateFormatSymbols::STANDALONE, - width_type), - count, calendar.c_str()); - case Type::kDayPeriod: - return new DayPeriodNames(gDayPeriod, locale, - symbols->getAmPmStrings(count), count, - calendar.c_str()); - default: - UNREACHABLE(); - } -} - DisplayNamesInternal* CreateInternal(const icu::Locale& locale, JSDisplayNames::Style style, Type type, - bool fallback) { + bool fallback, bool dialect) { switch (type) { case Type::kLanguage: - return new LanguageNames(locale, style, fallback); + return new LanguageNames(locale, style, fallback, dialect); case Type::kRegion: - return new RegionNames(locale, style, fallback); + return new RegionNames(locale, style, fallback, false); case Type::kScript: - return new ScriptNames(locale, style, fallback); + return new ScriptNames(locale, style, fallback, false); case Type::kCurrency: - return new CurrencyNames(locale, style, fallback); + return new CurrencyNames(locale, style, fallback, false); + case Type::kCalendar: + return new CalendarNames(locale, style, fallback, false); case Type::kDateTimeField: - return new DateTimeFieldNames(locale, style); - case Type::kMonth: - case Type::kWeekday: - case Type::kQuarter: - case Type::kDayPeriod: - return CreateDateFormatSymbolsNames(locale, style, type); + return new DateTimeFieldNames(locale, style, fallback); default: UNREACHABLE(); } @@ -525,43 +390,15 @@ MaybeHandle JSDisplayNames::New(Isolate* isolate, // 8. Set opt.[[localeMatcher]] to matcher. Intl::MatcherOption matcher = maybe_locale_matcher.FromJust(); - std::unique_ptr calendar_str = nullptr; - if (FLAG_harmony_intl_displaynames_date_types) { - const std::vector empty_values = {}; - // Let calendar be ? GetOption(options, "calendar", - // "string", undefined, undefined). - Maybe maybe_calendar = Intl::GetStringOption( - isolate, options, "calendar", empty_values, service, &calendar_str); - MAYBE_RETURN(maybe_calendar, MaybeHandle()); - // If calendar is not undefined, then - if (maybe_calendar.FromJust() && calendar_str != nullptr) { - // a. If calendar does not match the (3*8alphanum) *("-" (3*8alphanum)) - // sequence, throw a RangeError exception. - if (!Intl::IsWellFormedCalendar(calendar_str.get())) { - THROW_NEW_ERROR( - isolate, - NewRangeError( - MessageTemplate::kInvalid, factory->calendar_string(), - factory->NewStringFromAsciiChecked(calendar_str.get())), - JSDisplayNames); - } - } - } - - // Set opt.[[ca]] to calendar. - // ecma402/#sec-Intl.DisplayNames-internal-slots // The value of the [[RelevantExtensionKeys]] internal slot is - // « "ca" ». - std::set relevant_extension_keys_ca = {"ca"}; + // « ». std::set relevant_extension_keys = {}; // 9. Let r be ResolveLocale(%DisplayNames%.[[AvailableLocales]], // requestedLocales, opt, %DisplayNames%.[[RelevantExtensionKeys]]). - Maybe maybe_resolve_locale = Intl::ResolveLocale( - isolate, JSDisplayNames::GetAvailableLocales(), requested_locales, - matcher, - FLAG_harmony_intl_displaynames_date_types ? relevant_extension_keys_ca - : relevant_extension_keys); + Maybe maybe_resolve_locale = + Intl::ResolveLocale(isolate, JSDisplayNames::GetAvailableLocales(), + requested_locales, matcher, relevant_extension_keys); if (maybe_resolve_locale.IsNothing()) { THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError), JSDisplayNames); @@ -569,12 +406,6 @@ MaybeHandle JSDisplayNames::New(Isolate* isolate, Intl::ResolvedLocale r = maybe_resolve_locale.FromJust(); icu::Locale icu_locale = r.icu_locale; - UErrorCode status = U_ZERO_ERROR; - if (calendar_str != nullptr && - Intl::IsValidCalendar(icu_locale, calendar_str.get())) { - icu_locale.setUnicodeKeywordValue("ca", calendar_str.get(), status); - DCHECK(U_SUCCESS(status)); - } // 10. Let s be ? GetOption(options, "style", "string", // «"long", "short", "narrow"», "long"). @@ -587,25 +418,16 @@ MaybeHandle JSDisplayNames::New(Isolate* isolate, // 11. Set displayNames.[[Style]] to style. // 12. Let type be ? GetOption(options, "type", "string", « "language", - // "region", "script", "currency", "weekday", "month", "quarter", - // "dayPeriod", "dateTimeField" », undefined). + // "region", "script", "currency" , "calendar", "dateTimeField", "unit"», + // undefined). Maybe maybe_type = - FLAG_harmony_intl_displaynames_date_types + FLAG_harmony_intl_displaynames_v2 ? Intl::GetStringOption( isolate, options, "type", service, - {"language", "region", "script", "currency", "weekday", "month", - "quarter", "dayPeriod", "dateTimeField"}, - { - Type::kLanguage, - Type::kRegion, - Type::kScript, - Type::kCurrency, - Type::kWeekday, - Type::kMonth, - Type::kQuarter, - Type::kDayPeriod, - Type::kDateTimeField, - }, + {"language", "region", "script", "currency", "calendar", + "dateTimeField"}, + {Type::kLanguage, Type::kRegion, Type::kScript, Type::kCurrency, + Type::kCalendar, Type::kDateTimeField}, Type::kUndefined) : Intl::GetStringOption( isolate, options, "type", service, @@ -638,12 +460,28 @@ MaybeHandle JSDisplayNames::New(Isolate* isolate, // 16. Set displayNames.[[Fallback]] to fallback. + LanguageDisplay language_display_enum = LanguageDisplay::kDialect; + if (FLAG_harmony_intl_displaynames_v2) { + // 24. Let languageDisplay be ? GetOption(options, "languageDisplay", + // "string", « "dialect", "standard" », "dialect"). + Maybe maybe_language_display = + Intl::GetStringOption( + isolate, options, "languageDisplay", service, + {"dialect", "standard"}, + {LanguageDisplay::kDialect, LanguageDisplay::kStandard}, + LanguageDisplay::kDialect); + MAYBE_RETURN(maybe_language_display, MaybeHandle()); + // 25. If type is "language", then + if (type_enum == Type::kLanguage) { + // a. Set displayNames.[[LanguageDisplay]] to languageDisplay. + language_display_enum = maybe_language_display.FromJust(); + } + } + + // Set displayNames.[[Fallback]] to fallback. + // 17. Set displayNames.[[Locale]] to the value of r.[[Locale]]. - // Let calendar be r.[[ca]]. - - // Set displayNames.[[Calendar]] to calendar. - // Let dataLocale be r.[[dataLocale]]. // Let dataLocaleData be localeData.[[]]. @@ -663,7 +501,8 @@ MaybeHandle JSDisplayNames::New(Isolate* isolate, // Set displayNames.[[Fields]] to styleFields. DisplayNamesInternal* internal = CreateInternal( - icu_locale, style_enum, type_enum, fallback_enum == Fallback::kCode); + icu_locale, style_enum, type_enum, fallback_enum == Fallback::kCode, + language_display_enum == LanguageDisplay::kDialect); if (internal == nullptr) { THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError), JSDisplayNames); @@ -677,6 +516,7 @@ MaybeHandle JSDisplayNames::New(Isolate* isolate, display_names->set_flags(0); display_names->set_style(style_enum); display_names->set_fallback(fallback_enum); + display_names->set_language_display(language_display_enum); DisallowGarbageCollection no_gc; display_names->set_internal(*managed_internal); @@ -701,19 +541,13 @@ Handle JSDisplayNames::ResolvedOptions( Handle style = display_names->StyleAsString(); Handle type = factory->NewStringFromAsciiChecked(internal->type()); Handle fallback = display_names->FallbackAsString(); + Handle language_display = display_names->LanguageDisplayAsString(); Maybe maybe_create_locale = JSReceiver::CreateDataProperty( isolate, options, factory->locale_string(), locale, Just(kDontThrow)); DCHECK(maybe_create_locale.FromJust()); USE(maybe_create_locale); - if (internal->calendar() != nullptr) { - Maybe maybe_create_calendar = JSReceiver::CreateDataProperty( - isolate, options, factory->calendar_string(), - factory->NewStringFromAsciiChecked(internal->calendar()), - Just(kDontThrow)); - DCHECK(maybe_create_calendar.FromJust()); - USE(maybe_create_calendar); - } + Maybe maybe_create_style = JSReceiver::CreateDataProperty( isolate, options, factory->style_string(), style, Just(kDontThrow)); DCHECK(maybe_create_style.FromJust()); @@ -729,6 +563,17 @@ Handle JSDisplayNames::ResolvedOptions( DCHECK(maybe_create_fallback.FromJust()); USE(maybe_create_fallback); + if (FLAG_harmony_intl_displaynames_v2) { + if (std::strcmp("language", internal->type()) == 0) { + Maybe maybe_create_language_display = + JSReceiver::CreateDataProperty(isolate, options, + factory->languageDisplay_string(), + language_display, Just(kDontThrow)); + DCHECK(maybe_create_language_display.FromJust()); + USE(maybe_create_language_display); + } + } + return options; } @@ -787,5 +632,15 @@ Handle JSDisplayNames::FallbackAsString() const { UNREACHABLE(); } +Handle JSDisplayNames::LanguageDisplayAsString() const { + switch (language_display()) { + case LanguageDisplay::kDialect: + return GetReadOnlyRoots().dialect_string_handle(); + case LanguageDisplay::kStandard: + return GetReadOnlyRoots().standard_string_handle(); + } + UNREACHABLE(); +} + } // namespace internal } // namespace v8 diff --git a/src/objects/js-display-names.h b/src/objects/js-display-names.h index 837184d1de..373b826d20 100644 --- a/src/objects/js-display-names.h +++ b/src/objects/js-display-names.h @@ -46,6 +46,7 @@ class JSDisplayNames Handle StyleAsString() const; Handle FallbackAsString() const; + Handle LanguageDisplayAsString() const; // Style: identifying the display names style used. // @@ -68,6 +69,13 @@ class JSDisplayNames inline void set_fallback(Fallback fallback); inline Fallback fallback() const; + enum class LanguageDisplay { + kDialect, + kStandard, + }; + inline void set_language_display(LanguageDisplay language_display); + inline LanguageDisplay language_display() const; + // Bit positions in |flags|. DEFINE_TORQUE_GENERATED_JS_DISPLAY_NAMES_FLAGS() @@ -76,6 +84,8 @@ class JSDisplayNames STATIC_ASSERT(Style::kNarrow <= StyleBits::kMax); STATIC_ASSERT(Fallback::kCode <= FallbackBit::kMax); STATIC_ASSERT(Fallback::kNone <= FallbackBit::kMax); + STATIC_ASSERT(LanguageDisplay::kDialect <= LanguageDisplayBit::kMax); + STATIC_ASSERT(LanguageDisplay::kStandard <= LanguageDisplayBit::kMax); DECL_ACCESSORS(internal, Managed) diff --git a/src/objects/js-display-names.tq b/src/objects/js-display-names.tq index d2edf228d0..f70c0a1a3b 100644 --- a/src/objects/js-display-names.tq +++ b/src/objects/js-display-names.tq @@ -7,9 +7,12 @@ type JSDisplayNamesStyle extends int32 constexpr 'JSDisplayNames::Style'; type JSDisplayNamesFallback extends int32 constexpr 'JSDisplayNames::Fallback'; +type JSDisplayNamesLanguageDisplay extends int32 +constexpr 'JSDisplayNames::LanguageDisplay'; bitfield struct JSDisplayNamesFlags extends uint31 { style: JSDisplayNamesStyle: 2 bit; fallback: JSDisplayNamesFallback: 1 bit; + language_display: JSDisplayNamesLanguageDisplay: 1 bit; } @generateCppClass diff --git a/test/intl/displaynames/calendar-v2.js b/test/intl/displaynames/calendar-v2.js new file mode 100644 index 0000000000..15d7825be7 --- /dev/null +++ b/test/intl/displaynames/calendar-v2.js @@ -0,0 +1,20 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file.islamic' + +// Flags: --harmony_intl_displaynames_v2 + +const calendars = [ + 'buddhist', 'chinese', 'coptic', 'dangi', 'ethioaa', 'ethiopic-amete-alem', + 'ethiopic', 'gregory', 'hebrew', 'indian', 'islamic', 'islamic-umalqura', + 'islamic-tbla', 'islamic-civil', 'islamic-rgsa', 'iso8601', 'japanese', + 'persian', 'roc' +]; +let en = new Intl.DisplayNames("en", {type: 'calendar'}); +let zh = new Intl.DisplayNames("zh", {type: 'calendar'}); + +calendars.forEach(function(calendar) { + assertFalse(en.of(calendar) == zh.of(calendar), + calendar + ":" + en.of(calendar) + " == " + + zh.of(calendar)); +}); diff --git a/test/intl/displaynames/constructor-order-v2.js b/test/intl/displaynames/constructor-order-v2.js new file mode 100644 index 0000000000..ee815e3aa1 --- /dev/null +++ b/test/intl/displaynames/constructor-order-v2.js @@ -0,0 +1,30 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony_intl_displaynames_v2 + +// Throws only once during construction. +// Check for all getters to prevent regression. +// Preserve the order of getter initialization. +let getCount = 0; + +new Intl.DisplayNames(['en-US'], { + get localeMatcher() { + assertEquals(0, getCount++); + }, + get style() { + assertEquals(1, getCount++); + }, + get type() { + assertEquals(2, getCount++); + return 'language'; + }, + get fallback() { + assertEquals(3, getCount++); + }, + get languageDisplay() { + assertEquals(4, getCount++); + }, +}); +assertEquals(5, getCount); diff --git a/test/intl/displaynames/constructor-v2.js b/test/intl/displaynames/constructor-v2.js new file mode 100644 index 0000000000..974f193373 --- /dev/null +++ b/test/intl/displaynames/constructor-v2.js @@ -0,0 +1,21 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony_intl_displaynames_v2 + +assertDoesNotThrow( + () => new Intl.DisplayNames( + 'sr', {type: 'calendar'})); + +assertDoesNotThrow( + () => new Intl.DisplayNames( + 'sr', {type: 'dateTimeField'})); + +assertDoesNotThrow( + () => new Intl.DisplayNames( + 'sr', {type: 'language', languageDisplay: 'standard'})); + +assertDoesNotThrow( + () => new Intl.DisplayNames( + 'sr', {type: 'language', languageDisplay: 'dialect'})); diff --git a/test/intl/displaynames/date-time-field-v2.js b/test/intl/displaynames/date-time-field-v2.js new file mode 100644 index 0000000000..b7d68ba913 --- /dev/null +++ b/test/intl/displaynames/date-time-field-v2.js @@ -0,0 +1,18 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony_intl_displaynames_v2 + +const dateTimeFields = [ + 'era', 'year', 'quarter', 'month', 'weekOfYear', 'weekday', 'day', + 'dayPeriod', 'hour', 'minute', 'second', 'timeZoneName' +]; +let en = new Intl.DisplayNames("en", {type: 'dateTimeField'}); +let zh = new Intl.DisplayNames("zh", {type: 'dateTimeField'}); + +dateTimeFields.forEach(function(dateTimeField) { + assertFalse(en.of(dateTimeField) == zh.of(dateTimeField), + dateTimeField + ":" + en.of(dateTimeField) + " == " + + zh.of(dateTimeField)); +}); diff --git a/test/intl/displaynames/resolved-options-v2.js b/test/intl/displaynames/resolved-options-v2.js new file mode 100644 index 0000000000..843c0cacb8 --- /dev/null +++ b/test/intl/displaynames/resolved-options-v2.js @@ -0,0 +1,58 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony_intl_displaynames_v2 + +let displayNames = new Intl.DisplayNames(undefined, {type: 'language'}); +// The default languageDisplay is 'dialect' if type is 'language' +assertEquals('dialect', displayNames.resolvedOptions().languageDisplay); + +['region', 'script', 'calendar', 'dateTimeField', 'currency'].forEach( + function(type) { + let dn = new Intl.DisplayNames(undefined, {type}); + assertEquals(undefined, dn.resolvedOptions().languageDisplay); + }); + +const styles = ["long", "short", "narrow"]; +const types = ["calendar", "dateTimeField"]; +const fallbacks = ["code", "none"]; + +styles.forEach(function(style) { + types.forEach(function(type) { + assertEquals(style, + (new Intl.DisplayNames(['sr'], {style, type})).resolvedOptions().style); + assertEquals(type, + (new Intl.DisplayNames(['sr'], {style, type})).resolvedOptions().type); + assertEquals(fallbacks[0], + (new Intl.DisplayNames( + ['sr'], {style, type})).resolvedOptions().fallback); + fallbacks.forEach(function(fallback) { + assertEquals(style, + (new Intl.DisplayNames( + ['sr'], {style, type, fallback})).resolvedOptions().style); + assertEquals(type, + (new Intl.DisplayNames( + ['sr'], {style, type, fallback})).resolvedOptions().type); + assertEquals(fallback, + (new Intl.DisplayNames( + ['sr'], {style, type, fallback})).resolvedOptions().fallback); + }); + }); +}); + +const languageDisplays = ["dialect", "standard"]; +styles.forEach(function(style) { + let type = 'language'; + languageDisplays.forEach(function(languageDisplay) { + assertEquals(style, + (new Intl.DisplayNames(['sr'], {style, type, languageDisplay})) + .resolvedOptions().style); + assertEquals(type, + (new Intl.DisplayNames(['sr'], {style, type, languageDisplay})) + .resolvedOptions().type); + assertEquals(languageDisplay, + (new Intl.DisplayNames(['sr'], {style, type, languageDisplay})) + .resolvedOptions().languageDisplay); + }); +}); diff --git a/tools/v8heapconst.py b/tools/v8heapconst.py index 07c1261a51..373c2ab51a 100644 --- a/tools/v8heapconst.py +++ b/tools/v8heapconst.py @@ -329,66 +329,66 @@ KNOWN_MAPS = { ("read_only_space", 0x03215): (67, "BasicBlockCountersMarkerMap"), ("read_only_space", 0x03259): (91, "ArrayBoilerplateDescriptionMap"), ("read_only_space", 0x03359): (104, "InterceptorInfoMap"), - ("read_only_space", 0x05661): (76, "PromiseFulfillReactionJobTaskMap"), - ("read_only_space", 0x05689): (77, "PromiseRejectReactionJobTaskMap"), - ("read_only_space", 0x056b1): (78, "CallableTaskMap"), - ("read_only_space", 0x056d9): (79, "CallbackTaskMap"), - ("read_only_space", 0x05701): (80, "PromiseResolveThenableJobTaskMap"), - ("read_only_space", 0x05729): (83, "FunctionTemplateInfoMap"), - ("read_only_space", 0x05751): (84, "ObjectTemplateInfoMap"), - ("read_only_space", 0x05779): (85, "AccessCheckInfoMap"), - ("read_only_space", 0x057a1): (86, "AccessorInfoMap"), - ("read_only_space", 0x057c9): (87, "AccessorPairMap"), - ("read_only_space", 0x057f1): (88, "AliasedArgumentsEntryMap"), - ("read_only_space", 0x05819): (89, "AllocationMementoMap"), - ("read_only_space", 0x05841): (92, "AsmWasmDataMap"), - ("read_only_space", 0x05869): (93, "AsyncGeneratorRequestMap"), - ("read_only_space", 0x05891): (94, "BaselineDataMap"), - ("read_only_space", 0x058b9): (95, "BreakPointMap"), - ("read_only_space", 0x058e1): (96, "BreakPointInfoMap"), - ("read_only_space", 0x05909): (97, "CachedTemplateObjectMap"), - ("read_only_space", 0x05931): (99, "ClassPositionsMap"), - ("read_only_space", 0x05959): (100, "DebugInfoMap"), - ("read_only_space", 0x05981): (103, "FunctionTemplateRareDataMap"), - ("read_only_space", 0x059a9): (105, "InterpreterDataMap"), - ("read_only_space", 0x059d1): (106, "ModuleRequestMap"), - ("read_only_space", 0x059f9): (107, "PromiseCapabilityMap"), - ("read_only_space", 0x05a21): (108, "PromiseReactionMap"), - ("read_only_space", 0x05a49): (109, "PropertyDescriptorObjectMap"), - ("read_only_space", 0x05a71): (110, "PrototypeInfoMap"), - ("read_only_space", 0x05a99): (111, "RegExpBoilerplateDescriptionMap"), - ("read_only_space", 0x05ac1): (112, "ScriptMap"), - ("read_only_space", 0x05ae9): (113, "SourceTextModuleInfoEntryMap"), - ("read_only_space", 0x05b11): (114, "StackFrameInfoMap"), - ("read_only_space", 0x05b39): (115, "TemplateObjectDescriptionMap"), - ("read_only_space", 0x05b61): (116, "Tuple2Map"), - ("read_only_space", 0x05b89): (117, "WasmExceptionTagMap"), - ("read_only_space", 0x05bb1): (118, "WasmIndirectFunctionTableMap"), - ("read_only_space", 0x05bd9): (136, "SloppyArgumentsElementsMap"), - ("read_only_space", 0x05c01): (153, "DescriptorArrayMap"), - ("read_only_space", 0x05c29): (158, "UncompiledDataWithoutPreparseDataMap"), - ("read_only_space", 0x05c51): (157, "UncompiledDataWithPreparseDataMap"), - ("read_only_space", 0x05c79): (174, "OnHeapBasicBlockProfilerDataMap"), - ("read_only_space", 0x05ca1): (170, "InternalClassMap"), - ("read_only_space", 0x05cc9): (181, "SmiPairMap"), - ("read_only_space", 0x05cf1): (180, "SmiBoxMap"), - ("read_only_space", 0x05d19): (147, "ExportedSubClassBaseMap"), - ("read_only_space", 0x05d41): (148, "ExportedSubClassMap"), - ("read_only_space", 0x05d69): (68, "AbstractInternalClassSubclass1Map"), - ("read_only_space", 0x05d91): (69, "AbstractInternalClassSubclass2Map"), - ("read_only_space", 0x05db9): (135, "InternalClassWithSmiElementsMap"), - ("read_only_space", 0x05de1): (171, "InternalClassWithStructElementsMap"), - ("read_only_space", 0x05e09): (149, "ExportedSubClass2Map"), - ("read_only_space", 0x05e31): (182, "SortStateMap"), - ("read_only_space", 0x05e59): (90, "AllocationSiteWithWeakNextMap"), - ("read_only_space", 0x05e81): (90, "AllocationSiteWithoutWeakNextMap"), - ("read_only_space", 0x05ea9): (81, "LoadHandler1Map"), - ("read_only_space", 0x05ed1): (81, "LoadHandler2Map"), - ("read_only_space", 0x05ef9): (81, "LoadHandler3Map"), - ("read_only_space", 0x05f21): (82, "StoreHandler0Map"), - ("read_only_space", 0x05f49): (82, "StoreHandler1Map"), - ("read_only_space", 0x05f71): (82, "StoreHandler2Map"), - ("read_only_space", 0x05f99): (82, "StoreHandler3Map"), + ("read_only_space", 0x05691): (76, "PromiseFulfillReactionJobTaskMap"), + ("read_only_space", 0x056b9): (77, "PromiseRejectReactionJobTaskMap"), + ("read_only_space", 0x056e1): (78, "CallableTaskMap"), + ("read_only_space", 0x05709): (79, "CallbackTaskMap"), + ("read_only_space", 0x05731): (80, "PromiseResolveThenableJobTaskMap"), + ("read_only_space", 0x05759): (83, "FunctionTemplateInfoMap"), + ("read_only_space", 0x05781): (84, "ObjectTemplateInfoMap"), + ("read_only_space", 0x057a9): (85, "AccessCheckInfoMap"), + ("read_only_space", 0x057d1): (86, "AccessorInfoMap"), + ("read_only_space", 0x057f9): (87, "AccessorPairMap"), + ("read_only_space", 0x05821): (88, "AliasedArgumentsEntryMap"), + ("read_only_space", 0x05849): (89, "AllocationMementoMap"), + ("read_only_space", 0x05871): (92, "AsmWasmDataMap"), + ("read_only_space", 0x05899): (93, "AsyncGeneratorRequestMap"), + ("read_only_space", 0x058c1): (94, "BaselineDataMap"), + ("read_only_space", 0x058e9): (95, "BreakPointMap"), + ("read_only_space", 0x05911): (96, "BreakPointInfoMap"), + ("read_only_space", 0x05939): (97, "CachedTemplateObjectMap"), + ("read_only_space", 0x05961): (99, "ClassPositionsMap"), + ("read_only_space", 0x05989): (100, "DebugInfoMap"), + ("read_only_space", 0x059b1): (103, "FunctionTemplateRareDataMap"), + ("read_only_space", 0x059d9): (105, "InterpreterDataMap"), + ("read_only_space", 0x05a01): (106, "ModuleRequestMap"), + ("read_only_space", 0x05a29): (107, "PromiseCapabilityMap"), + ("read_only_space", 0x05a51): (108, "PromiseReactionMap"), + ("read_only_space", 0x05a79): (109, "PropertyDescriptorObjectMap"), + ("read_only_space", 0x05aa1): (110, "PrototypeInfoMap"), + ("read_only_space", 0x05ac9): (111, "RegExpBoilerplateDescriptionMap"), + ("read_only_space", 0x05af1): (112, "ScriptMap"), + ("read_only_space", 0x05b19): (113, "SourceTextModuleInfoEntryMap"), + ("read_only_space", 0x05b41): (114, "StackFrameInfoMap"), + ("read_only_space", 0x05b69): (115, "TemplateObjectDescriptionMap"), + ("read_only_space", 0x05b91): (116, "Tuple2Map"), + ("read_only_space", 0x05bb9): (117, "WasmExceptionTagMap"), + ("read_only_space", 0x05be1): (118, "WasmIndirectFunctionTableMap"), + ("read_only_space", 0x05c09): (136, "SloppyArgumentsElementsMap"), + ("read_only_space", 0x05c31): (153, "DescriptorArrayMap"), + ("read_only_space", 0x05c59): (158, "UncompiledDataWithoutPreparseDataMap"), + ("read_only_space", 0x05c81): (157, "UncompiledDataWithPreparseDataMap"), + ("read_only_space", 0x05ca9): (174, "OnHeapBasicBlockProfilerDataMap"), + ("read_only_space", 0x05cd1): (170, "InternalClassMap"), + ("read_only_space", 0x05cf9): (181, "SmiPairMap"), + ("read_only_space", 0x05d21): (180, "SmiBoxMap"), + ("read_only_space", 0x05d49): (147, "ExportedSubClassBaseMap"), + ("read_only_space", 0x05d71): (148, "ExportedSubClassMap"), + ("read_only_space", 0x05d99): (68, "AbstractInternalClassSubclass1Map"), + ("read_only_space", 0x05dc1): (69, "AbstractInternalClassSubclass2Map"), + ("read_only_space", 0x05de9): (135, "InternalClassWithSmiElementsMap"), + ("read_only_space", 0x05e11): (171, "InternalClassWithStructElementsMap"), + ("read_only_space", 0x05e39): (149, "ExportedSubClass2Map"), + ("read_only_space", 0x05e61): (182, "SortStateMap"), + ("read_only_space", 0x05e89): (90, "AllocationSiteWithWeakNextMap"), + ("read_only_space", 0x05eb1): (90, "AllocationSiteWithoutWeakNextMap"), + ("read_only_space", 0x05ed9): (81, "LoadHandler1Map"), + ("read_only_space", 0x05f01): (81, "LoadHandler2Map"), + ("read_only_space", 0x05f29): (81, "LoadHandler3Map"), + ("read_only_space", 0x05f51): (82, "StoreHandler0Map"), + ("read_only_space", 0x05f79): (82, "StoreHandler1Map"), + ("read_only_space", 0x05fa1): (82, "StoreHandler2Map"), + ("read_only_space", 0x05fc9): (82, "StoreHandler3Map"), ("map_space", 0x02119): (1057, "ExternalMap"), ("map_space", 0x02141): (1098, "JSMessageObjectMap"), }