Commit 93014366 authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[Intl] Implement intl-datetime-style

See https://github.com/tc39/proposal-intl-datetime-style
Design Doc: https://goo.gl/v7n7zV


Bug: v8:8702
Change-Id: If45a901e369003ded6c0c690a65f0429800d5ecc
Reviewed-on: https://chromium-review.googlesource.com/c/1417372
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59264}
parent 73aaa19f
......@@ -4212,6 +4212,11 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_sequence)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_await_optimization)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_hashbang)
#ifdef V8_INTL_SUPPORT
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_bigint)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_datetime_style)
#endif // V8_INTL_SUPPORT
#undef EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE
void Genesis::InitializeGlobal_harmony_global() {
......@@ -4642,10 +4647,6 @@ void Genesis::InitializeGlobal_harmony_intl_segmenter() {
}
}
void Genesis::InitializeGlobal_harmony_intl_bigint() {
// No new functions.
}
#endif // V8_INTL_SUPPORT
void Genesis::InitializeGlobal_harmony_object_from_entries() {
......
......@@ -204,10 +204,11 @@ DEFINE_IMPLICATION(harmony_private_methods, harmony_private_fields)
V(harmony_weak_refs, "harmony weak references") \
#ifdef V8_INTL_SUPPORT
#define HARMONY_INPROGRESS(V) \
HARMONY_INPROGRESS_BASE(V) \
V(harmony_locale, "Intl.Locale") \
V(harmony_intl_bigint, "BigInt.prototype.toLocaleString")
#define HARMONY_INPROGRESS(V) \
HARMONY_INPROGRESS_BASE(V) \
V(harmony_intl_bigint, "BigInt.prototype.toLocaleString") \
V(harmony_intl_datetime_style, "dateStyle timeStyle for DateTimeFormat") \
V(harmony_locale, "Intl.Locale")
#else
#define HARMONY_INPROGRESS(V) HARMONY_INPROGRESS_BASE(V)
#endif
......
......@@ -11,11 +11,13 @@
V(_, calendar_string, "calendar") \
V(_, cardinal_string, "cardinal") \
V(_, caseFirst_string, "caseFirst") \
V(_, dateStyle_string, "dateStyle") \
V(_, day_string, "day") \
V(_, dayPeriod_string, "dayPeriod") \
V(_, decimal_string, "decimal") \
V(_, era_string, "era") \
V(_, fraction_string, "fraction") \
V(_, full_string, "full") \
V(_, granularity_string, "granularity") \
V(_, grapheme_string, "grapheme") \
V(_, group_string, "group") \
......@@ -65,6 +67,7 @@
V(_, strict_string, "strict") \
V(_, style_string, "style") \
V(_, term_string, "term") \
V(_, timeStyle_string, "timeStyle") \
V(_, timeZone_string, "timeZone") \
V(_, timeZoneName_string, "timeZoneName") \
V(_, type_string, "type") \
......@@ -189,6 +192,7 @@
V(_, long_string, "long") \
V(_, Map_string, "Map") \
V(_, MapIterator_string, "Map Iterator") \
V(_, medium_string, "medium") \
V(_, message_string, "message") \
V(_, meta_string, "meta") \
V(_, minus_Infinity_string, "-Infinity") \
......
......@@ -36,6 +36,28 @@ inline Intl::HourCycle JSDateTimeFormat::hour_cycle() const {
return HourCycleBits::decode(flags());
}
inline void JSDateTimeFormat::set_date_style(
JSDateTimeFormat::DateTimeStyle date_style) {
int hints = flags();
hints = DateStyleBits::update(hints, date_style);
set_flags(hints);
}
inline JSDateTimeFormat::DateTimeStyle JSDateTimeFormat::date_style() const {
return DateStyleBits::decode(flags());
}
inline void JSDateTimeFormat::set_time_style(
JSDateTimeFormat::DateTimeStyle time_style) {
int hints = flags();
hints = TimeStyleBits::update(hints, time_style);
set_flags(hints);
}
inline JSDateTimeFormat::DateTimeStyle JSDateTimeFormat::time_style() const {
return TimeStyleBits::decode(flags());
}
CAST_ACCESSOR(JSDateTimeFormat);
} // namespace internal
......
......@@ -273,6 +273,26 @@ std::string JSDateTimeFormat::CanonicalizeTimeZoneID(Isolate* isolate,
return ToTitleCaseTimezoneLocation(isolate, input);
}
namespace {
Handle<String> DateTimeStyleAsString(Isolate* isolate,
JSDateTimeFormat::DateTimeStyle style) {
switch (style) {
case JSDateTimeFormat::DateTimeStyle::kFull:
return ReadOnlyRoots(isolate).full_string_handle();
case JSDateTimeFormat::DateTimeStyle::kLong:
return ReadOnlyRoots(isolate).long_string_handle();
case JSDateTimeFormat::DateTimeStyle::kMedium:
return ReadOnlyRoots(isolate).medium_string_handle();
case JSDateTimeFormat::DateTimeStyle::kShort:
return ReadOnlyRoots(isolate).short_string_handle();
case JSDateTimeFormat::DateTimeStyle::kUndefined:
UNREACHABLE();
}
}
} // namespace
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format) {
......@@ -432,6 +452,24 @@ MaybeHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
}
}
// dateStyle
if (date_time_format->date_style() != DateTimeStyle::kUndefined) {
CHECK(JSReceiver::CreateDataProperty(
isolate, options, factory->dateStyle_string(),
DateTimeStyleAsString(isolate, date_time_format->date_style()),
Just(kDontThrow))
.FromJust());
}
// timeStyle
if (date_time_format->time_style() != DateTimeStyle::kUndefined) {
CHECK(JSReceiver::CreateDataProperty(
isolate, options, factory->timeStyle_string(),
DateTimeStyleAsString(isolate, date_time_format->time_style()),
Just(kDontThrow))
.FromJust());
}
return options;
}
......@@ -762,8 +800,8 @@ std::unique_ptr<icu::Calendar> CreateCalendar(Isolate* isolate,
}
std::unique_ptr<icu::SimpleDateFormat> CreateICUDateFormat(
Isolate* isolate, const icu::Locale& icu_locale,
const std::string& skeleton) {
const icu::Locale& icu_locale, const icu::UnicodeString& skeleton,
icu::DateTimePatternGenerator& generator) {
// See https://github.com/tc39/ecma402/issues/225 . The best pattern
// generation needs to be done in the base locale according to the
// current spec however odd it may be. See also crbug.com/826549 .
......@@ -774,16 +812,10 @@ std::unique_ptr<icu::SimpleDateFormat> CreateICUDateFormat(
// locale for the pattern match is not quite right. Moreover, what to
// do with 'related year' part when 'chinese/dangi' calendar is specified
// has to be discussed. Revisit once the spec is clarified/revised.
icu::Locale no_extension_locale(icu_locale.getBaseName());
UErrorCode status = U_ZERO_ERROR;
std::unique_ptr<icu::DateTimePatternGenerator> generator(
icu::DateTimePatternGenerator::createInstance(no_extension_locale,
status));
icu::UnicodeString pattern;
if (U_SUCCESS(status)) {
pattern =
generator->getBestPattern(icu::UnicodeString(skeleton.c_str()), status);
}
UErrorCode status = U_ZERO_ERROR;
pattern = generator.getBestPattern(skeleton, status);
CHECK(U_SUCCESS(status));
// Make formatter from skeleton. Calendar and numbering system are added
// to the locale as Unicode extension (if they were specified at all).
......@@ -796,9 +828,7 @@ std::unique_ptr<icu::SimpleDateFormat> CreateICUDateFormat(
return date_format;
}
Intl::HourCycle HourCycleDefault(icu::SimpleDateFormat* date_format) {
icu::UnicodeString pattern;
date_format->toPattern(pattern);
Intl::HourCycle HourCycleFromPattern(const icu::UnicodeString pattern) {
bool in_quote = false;
for (int32_t i = 0; i < pattern.length(); i++) {
char16_t ch = pattern[i];
......@@ -823,6 +853,106 @@ Intl::HourCycle HourCycleDefault(icu::SimpleDateFormat* date_format) {
return Intl::HourCycle::kUndefined;
}
icu::DateFormat::EStyle DateTimeStyleToEStyle(
JSDateTimeFormat::DateTimeStyle style) {
switch (style) {
case JSDateTimeFormat::DateTimeStyle::kFull:
return icu::DateFormat::EStyle::kFull;
case JSDateTimeFormat::DateTimeStyle::kLong:
return icu::DateFormat::EStyle::kLong;
case JSDateTimeFormat::DateTimeStyle::kMedium:
return icu::DateFormat::EStyle::kMedium;
case JSDateTimeFormat::DateTimeStyle::kShort:
return icu::DateFormat::EStyle::kShort;
case JSDateTimeFormat::DateTimeStyle::kUndefined:
UNREACHABLE();
}
}
icu::UnicodeString ReplaceSkeleton(const icu::UnicodeString input,
Intl::HourCycle hc) {
icu::UnicodeString result;
char16_t to;
switch (hc) {
case Intl::HourCycle::kH11:
to = 'K';
break;
case Intl::HourCycle::kH12:
to = 'h';
break;
case Intl::HourCycle::kH23:
to = 'H';
break;
case Intl::HourCycle::kH24:
to = 'k';
break;
case Intl::HourCycle::kUndefined:
UNREACHABLE();
}
for (int32_t i = 0; i < input.length(); i++) {
switch (input[i]) {
case 'a':
// ignore
break;
case 'h':
case 'H':
case 'K':
case 'k':
result += to;
break;
default:
result += input[i];
break;
}
}
return result;
}
std::unique_ptr<icu::SimpleDateFormat> DateTimeStylePattern(
JSDateTimeFormat::DateTimeStyle date_style,
JSDateTimeFormat::DateTimeStyle time_style, const icu::Locale& icu_locale,
Intl::HourCycle hc, icu::DateTimePatternGenerator& generator) {
std::unique_ptr<icu::SimpleDateFormat> result;
if (date_style != JSDateTimeFormat::DateTimeStyle::kUndefined) {
if (time_style != JSDateTimeFormat::DateTimeStyle::kUndefined) {
result.reset(reinterpret_cast<icu::SimpleDateFormat*>(
icu::DateFormat::createDateTimeInstance(
DateTimeStyleToEStyle(date_style),
DateTimeStyleToEStyle(time_style), icu_locale)));
} else {
result.reset(reinterpret_cast<icu::SimpleDateFormat*>(
icu::DateFormat::createDateInstance(DateTimeStyleToEStyle(date_style),
icu_locale)));
// For instance without time, we do not need to worry about the hour cycle
// impact so we can return directly.
return result;
}
} else {
if (time_style != JSDateTimeFormat::DateTimeStyle::kUndefined) {
result.reset(reinterpret_cast<icu::SimpleDateFormat*>(
icu::DateFormat::createTimeInstance(DateTimeStyleToEStyle(time_style),
icu_locale)));
} else {
UNREACHABLE();
}
}
icu::UnicodeString pattern;
pattern = result->toPattern(pattern);
UErrorCode status = U_ZERO_ERROR;
icu::UnicodeString skeleton =
icu::DateTimePatternGenerator::staticGetSkeleton(pattern, status);
CHECK(U_SUCCESS(status));
// If the skeleton match the HourCycle, we just return it.
if (hc == HourCycleFromPattern(pattern)) {
return result;
}
return CreateICUDateFormat(icu_locale, ReplaceSkeleton(skeleton, hc),
generator);
}
} // namespace
enum FormatMatcherOption { kBestFit, kBasic };
......@@ -892,14 +1022,6 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
icu::Locale icu_locale = r.icu_locale;
DCHECK(!icu_locale.isBogus());
if (!maybe_get_hour12.FromJust() &&
hour_cycle == Intl::HourCycle::kUndefined) {
auto hc_extension_it = r.extensions.find("hc");
if (hc_extension_it != r.extensions.end()) {
hour_cycle = Intl::ToHourCycle(hc_extension_it->second.c_str());
}
}
// 17. Let timeZone be ? Get(options, "timeZone").
const std::vector<const char*> empty_values;
std::unique_ptr<char[]> timezone = nullptr;
......@@ -921,91 +1043,175 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
JSDateTimeFormat);
}
// 29. If dateTimeFormat.[[Hour]] is not undefined, then
icu::Locale no_extension_locale(icu_locale.getBaseName());
UErrorCode status = U_ZERO_ERROR;
std::unique_ptr<icu::DateTimePatternGenerator> generator(
icu::DateTimePatternGenerator::createInstance(no_extension_locale,
status));
CHECK(U_SUCCESS(status));
// 15.Let hcDefault be dataLocaleData.[[hourCycle]].
icu::UnicodeString hour_pattern = generator->getBestPattern("jjmm", status);
CHECK(U_SUCCESS(status));
Intl::HourCycle hc_default = HourCycleFromPattern(hour_pattern);
// 16.Let hc be r.[[hc]].
Intl::HourCycle hc = Intl::HourCycle::kUndefined;
if (hour_cycle == Intl::HourCycle::kUndefined) {
// d. If hour12 is not undefined, then
if (maybe_get_hour12.FromJust()) {
// i. If hour12 is true, then
if (hour12) {
hour_cycle = Intl::HourCycle::kH12;
} else { // ii. Else,
hour_cycle = Intl::HourCycle::kH23;
}
auto hc_extension_it = r.extensions.find("hc");
if (hc_extension_it != r.extensions.end()) {
hc = Intl::ToHourCycle(hc_extension_it->second.c_str());
}
} else {
hc = hour_cycle;
}
// 17. If hc is null, then
if (hc == Intl::HourCycle::kUndefined) {
// a. Set hc to hcDefault.
hc = hc_default;
}
bool has_hour_option = false;
// 22. For each row of Table 5, except the header row, do
std::string skeleton;
for (const PatternData& item : GetPatternData(hour_cycle)) {
std::unique_ptr<char[]> input;
// a. Let prop be the name given in the Property column of the row.
// b. Let value be ? GetOption(options, prop, "string", « the strings given
// in the Values column of the row », undefined).
Maybe<bool> maybe_get_option = Intl::GetStringOption(
isolate, options, item.property.c_str(), item.allowed_values,
"Intl.DateTimeFormat", &input);
MAYBE_RETURN(maybe_get_option, Handle<JSDateTimeFormat>());
if (maybe_get_option.FromJust()) {
if (item.property == "hour") {
has_hour_option = true;
// 18. If hour12 is not undefined, then
if (maybe_get_hour12.FromJust()) {
// a. If hour12 is true, then
if (hour12) {
// i. If hcDefault is "h11" or "h23", then
if (hc_default == Intl::HourCycle::kH11 ||
hc_default == Intl::HourCycle::kH23) {
// 1. Set hc to "h11".
hc = Intl::HourCycle::kH11;
// ii. Else,
} else {
// 1. Set hc to "h12".
hc = Intl::HourCycle::kH12;
}
// b. Else,
} else {
// ii. If hcDefault is "h11" or "h23", then
if (hc_default == Intl::HourCycle::kH11 ||
hc_default == Intl::HourCycle::kH23) {
// 1. Set hc to "h23".
hc = Intl::HourCycle::kH23;
// iii. Else,
} else {
// 1. Set hc to "h24".
hc = Intl::HourCycle::kH24;
}
DCHECK_NOT_NULL(input.get());
// c. Set opt.[[<prop>]] to value.
skeleton += item.map.find(input.get())->second;
}
}
date_time_format->set_hour_cycle(hc);
DateTimeStyle date_style = DateTimeStyle::kUndefined;
DateTimeStyle time_style = DateTimeStyle::kUndefined;
std::unique_ptr<icu::SimpleDateFormat> icu_date_format;
if (FLAG_harmony_intl_datetime_style) {
// 28. Let dateStyle be ? GetOption(options, "dateStyle", "string", «
// "full", "long", "medium", "short" », undefined).
Maybe<DateTimeStyle> maybe_date_style =
Intl::GetStringOption<DateTimeStyle>(
isolate, options, "dateStyle", "Intl.DateTimeFormat",
{"full", "long", "medium", "short"},
{DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium,
DateTimeStyle::kShort},
DateTimeStyle::kUndefined);
MAYBE_RETURN(maybe_date_style, MaybeHandle<JSDateTimeFormat>());
// 29. If dateStyle is not undefined, set dateTimeFormat.[[DateStyle]] to
// dateStyle.
date_style = maybe_date_style.FromJust();
if (date_style != DateTimeStyle::kUndefined) {
date_time_format->set_date_style(date_style);
}
enum FormatMatcherOption { kBestFit, kBasic };
// We implement only best fit algorithm, but still need to check
// if the formatMatcher values are in range.
// 25. Let matcher be ? GetOption(options, "formatMatcher", "string",
// « "basic", "best fit" », "best fit").
Maybe<FormatMatcherOption> maybe_format_matcher =
Intl::GetStringOption<FormatMatcherOption>(
isolate, options, "formatMatcher", "Intl.DateTimeFormat",
{"best fit", "basic"},
{FormatMatcherOption::kBestFit, FormatMatcherOption::kBasic},
FormatMatcherOption::kBestFit);
MAYBE_RETURN(maybe_format_matcher, MaybeHandle<JSDateTimeFormat>());
// TODO(ftang): uncomment the following line and handle format_matcher.
// FormatMatcherOption format_matcher = maybe_format_matcher.FromJust();
// 30. Let timeStyle be ? GetOption(options, "timeStyle", "string", «
// "full", "long", "medium", "short" »).
Maybe<DateTimeStyle> maybe_time_style =
Intl::GetStringOption<DateTimeStyle>(
isolate, options, "timeStyle", "Intl.DateTimeFormat",
{"full", "long", "medium", "short"},
{DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium,
DateTimeStyle::kShort},
DateTimeStyle::kUndefined);
MAYBE_RETURN(maybe_time_style, MaybeHandle<JSDateTimeFormat>());
// 31. If timeStyle is not undefined, set dateTimeFormat.[[TimeStyle]] to
// timeStyle.
time_style = maybe_time_style.FromJust();
if (time_style != DateTimeStyle::kUndefined) {
date_time_format->set_time_style(time_style);
}
std::unique_ptr<icu::SimpleDateFormat> date_format(
CreateICUDateFormat(isolate, icu_locale, skeleton));
if (date_format.get() == nullptr) {
// Remove extensions and try again.
icu_locale = icu::Locale(icu_locale.getBaseName());
date_format = CreateICUDateFormat(isolate, icu_locale, skeleton);
if (date_format.get() == nullptr) {
FATAL("Failed to create ICU date format, are ICU data files missing?");
// 32. If dateStyle or timeStyle are not undefined, then
if (date_style != DateTimeStyle::kUndefined ||
time_style != DateTimeStyle::kUndefined) {
icu_date_format = DateTimeStylePattern(date_style, time_style, icu_locale,
hc, *generator);
}
}
// 33. Else,
if (icu_date_format.get() == nullptr) {
bool has_hour_option = false;
// b. For each row of Table 5, except the header row, do
std::string skeleton;
for (const PatternData& item : GetPatternData(hc)) {
std::unique_ptr<char[]> input;
// i. Let prop be the name given in the Property column of the row.
// ii. Let value be ? GetOption(options, prop, "string", « the strings
// given in the Values column of the row », undefined).
Maybe<bool> maybe_get_option = Intl::GetStringOption(
isolate, options, item.property.c_str(), item.allowed_values,
"Intl.DateTimeFormat", &input);
MAYBE_RETURN(maybe_get_option, Handle<JSDateTimeFormat>());
if (maybe_get_option.FromJust()) {
if (item.property == "hour") {
has_hour_option = true;
}
DCHECK_NOT_NULL(input.get());
// iii. Set opt.[[<prop>]] to value.
skeleton += item.map.find(input.get())->second;
}
}
// The creation of Calendar depends on timeZone so we have to put 13 after 17.
// Also date_format is not created until here.
// 13. Set dateTimeFormat.[[Calendar]] to r.[[ca]].
date_format->adoptCalendar(calendar.release());
// 29. If dateTimeFormat.[[Hour]] is not undefined, then
if (has_hour_option) {
// a. Let hcDefault be dataLocaleData.[[hourCycle]].
Intl::HourCycle hc_default = HourCycleDefault(date_format.get());
// b. Let hc be dateTimeFormat.[[HourCycle]].
Intl::HourCycle hc = hour_cycle;
// c. If hc is null, then
if (hc == Intl::HourCycle::kUndefined) {
// i. Set hc to hcDefault.
hc = hc_default;
enum FormatMatcherOption { kBestFit, kBasic };
// We implement only best fit algorithm, but still need to check
// if the formatMatcher values are in range.
// c. Let matcher be ? GetOption(options, "formatMatcher", "string",
// « "basic", "best fit" », "best fit").
Maybe<FormatMatcherOption> maybe_format_matcher =
Intl::GetStringOption<FormatMatcherOption>(
isolate, options, "formatMatcher", "Intl.DateTimeFormat",
{"best fit", "basic"},
{FormatMatcherOption::kBestFit, FormatMatcherOption::kBasic},
FormatMatcherOption::kBestFit);
MAYBE_RETURN(maybe_format_matcher, MaybeHandle<JSDateTimeFormat>());
// TODO(ftang): uncomment the following line and handle format_matcher.
// FormatMatcherOption format_matcher = maybe_format_matcher.FromJust();
icu::UnicodeString skeleton_ustr(skeleton.c_str());
icu_date_format =
CreateICUDateFormat(icu_locale, skeleton_ustr, *generator);
if (icu_date_format.get() == nullptr) {
// Remove extensions and try again.
icu_locale = icu::Locale(icu_locale.getBaseName());
icu_date_format =
CreateICUDateFormat(icu_locale, skeleton_ustr, *generator);
if (icu_date_format.get() == nullptr) {
FATAL("Failed to create ICU date format, are ICU data files missing?");
}
}
// g. If dateTimeFormat.[[Hour]] is not undefined, then
if (!has_hour_option) {
// h. Else, i. Set dateTimeFormat.[[HourCycle]] to undefined.
date_time_format->set_hour_cycle(Intl::HourCycle::kUndefined);
}
// e. Set dateTimeFormat.[[HourCycle]] to hc.
date_time_format->set_hour_cycle(hc);
// 30. Else
} else {
// a. Set dateTimeFormat.[[HourCycle]] to undefined.
date_time_format->set_hour_cycle(Intl::HourCycle::kUndefined);
}
// The creation of Calendar depends on timeZone so we have to put 13 after 17.
// Also icu_date_format is not created until here.
// 13. Set dateTimeFormat.[[Calendar]] to r.[[ca]].
icu_date_format->adoptCalendar(calendar.release());
// 12.1.1 InitializeDateTimeFormat ( dateTimeFormat, locales, options )
//
// Steps 8-9 set opt.[[hc]] to value *other than undefined*
......@@ -1039,7 +1245,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::Initialize(
date_time_format->set_icu_locale(*managed_locale);
Handle<Managed<icu::SimpleDateFormat>> managed_format =
Managed<icu::SimpleDateFormat>::FromUniquePtr(isolate, 0,
std::move(date_format));
std::move(icu_date_format));
date_time_format->set_icu_simple_date_format(*managed_format);
return date_time_format;
......
......@@ -76,6 +76,9 @@ class JSDateTimeFormat : public JSObject {
Handle<String> HourCycleAsString() const;
DECL_CAST(JSDateTimeFormat)
// ecma-402/#sec-properties-of-intl-datetimeformat-instances
enum class DateTimeStyle { kUndefined, kFull, kLong, kMedium, kShort };
// Layout description.
#define JS_DATE_TIME_FORMAT_FIELDS(V) \
V(kICULocaleOffset, kTaggedSize) \
......@@ -92,8 +95,17 @@ class JSDateTimeFormat : public JSObject {
inline void set_hour_cycle(Intl::HourCycle hour_cycle);
inline Intl::HourCycle hour_cycle() const;
inline void set_date_style(DateTimeStyle date_style);
inline DateTimeStyle date_style() const;
inline void set_time_style(DateTimeStyle time_style);
inline DateTimeStyle time_style() const;
// Bit positions in |flags|.
#define FLAGS_BIT_FIELDS(V, _) V(HourCycleBits, Intl::HourCycle, 3, _)
#define FLAGS_BIT_FIELDS(V, _) \
V(HourCycleBits, Intl::HourCycle, 3, _) \
V(DateStyleBits, DateTimeStyle, 3, _) \
V(TimeStyleBits, DateTimeStyle, 3, _)
DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
#undef FLAGS_BIT_FIELDS
......@@ -104,6 +116,18 @@ class JSDateTimeFormat : public JSObject {
STATIC_ASSERT(Intl::HourCycle::kH23 <= HourCycleBits::kMax);
STATIC_ASSERT(Intl::HourCycle::kH24 <= HourCycleBits::kMax);
STATIC_ASSERT(DateTimeStyle::kUndefined <= DateStyleBits::kMax);
STATIC_ASSERT(DateTimeStyle::kFull <= DateStyleBits::kMax);
STATIC_ASSERT(DateTimeStyle::kLong <= DateStyleBits::kMax);
STATIC_ASSERT(DateTimeStyle::kMedium <= DateStyleBits::kMax);
STATIC_ASSERT(DateTimeStyle::kShort <= DateStyleBits::kMax);
STATIC_ASSERT(DateTimeStyle::kUndefined <= TimeStyleBits::kMax);
STATIC_ASSERT(DateTimeStyle::kFull <= TimeStyleBits::kMax);
STATIC_ASSERT(DateTimeStyle::kLong <= TimeStyleBits::kMax);
STATIC_ASSERT(DateTimeStyle::kMedium <= TimeStyleBits::kMax);
STATIC_ASSERT(DateTimeStyle::kShort <= TimeStyleBits::kMax);
DECL_ACCESSORS(icu_locale, Managed<icu::Locale>)
DECL_ACCESSORS(icu_simple_date_format, Managed<icu::SimpleDateFormat>)
DECL_ACCESSORS(bound_format, Object)
......
// Copyright 2019 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-datetime-style
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
let weekday = new Array();
let year = new Array();
let month = new Array();
let day = new Array();
let hour = new Array();
let minute = new Array();
let second = new Array();
let localeMatcher = new Array();
let hour12 = new Array();
let hourCycle = new Array();
let dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let timeZoneName = new Array();
let formatMatcher = new Array();
new Intl.DateTimeFormat(['en-US'], {
get weekday() {
weekday.push(++getCount);
},
get year() {
year.push(++getCount);
},
get month() {
month.push(++getCount);
},
get day() {
day.push(++getCount);
},
get hour() {
hour.push(++getCount);
},
get minute() {
minute.push(++getCount);
},
get second() {
second.push(++getCount);
},
get localeMatcher() {
localeMatcher.push(++getCount);
},
get hour12() {
hour12.push(++getCount);
},
get hourCycle() {
hourCycle.push(++getCount);
},
get timeZone() {
timeZone.push(++getCount);
},
get dateStyle() {
dateStyle.push(++getCount);
return "full";
},
get timeStyle() {
timeStyle.push(++getCount);
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
}
});
assertEquals(1, weekday.length);
assertEquals(1, weekday[0]);
assertEquals(1, year.length);
assertEquals(2, year[0]);
assertEquals(1, month.length);
assertEquals(3, month[0]);
assertEquals(1, day.length);
assertEquals(4, day[0]);
assertEquals(1, hour.length);
assertEquals(5, hour[0]);
assertEquals(1, minute.length);
assertEquals(6, minute[0]);
assertEquals(1, second.length);
assertEquals(7, second[0]);
assertEquals(1, localeMatcher.length);
assertEquals(8, localeMatcher[0]);
assertEquals(1, hour12.length);
assertEquals(9, hour12[0]);
assertEquals(1, hourCycle.length);
assertEquals(10, hourCycle[0]);
assertEquals(1, timeZone.length);
assertEquals(11, timeZone[0]);
assertEquals(1, dateStyle.length);
assertEquals(12, dateStyle[0]);
assertEquals(1, timeStyle.length);
assertEquals(13, timeStyle[0]);
assertEquals(0, era.length);
assertEquals(0, timeZoneName.length);
assertEquals(0, formatMatcher.length);
// Copyright 2019 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-datetime-style
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
let weekday = new Array();
let year = new Array();
let month = new Array();
let day = new Array();
let hour = new Array();
let minute = new Array();
let second = new Array();
let localeMatcher = new Array();
let hour12 = new Array();
let hourCycle = new Array();
let dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let timeZoneName = new Array();
let formatMatcher = new Array();
new Intl.DateTimeFormat(['en-US'], {
get weekday() {
weekday.push(++getCount);
},
get year() {
year.push(++getCount);
},
get month() {
month.push(++getCount);
},
get day() {
day.push(++getCount);
},
get hour() {
hour.push(++getCount);
},
get minute() {
minute.push(++getCount);
},
get second() {
second.push(++getCount);
},
get localeMatcher() {
localeMatcher.push(++getCount);
},
get hour12() {
hour12.push(++getCount);
},
get hourCycle() {
hourCycle.push(++getCount);
},
get timeZone() {
timeZone.push(++getCount);
},
get dateStyle() {
dateStyle.push(++getCount);
return "full";
},
get timeStyle() {
timeStyle.push(++getCount);
return "full";
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
}
});
assertEquals(1, weekday.length);
assertEquals(1, weekday[0]);
assertEquals(1, year.length);
assertEquals(2, year[0]);
assertEquals(1, month.length);
assertEquals(3, month[0]);
assertEquals(1, day.length);
assertEquals(4, day[0]);
assertEquals(1, hour.length);
assertEquals(5, hour[0]);
assertEquals(1, minute.length);
assertEquals(6, minute[0]);
assertEquals(1, second.length);
assertEquals(7, second[0]);
assertEquals(1, localeMatcher.length);
assertEquals(8, localeMatcher[0]);
assertEquals(1, hour12.length);
assertEquals(9, hour12[0]);
assertEquals(1, hourCycle.length);
assertEquals(10, hourCycle[0]);
assertEquals(1, timeZone.length);
assertEquals(11, timeZone[0]);
assertEquals(1, dateStyle.length);
assertEquals(12, dateStyle[0]);
assertEquals(1, timeStyle.length);
assertEquals(13, timeStyle[0]);
assertEquals(0, era.length);
assertEquals(0, timeZoneName.length);
assertEquals(0, formatMatcher.length);
// Copyright 2019 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-datetime-style
var validStyle = ["full", "long", "medium", "short", undefined];
var invalidStyle = ["narrow", "numeric"];
validStyle.forEach(function(dateStyle) {
validStyle.forEach(function(timeStyle) {
assertDoesNotThrow(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}));
});
invalidStyle.forEach(function(timeStyle) {
assertThrows(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}), RangeError);
});
}
);
invalidStyle.forEach(function(dateStyle) {
validStyle.forEach(function(timeStyle) {
assertThrows(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}), RangeError);
});
invalidStyle.forEach(function(timeStyle) {
assertThrows(() =>
new Intl.DateTimeFormat("en", {dateStyle, timeStyle}), RangeError);
});
}
);
// Copyright 2019 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-datetime-style
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
let weekday = new Array();
let year = new Array();
let month = new Array();
let day = new Array();
let hour = new Array();
let minute = new Array();
let second = new Array();
let localeMatcher = new Array();
let hour12 = new Array();
let hourCycle = new Array();
let dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let timeZoneName = new Array();
let formatMatcher = new Array();
new Intl.DateTimeFormat(['en-US'], {
get weekday() {
weekday.push(++getCount);
},
get year() {
year.push(++getCount);
},
get month() {
month.push(++getCount);
},
get day() {
day.push(++getCount);
},
get hour() {
hour.push(++getCount);
},
get minute() {
minute.push(++getCount);
},
get second() {
second.push(++getCount);
},
get localeMatcher() {
localeMatcher.push(++getCount);
},
get hour12() {
hour12.push(++getCount);
},
get hourCycle() {
hourCycle.push(++getCount);
},
get timeZone() {
timeZone.push(++getCount);
},
get dateStyle() {
dateStyle.push(++getCount);
},
get timeStyle() {
timeStyle.push(++getCount);
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
}
});
assertEquals(2, weekday.length);
assertEquals(1, weekday[0]);
assertEquals(1, year.length);
assertEquals(2, year[0]);
assertEquals(1, month.length);
assertEquals(3, month[0]);
assertEquals(1, day.length);
assertEquals(4, day[0]);
assertEquals(2, hour.length);
assertEquals(5, hour[0]);
assertEquals(2, minute.length);
assertEquals(6, minute[0]);
assertEquals(2, second.length);
assertEquals(7, second[0]);
assertEquals(1, localeMatcher.length);
assertEquals(8, localeMatcher[0]);
assertEquals(1, hour12.length);
assertEquals(9, hour12[0]);
assertEquals(1, hourCycle.length);
assertEquals(10, hourCycle[0]);
assertEquals(1, timeZone.length);
assertEquals(11, timeZone[0]);
assertEquals(1, dateStyle.length);
assertEquals(12, dateStyle[0]);
assertEquals(1, timeStyle.length);
assertEquals(13, timeStyle[0]);
assertEquals(14, weekday[1]);
assertEquals(1, era.length);
assertEquals(15, era[0]);
assertEquals(16, hour[1]);
assertEquals(17, minute[1]);
assertEquals(18, second[1]);
assertEquals(1, timeZoneName.length);
assertEquals(19, timeZoneName[0]);
assertEquals(1, formatMatcher.length);
assertEquals(20, formatMatcher[0]);
// Copyright 2019 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-datetime-style
// Throws only once during construction.
// Check for all getters to prevent regression.
// Preserve the order of getter initialization.
let getCount = 0;
let weekday = new Array();
let year = new Array();
let month = new Array();
let day = new Array();
let hour = new Array();
let minute = new Array();
let second = new Array();
let localeMatcher = new Array();
let hour12 = new Array();
let hourCycle = new Array();
let dateStyle = new Array();
let timeStyle = new Array();
let timeZone = new Array();
let era = new Array();
let timeZoneName = new Array();
let formatMatcher = new Array();
new Intl.DateTimeFormat(['en-US'], {
get weekday() {
weekday.push(++getCount);
},
get year() {
year.push(++getCount);
},
get month() {
month.push(++getCount);
},
get day() {
day.push(++getCount);
},
get hour() {
hour.push(++getCount);
},
get minute() {
minute.push(++getCount);
},
get second() {
second.push(++getCount);
},
get localeMatcher() {
localeMatcher.push(++getCount);
},
get hour12() {
hour12.push(++getCount);
},
get hourCycle() {
hourCycle.push(++getCount);
},
get timeZone() {
timeZone.push(++getCount);
},
get dateStyle() {
dateStyle.push(++getCount);
},
get timeStyle() {
timeStyle.push(++getCount);
return "full";
},
get era() {
era.push(++getCount);
},
get timeZoneName() {
timeZoneName.push(++getCount);
},
get formatMatcher() {
formatMatcher.push(++getCount);
}
});
assertEquals(1, weekday.length);
assertEquals(1, weekday[0]);
assertEquals(1, year.length);
assertEquals(2, year[0]);
assertEquals(1, month.length);
assertEquals(3, month[0]);
assertEquals(1, day.length);
assertEquals(4, day[0]);
assertEquals(1, hour.length);
assertEquals(5, hour[0]);
assertEquals(1, minute.length);
assertEquals(6, minute[0]);
assertEquals(1, second.length);
assertEquals(7, second[0]);
assertEquals(1, localeMatcher.length);
assertEquals(8, localeMatcher[0]);
assertEquals(1, hour12.length);
assertEquals(9, hour12[0]);
assertEquals(1, hourCycle.length);
assertEquals(10, hourCycle[0]);
assertEquals(1, timeZone.length);
assertEquals(11, timeZone[0]);
assertEquals(1, dateStyle.length);
assertEquals(12, dateStyle[0]);
assertEquals(1, timeStyle.length);
assertEquals(13, timeStyle[0]);
assertEquals(0, era.length);
assertEquals(0, timeZoneName.length);
assertEquals(0, formatMatcher.length);
// Copyright 2019 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-datetime-style
// Checks for security holes introduced by Object.property overrides.
// For example:
// Object.defineProperty(Array.prototype, 'locale', {
// set: function(value) {
// throw new Error('blah');
// },
// configurable: true,
// enumerable: false
// });
//
// would throw in case of (JS) x.locale = 'us' or (C++) x->Set('locale', 'us').
//
// First get supported properties.
// Some of the properties are optional, so we request them.
var properties = [];
var options = Intl.DateTimeFormat(
'en-US', {dateStyle: 'full'}).resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
// In the order of Table 6 of
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
var expectedProperties = [
'locale',
'calendar',
'numberingSystem',
'timeZone',
'hourCycle',
'hour12',
'weekday',
'year',
'month',
'day',
'dateStyle',
];
assertEquals(expectedProperties.length, properties.length);
properties.forEach(function(prop) {
assertFalse(expectedProperties.indexOf(prop) === -1);
});
taintProperties(properties);
var locale = Intl.DateTimeFormat().resolvedOptions().locale;
// Copyright 2019 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-datetime-style
// Checks for security holes introduced by Object.property overrides.
// For example:
// Object.defineProperty(Array.prototype, 'locale', {
// set: function(value) {
// throw new Error('blah');
// },
// configurable: true,
// enumerable: false
// });
//
// would throw in case of (JS) x.locale = 'us' or (C++) x->Set('locale', 'us').
// First get supported properties.
// Some of the properties are optional, so we request them.
var properties = [];
var options = Intl.DateTimeFormat(
'en-US', {dateStyle: 'full', timeStyle: 'full'}).resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
// In the order of Table 6 of
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
var expectedProperties = [
'locale',
'calendar',
'numberingSystem',
'timeZone',
'hourCycle',
'hour12',
'weekday',
'year',
'month',
'day',
'hour',
'minute',
'second',
'timeZoneName',
'dateStyle',
'timeStyle',
];
assertEquals(expectedProperties.length, properties.length);
properties.forEach(function(prop) {
assertFalse(expectedProperties.indexOf(prop) === -1);
});
taintProperties(properties);
var locale = Intl.DateTimeFormat().resolvedOptions().locale;
// Copyright 2019 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-datetime-style
// Checks for security holes introduced by Object.property overrides.
// For example:
// Object.defineProperty(Array.prototype, 'locale', {
// set: function(value) {
// throw new Error('blah');
// },
// configurable: true,
// enumerable: false
// });
//
// would throw in case of (JS) x.locale = 'us' or (C++) x->Set('locale', 'us').
// First get supported properties.
// Some of the properties are optional, so we request them.
var properties = [];
var options = Intl.DateTimeFormat(
'en-US', {timeStyle: 'full'}).resolvedOptions();
for (var prop in options) {
if (options.hasOwnProperty(prop)) {
properties.push(prop);
}
}
// In the order of Table 6 of
// ecma402 #sec-intl.datetimeformat.prototype.resolvedoptions
var expectedProperties = [
'locale',
'calendar',
'numberingSystem',
'timeZone',
'hourCycle',
'hour12',
'hour',
'minute',
'second',
'timeZoneName',
'timeStyle',
];
assertEquals(expectedProperties.length, properties.length);
properties.forEach(function(prop) {
assertFalse(expectedProperties.indexOf(prop) === -1);
});
taintProperties(properties);
var locale = Intl.DateTimeFormat().resolvedOptions().locale;
......@@ -308,44 +308,44 @@ KNOWN_MAPS = {
("RO_SPACE", 0x02821): (173, "Tuple2Map"),
("RO_SPACE", 0x028c1): (175, "ArrayBoilerplateDescriptionMap"),
("RO_SPACE", 0x02c01): (163, "InterceptorInfoMap"),
("RO_SPACE", 0x05099): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x050e9): (154, "AccessorInfoMap"),
("RO_SPACE", 0x05139): (155, "AccessorPairMap"),
("RO_SPACE", 0x05189): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x051d9): (157, "AllocationMementoMap"),
("RO_SPACE", 0x05229): (158, "AsmWasmDataMap"),
("RO_SPACE", 0x05279): (159, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x052c9): (160, "DebugInfoMap"),
("RO_SPACE", 0x05319): (161, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x05369): (162, "FunctionTemplateRareDataMap"),
("RO_SPACE", 0x053b9): (164, "InterpreterDataMap"),
("RO_SPACE", 0x05409): (165, "ModuleInfoEntryMap"),
("RO_SPACE", 0x05459): (166, "ModuleMap"),
("RO_SPACE", 0x054a9): (167, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x054f9): (168, "PromiseCapabilityMap"),
("RO_SPACE", 0x05549): (169, "PromiseReactionMap"),
("RO_SPACE", 0x05599): (170, "PrototypeInfoMap"),
("RO_SPACE", 0x055e9): (171, "ScriptMap"),
("RO_SPACE", 0x05639): (172, "StackFrameInfoMap"),
("RO_SPACE", 0x05689): (174, "Tuple3Map"),
("RO_SPACE", 0x056d9): (176, "WasmDebugInfoMap"),
("RO_SPACE", 0x05729): (177, "WasmExceptionTagMap"),
("RO_SPACE", 0x05779): (178, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x057c9): (179, "CallableTaskMap"),
("RO_SPACE", 0x05819): (180, "CallbackTaskMap"),
("RO_SPACE", 0x05869): (181, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x058b9): (182, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x05909): (183, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x05959): (184, "FinalizationGroupCleanupJobTaskMap"),
("RO_SPACE", 0x059a9): (185, "AllocationSiteWithWeakNextMap"),
("RO_SPACE", 0x059f9): (185, "AllocationSiteWithoutWeakNextMap"),
("RO_SPACE", 0x05a49): (219, "LoadHandler1Map"),
("RO_SPACE", 0x05a99): (219, "LoadHandler2Map"),
("RO_SPACE", 0x05ae9): (219, "LoadHandler3Map"),
("RO_SPACE", 0x05b39): (227, "StoreHandler0Map"),
("RO_SPACE", 0x05b89): (227, "StoreHandler1Map"),
("RO_SPACE", 0x05bd9): (227, "StoreHandler2Map"),
("RO_SPACE", 0x05c29): (227, "StoreHandler3Map"),
("RO_SPACE", 0x05109): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x05159): (154, "AccessorInfoMap"),
("RO_SPACE", 0x051a9): (155, "AccessorPairMap"),
("RO_SPACE", 0x051f9): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x05249): (157, "AllocationMementoMap"),
("RO_SPACE", 0x05299): (158, "AsmWasmDataMap"),
("RO_SPACE", 0x052e9): (159, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x05339): (160, "DebugInfoMap"),
("RO_SPACE", 0x05389): (161, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x053d9): (162, "FunctionTemplateRareDataMap"),
("RO_SPACE", 0x05429): (164, "InterpreterDataMap"),
("RO_SPACE", 0x05479): (165, "ModuleInfoEntryMap"),
("RO_SPACE", 0x054c9): (166, "ModuleMap"),
("RO_SPACE", 0x05519): (167, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x05569): (168, "PromiseCapabilityMap"),
("RO_SPACE", 0x055b9): (169, "PromiseReactionMap"),
("RO_SPACE", 0x05609): (170, "PrototypeInfoMap"),
("RO_SPACE", 0x05659): (171, "ScriptMap"),
("RO_SPACE", 0x056a9): (172, "StackFrameInfoMap"),
("RO_SPACE", 0x056f9): (174, "Tuple3Map"),
("RO_SPACE", 0x05749): (176, "WasmDebugInfoMap"),
("RO_SPACE", 0x05799): (177, "WasmExceptionTagMap"),
("RO_SPACE", 0x057e9): (178, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x05839): (179, "CallableTaskMap"),
("RO_SPACE", 0x05889): (180, "CallbackTaskMap"),
("RO_SPACE", 0x058d9): (181, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x05929): (182, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x05979): (183, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x059c9): (184, "FinalizationGroupCleanupJobTaskMap"),
("RO_SPACE", 0x05a19): (185, "AllocationSiteWithWeakNextMap"),
("RO_SPACE", 0x05a69): (185, "AllocationSiteWithoutWeakNextMap"),
("RO_SPACE", 0x05ab9): (219, "LoadHandler1Map"),
("RO_SPACE", 0x05b09): (219, "LoadHandler2Map"),
("RO_SPACE", 0x05b59): (219, "LoadHandler3Map"),
("RO_SPACE", 0x05ba9): (227, "StoreHandler0Map"),
("RO_SPACE", 0x05bf9): (227, "StoreHandler1Map"),
("RO_SPACE", 0x05c49): (227, "StoreHandler2Map"),
("RO_SPACE", 0x05c99): (227, "StoreHandler3Map"),
("MAP_SPACE", 0x00139): (1057, "ExternalMap"),
("MAP_SPACE", 0x00189): (1073, "JSMessageObjectMap"),
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment