Commit 41bc1cfd authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[Intl] Speed up Intl.NumberFormat constructor x4

1. Use the newer LocalizedNumberFormatter API which improve
   the performance score x3.3.
   Here are how I got the performance score:
  $ python -u tools/run_perf.py --binary-override-path \
    out/x64.release/d8 --filter "JSTests/Intl"  \
    test/js-perf-test/JSTests5.json

  Look for NewIntlNumberFormat-Intl(Score) for 3 runs.

  BEFORE: 539   507  507
   AFTER: 2009 2069 1994

2. Also add symbol and enum to prepare implementing of the unified
   number proposal.


Bug: v8:8515
Change-Id: Ie1ca1dba1e806449632cc96b81d44f0dc61b6093
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1392233
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarFrank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61421}
parent 55a7c6a5
......@@ -482,13 +482,14 @@ BUILTIN(NumberFormatInternalFormatNumber) {
Object::ToNumber(isolate, value));
}
icu::NumberFormat* icu_number_format =
number_format->icu_number_format()->raw();
CHECK_NOT_NULL(icu_number_format);
icu::number::LocalizedNumberFormatter* icu_localized_number_formatter =
number_format->icu_number_formatter()->raw();
CHECK_NOT_NULL(icu_localized_number_formatter);
// Return FormatNumber(nf, x).
RETURN_RESULT_OR_FAILURE(
isolate,
JSNumberFormat::FormatNumeric(isolate, *icu_number_format, numeric_obj));
isolate, JSNumberFormat::FormatNumeric(
isolate, *icu_localized_number_formatter, numeric_obj));
}
BUILTIN(DateTimeFormatConstructor) {
......
......@@ -9,20 +9,30 @@
#define INTERNALIZED_STRING_LIST_GENERATOR_INTL(V, _) \
V(_, adoptText_string, "adoptText") \
V(_, baseName_string, "baseName") \
V(_, accounting_string, "accounting") \
V(_, breakType_string, "breakType") \
V(_, calendar_string, "calendar") \
V(_, cardinal_string, "cardinal") \
V(_, caseFirst_string, "caseFirst") \
V(_, compare_string, "compare") \
V(_, current_string, "current") \
V(_, collation_string, "collation") \
V(_, compact_string, "compact") \
V(_, currency_string, "currency") \
V(_, currencyDisplay_string, "currencyDisplay") \
V(_, dateStyle_string, "dateStyle") \
V(_, day_string, "day") \
V(_, dayPeriod_string, "dayPeriod") \
V(_, decimal_string, "decimal") \
V(_, endRange_string, "endRange") \
V(_, engineering_string, "engineering") \
V(_, era_string, "era") \
V(_, first_string, "first") \
V(_, format_string, "format") \
V(_, except_zero_string, "except-zero") \
V(_, exponentInteger_string, "exponentInteger") \
V(_, exponentMinusSign_string, "exponentMinusSign") \
V(_, exponentSeparator_string, "exponentSeparator") \
V(_, fraction_string, "fraction") \
V(_, full_string, "full") \
V(_, granularity_string, "granularity") \
......@@ -35,9 +45,6 @@
V(_, hour_string, "hour") \
V(_, hour12_string, "hour12") \
V(_, hourCycle_string, "hourCycle") \
V(_, collation_string, "collation") \
V(_, currency_string, "currency") \
V(_, currencyDisplay_string, "currencyDisplay") \
V(_, ideo_string, "ideo") \
V(_, ignorePunctuation_string, "ignorePunctuation") \
V(_, Invalid_Date_string, "Invalid Date") \
......@@ -59,6 +66,8 @@
V(_, minute_string, "minute") \
V(_, month_string, "month") \
V(_, nan_string, "nan") \
V(_, narrow_symbol_string, "narrow-symbol") \
V(_, never_string, "never") \
V(_, none_string, "none") \
V(_, normal_string, "normal") \
V(_, numberingSystem_string, "numberingSystem") \
......@@ -68,12 +77,14 @@
V(_, plusSign_string, "plusSign") \
V(_, quarter_string, "quarter") \
V(_, region_string, "region") \
V(_, scientific_string, "scientific") \
V(_, second_string, "second") \
V(_, segment_string, "segment") \
V(_, SegmentIterator_string, "Segment Iterator") \
V(_, sensitivity_string, "sensitivity") \
V(_, sep_string, "sep") \
V(_, shared_string, "shared") \
V(_, standard_string, "standard") \
V(_, startRange_string, "startRange") \
V(_, strict_string, "strict") \
V(_, style_string, "style") \
......
......@@ -4626,12 +4626,12 @@ void Isolate::SetIdle(bool is_idle) {
}
#ifdef V8_INTL_SUPPORT
icu::UObject* Isolate::get_cached_icu_object(ICUObjectCacheType cache_type) {
icu::UMemory* Isolate::get_cached_icu_object(ICUObjectCacheType cache_type) {
return icu_object_cache_[cache_type].get();
}
void Isolate::set_icu_object_in_cache(ICUObjectCacheType cache_type,
std::shared_ptr<icu::UObject> obj) {
std::shared_ptr<icu::UMemory> obj) {
icu_object_cache_[cache_type] = obj;
}
......
......@@ -38,7 +38,7 @@
#ifdef V8_INTL_SUPPORT
#include "unicode/uversion.h" // Define U_ICU_NAMESPACE.
namespace U_ICU_NAMESPACE {
class UObject;
class UMemory;
} // namespace U_ICU_NAMESPACE
#endif // V8_INTL_SUPPORT
......@@ -1143,9 +1143,9 @@ class Isolate final : private HiddenFactory {
kDefaultCollator, kDefaultNumberFormat, kDefaultSimpleDateFormat,
kDefaultSimpleDateFormatForTime, kDefaultSimpleDateFormatForDate};
icu::UObject* get_cached_icu_object(ICUObjectCacheType cache_type);
icu::UMemory* get_cached_icu_object(ICUObjectCacheType cache_type);
void set_icu_object_in_cache(ICUObjectCacheType cache_type,
std::shared_ptr<icu::UObject> obj);
std::shared_ptr<icu::UMemory> obj);
void clear_cached_icu_object(ICUObjectCacheType cache_type);
#endif // V8_INTL_SUPPORT
......@@ -1709,7 +1709,7 @@ class Isolate final : private HiddenFactory {
return static_cast<std::size_t>(a);
}
};
std::unordered_map<ICUObjectCacheType, std::shared_ptr<icu::UObject>,
std::unordered_map<ICUObjectCacheType, std::shared_ptr<icu::UMemory>,
ICUObjectCacheTypeHash>
icu_object_cache_;
......
......@@ -2268,7 +2268,7 @@ void JSNumberFormat::JSNumberFormatVerify(Isolate* isolate) {
CHECK(IsJSNumberFormat());
JSObjectVerify(isolate);
VerifyObjectField(isolate, kLocaleOffset);
VerifyObjectField(isolate, kIcuNumberFormatOffset);
VerifyObjectField(isolate, kIcuNumberFormatterOffset);
VerifyObjectField(isolate, kBoundFormatOffset);
CHECK(bound_format()->IsUndefined(isolate) || bound_format()->IsJSFunction());
VerifySmiField(kFlagsOffset);
......
......@@ -2164,10 +2164,8 @@ void JSLocale::JSLocalePrint(std::ostream& os) { // NOLINT
void JSNumberFormat::JSNumberFormatPrint(std::ostream& os) { // NOLINT
JSObjectPrintHeader(os, *this, "JSNumberFormat");
os << "\n - locale: " << Brief(locale());
os << "\n - icu_number_format: " << Brief(icu_number_format());
os << "\n - icu_number_formatter: " << Brief(icu_number_formatter());
os << "\n - bound_format: " << Brief(bound_format());
os << "\n - style: " << StyleAsString();
os << "\n - currency_display: " << CurrencyDisplayAsString();
JSObjectPrintBody(os, *this);
}
......
......@@ -977,7 +977,7 @@ MaybeHandle<Object> Intl::StringLocaleCompare(Isolate* isolate,
if (can_cache) {
isolate->set_icu_object_in_cache(
Isolate::ICUObjectCacheType::kDefaultCollator,
std::static_pointer_cast<icu::UObject>(
std::static_pointer_cast<icu::UMemory>(
collator->icu_collator()->get()));
}
icu::Collator* icu_collator = collator->icu_collator()->raw();
......@@ -1039,9 +1039,10 @@ MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate,
bool can_cache =
locales->IsUndefined(isolate) && options->IsUndefined(isolate);
if (can_cache) {
icu::NumberFormat* cached_number_format =
static_cast<icu::NumberFormat*>(isolate->get_cached_icu_object(
Isolate::ICUObjectCacheType::kDefaultNumberFormat));
icu::number::LocalizedNumberFormatter* cached_number_format =
static_cast<icu::number::LocalizedNumberFormatter*>(
isolate->get_cached_icu_object(
Isolate::ICUObjectCacheType::kDefaultNumberFormat));
// We may use the cached icu::NumberFormat for a fast path.
if (cached_number_format != nullptr) {
return JSNumberFormat::FormatNumeric(isolate, *cached_number_format,
......@@ -1062,13 +1063,13 @@ MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate,
if (can_cache) {
isolate->set_icu_object_in_cache(
Isolate::ICUObjectCacheType::kDefaultNumberFormat,
std::static_pointer_cast<icu::UObject>(
number_format->icu_number_format()->get()));
std::static_pointer_cast<icu::UMemory>(
number_format->icu_number_formatter()->get()));
}
// Return FormatNumber(numberFormat, x).
icu::NumberFormat* icu_number_format =
number_format->icu_number_format()->raw();
icu::number::LocalizedNumberFormatter* icu_number_format =
number_format->icu_number_formatter()->raw();
return JSNumberFormat::FormatNumeric(isolate, *icu_number_format,
numeric_obj);
}
......@@ -1130,19 +1131,17 @@ Maybe<int> GetNumberOption(Isolate* isolate, Handle<JSReceiver> options,
} // namespace
Maybe<bool> Intl::SetNumberFormatDigitOptions(Isolate* isolate,
icu::DecimalFormat* number_format,
Handle<JSReceiver> options,
int mnfd_default,
int mxfd_default) {
CHECK_NOT_NULL(number_format);
Maybe<Intl::NumberFormatDigitOptions> Intl::SetNumberFormatDigitOptions(
Isolate* isolate, Handle<JSReceiver> options, int mnfd_default,
int mxfd_default) {
Intl::NumberFormatDigitOptions digit_options;
// 5. Let mnid be ? GetNumberOption(options, "minimumIntegerDigits,", 1, 21,
// 1).
int mnid;
if (!GetNumberOption(isolate, options, "minimumIntegerDigits", 1, 21, 1)
.To(&mnid)) {
return Nothing<bool>();
return Nothing<NumberFormatDigitOptions>();
}
// 6. Let mnfd be ? GetNumberOption(options, "minimumFractionDigits", 0, 20,
......@@ -1151,7 +1150,7 @@ Maybe<bool> Intl::SetNumberFormatDigitOptions(Isolate* isolate,
if (!GetNumberOption(isolate, options, "minimumFractionDigits", 0, 20,
mnfd_default)
.To(&mnfd)) {
return Nothing<bool>();
return Nothing<NumberFormatDigitOptions>();
}
// 7. Let mxfdActualDefault be max( mnfd, mxfdDefault ).
......@@ -1163,7 +1162,7 @@ Maybe<bool> Intl::SetNumberFormatDigitOptions(Isolate* isolate,
if (!GetNumberOption(isolate, options, "maximumFractionDigits", mnfd, 20,
mxfd_actual_default)
.To(&mxfd)) {
return Nothing<bool>();
return Nothing<NumberFormatDigitOptions>();
}
// 9. Let mnsd be ? Get(options, "minimumSignificantDigits").
......@@ -1172,7 +1171,7 @@ Maybe<bool> Intl::SetNumberFormatDigitOptions(Isolate* isolate,
isolate->factory()->minimumSignificantDigits_string();
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, mnsd_obj, JSReceiver::GetProperty(isolate, options, mnsd_str),
Nothing<bool>());
Nothing<NumberFormatDigitOptions>());
// 10. Let mxsd be ? Get(options, "maximumSignificantDigits").
Handle<Object> mxsd_obj;
......@@ -1180,45 +1179,43 @@ Maybe<bool> Intl::SetNumberFormatDigitOptions(Isolate* isolate,
isolate->factory()->maximumSignificantDigits_string();
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, mxsd_obj, JSReceiver::GetProperty(isolate, options, mxsd_str),
Nothing<bool>());
Nothing<NumberFormatDigitOptions>());
// 11. Set intlObj.[[MinimumIntegerDigits]] to mnid.
number_format->setMinimumIntegerDigits(mnid);
digit_options.minimum_integer_digits = mnid;
// 12. Set intlObj.[[MinimumFractionDigits]] to mnfd.
number_format->setMinimumFractionDigits(mnfd);
digit_options.minimum_fraction_digits = mnfd;
// 13. Set intlObj.[[MaximumFractionDigits]] to mxfd.
number_format->setMaximumFractionDigits(mxfd);
digit_options.maximum_fraction_digits = mxfd;
bool significant_digits_used = false;
// 14. If mnsd is not undefined or mxsd is not undefined, then
if (!mnsd_obj->IsUndefined(isolate) || !mxsd_obj->IsUndefined(isolate)) {
// 14. a. Let mnsd be ? DefaultNumberOption(mnsd, 1, 21, 1).
int mnsd;
if (!DefaultNumberOption(isolate, mnsd_obj, 1, 21, 1, mnsd_str).To(&mnsd)) {
return Nothing<bool>();
return Nothing<NumberFormatDigitOptions>();
}
// 14. b. Let mxsd be ? DefaultNumberOption(mxsd, mnsd, 21, 21).
int mxsd;
if (!DefaultNumberOption(isolate, mxsd_obj, mnsd, 21, 21, mxsd_str)
.To(&mxsd)) {
return Nothing<bool>();
return Nothing<NumberFormatDigitOptions>();
}
significant_digits_used = true;
// 14. c. Set intlObj.[[MinimumSignificantDigits]] to mnsd.
number_format->setMinimumSignificantDigits(mnsd);
digit_options.minimum_significant_digits = mnsd;
// 14. d. Set intlObj.[[MaximumSignificantDigits]] to mxsd.
number_format->setMaximumSignificantDigits(mxsd);
digit_options.maximum_significant_digits = mxsd;
} else {
digit_options.minimum_significant_digits = 0;
digit_options.maximum_significant_digits = 0;
}
number_format->setSignificantDigitsUsed(significant_digits_used);
number_format->setRoundingMode(icu::DecimalFormat::kRoundHalfUp);
return Just(true);
return Just(digit_options);
}
namespace {
......@@ -1972,6 +1969,11 @@ Handle<String> Intl::NumberFieldToType(Isolate* isolate,
UNREACHABLE();
return Handle<String>();
case UNUM_COMPACT_FIELD:
return isolate->factory()->compact_string();
case UNUM_MEASURE_UNIT_FIELD:
return isolate->factory()->unit_string();
default:
UNREACHABLE();
return Handle<String>();
......
......@@ -25,11 +25,10 @@
namespace U_ICU_NAMESPACE {
class BreakIterator;
class Collator;
class DecimalFormat;
class FormattedValue;
class SimpleDateFormat;
class UnicodeString;
}
} // namespace U_ICU_NAMESPACE
namespace v8 {
namespace internal {
......@@ -172,9 +171,16 @@ class Intl {
Handle<Object> options);
// ecma402/#sec-setnfdigitoptions
V8_WARN_UNUSED_RESULT static Maybe<bool> SetNumberFormatDigitOptions(
Isolate* isolate, icu::DecimalFormat* number_format,
Handle<JSReceiver> options, int mnfd_default, int mxfd_default);
struct NumberFormatDigitOptions {
int minimum_integer_digits;
int minimum_fraction_digits;
int maximum_fraction_digits;
int minimum_significant_digits;
int maximum_significant_digits;
};
V8_WARN_UNUSED_RESULT static Maybe<NumberFormatDigitOptions>
SetNumberFormatDigitOptions(Isolate* isolate, Handle<JSReceiver> options,
int mnfd_default, int mxfd_default);
static icu::Locale CreateICULocale(const std::string& bcp47_locale);
......
......@@ -28,7 +28,8 @@ extern class JSListFormat extends JSObject {
extern class JSNumberFormat extends JSObject {
locale: String;
icu_number_format: Foreign; // Managed<icu::NumberFormat>
icu_number_formatter:
Foreign; // Managed<icu::number::LocalizedNumberFormatter>
bound_format: JSFunction | Undefined;
flags: Smi;
}
......
......@@ -658,7 +658,7 @@ MaybeHandle<String> JSDateTimeFormat::ToLocaleDateTime(
if (can_cache) {
isolate->set_icu_object_in_cache(
cache_type, std::static_pointer_cast<icu::UObject>(
cache_type, std::static_pointer_cast<icu::UMemory>(
date_time_format->icu_simple_date_format()->get()));
}
// 5. Return FormatDateTime(dateFormat, x).
......
......@@ -21,35 +21,51 @@ namespace internal {
OBJECT_CONSTRUCTORS_IMPL(JSNumberFormat, JSObject)
ACCESSORS(JSNumberFormat, locale, String, kLocaleOffset)
ACCESSORS(JSNumberFormat, icu_number_format, Managed<icu::NumberFormat>,
kIcuNumberFormatOffset)
ACCESSORS(JSNumberFormat, icu_number_formatter,
Managed<icu::number::LocalizedNumberFormatter>,
kIcuNumberFormatterOffset)
ACCESSORS(JSNumberFormat, bound_format, Object, kBoundFormatOffset)
// Currenct ECMA 402 spec mandate to record (Min|Max)imumFractionDigits
// uncondictionally while the unified number proposal eventually will only
// record either (Min|Max)imumFractionDigits or (Min|Max)imumSignaficantDigits
// Since LocalizedNumberFormatter can only remember one set, and during
// 2019-1-17 ECMA402 meeting that the committee decide not to take a PR to
// address that prior to the unified number proposal, we have to add these two
// 5 bits int into flags to remember the (Min|Max)imumFractionDigits while
// (Min|Max)imumSignaficantDigits is present.
// TODO(ftang) remove the following once we ship int-number-format-unified
// * SMI_ACCESSORS of flags
// * Four inline functions: (set_)?(min|max)imum_fraction_digits
SMI_ACCESSORS(JSNumberFormat, flags, kFlagsOffset)
inline void JSNumberFormat::set_style(Style style) {
DCHECK_LT(style, Style::COUNT);
inline int JSNumberFormat::minimum_fraction_digits() const {
return MinimumFractionDigitsBits::decode(flags());
}
inline void JSNumberFormat::set_minimum_fraction_digits(int digits) {
DCHECK_GE(MinimumFractionDigitsBits::kMax, digits);
DCHECK_LE(0, digits);
DCHECK_GE(20, digits);
int hints = flags();
hints = StyleBits::update(hints, style);
hints = MinimumFractionDigitsBits::update(hints, digits);
set_flags(hints);
}
inline JSNumberFormat::Style JSNumberFormat::style() const {
return StyleBits::decode(flags());
inline int JSNumberFormat::maximum_fraction_digits() const {
return MaximumFractionDigitsBits::decode(flags());
}
inline void JSNumberFormat::set_currency_display(
CurrencyDisplay currency_display) {
DCHECK_LT(currency_display, CurrencyDisplay::COUNT);
inline void JSNumberFormat::set_maximum_fraction_digits(int digits) {
DCHECK_GE(MaximumFractionDigitsBits::kMax, digits);
DCHECK_LE(0, digits);
DCHECK_GE(20, digits);
int hints = flags();
hints = CurrencyDisplayBits::update(hints, currency_display);
hints = MaximumFractionDigitsBits::update(hints, digits);
set_flags(hints);
}
inline JSNumberFormat::CurrencyDisplay JSNumberFormat::currency_display()
const {
return CurrencyDisplayBits::decode(flags());
}
CAST_ACCESSOR(JSNumberFormat)
} // namespace internal
......
This diff is collapsed.
......@@ -17,12 +17,14 @@
#include "src/objects.h"
#include "src/objects/intl-objects.h"
#include "src/objects/managed.h"
#include "unicode/numberformatter.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace U_ICU_NAMESPACE {
class NumberFormat;
class UnicodeString;
} // namespace U_ICU_NAMESPACE
namespace v8 {
......@@ -47,78 +49,55 @@ class JSNumberFormat : public JSObject {
Isolate* isolate, Handle<JSNumberFormat> number_format,
Handle<Object> numeric_obj);
// A utility function used by the above JSNumberFormat::FormatToParts()
// and JSRelativeTimeFormat::FormatToParts().
// Format the number by using the icu::NumberFormat to get the field
// information. It add an object into the result array, starting from the
// start_index and return the total number of elements in the result array.
// For each object added as element, it set the substring of the field as
// "value", the field type as "type". If the unit is not null, it also set
// unit as "unit" to each added object.
V8_WARN_UNUSED_RESULT static Maybe<int> FormatToParts(
Isolate* isolate, Handle<JSArray> result, int start_index,
const icu::NumberFormat& fmt, Handle<Object> numeric_obj,
Handle<String> unit);
V8_WARN_UNUSED_RESULT static MaybeHandle<String> FormatNumeric(
Isolate* isolate, const icu::NumberFormat& number_format,
Isolate* isolate,
const icu::number::LocalizedNumberFormatter& number_format,
Handle<Object> numeric_obj);
V8_EXPORT_PRIVATE static const std::set<std::string>& GetAvailableLocales();
Handle<String> StyleAsString() const;
Handle<String> CurrencyDisplayAsString() const;
DECL_CAST(JSNumberFormat)
DECL_PRINTER(JSNumberFormat)
DECL_VERIFIER(JSNumberFormat)
// [[Style]] is one of the values "decimal", "percent" or "currency",
// identifying the style of the number format.
enum class Style {
DECIMAL,
PERCENT,
CURRENCY,
COUNT
};
inline void set_style(Style style);
inline Style style() const;
// [[CurrencyDisplay]] is one of the values "code", "symbol" or "name",
// identifying the display of the currency number format.
enum class CurrencyDisplay {
CODE,
SYMBOL,
NAME,
COUNT
};
inline void set_currency_display(CurrencyDisplay currency_display);
inline CurrencyDisplay currency_display() const;
// Layout description.
// Current ECMA 402 spec mandates to record (Min|Max)imumFractionDigits
// unconditionally while the unified number proposal eventually will only
// record either (Min|Max)imumFractionDigits or (Min|Max)imumSignaficantDigits
// Since LocalizedNumberFormatter can only remember one set, and during
// 2019-1-17 ECMA402 meeting that the committee decide not to take a PR to
// address that prior to the unified number proposal, we have to add these two
// 5 bits int into flags to remember the (Min|Max)imumFractionDigits while
// (Min|Max)imumSignaficantDigits is present.
// TODO(ftang) remove the following once we ship int-number-format-unified
// * Four inline functions: (set_)?(min|max)imum_fraction_digits
// * kFlagsOffset
// * #define FLAGS_BIT_FIELDS
// * DECL_INT_ACCESSORS(flags)
inline int minimum_fraction_digits() const;
inline void set_minimum_fraction_digits(int digits);
inline int maximum_fraction_digits() const;
inline void set_maximum_fraction_digits(int digits);
// Layout description.
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
TORQUE_GENERATED_JSNUMBER_FORMAT_FIELDS)
// Bit positions in |flags|.
#define FLAGS_BIT_FIELDS(V, _) \
V(StyleBits, Style, 2, _) \
V(CurrencyDisplayBits, CurrencyDisplay, 2, _)
#define FLAGS_BIT_FIELDS(V, _) \
V(MinimumFractionDigitsBits, int, 5, _) \
V(MaximumFractionDigitsBits, int, 5, _)
DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
#undef FLAGS_BIT_FIELDS
STATIC_ASSERT(Style::DECIMAL <= StyleBits::kMax);
STATIC_ASSERT(Style::PERCENT <= StyleBits::kMax);
STATIC_ASSERT(Style::CURRENCY <= StyleBits::kMax);
STATIC_ASSERT(CurrencyDisplay::CODE <= CurrencyDisplayBits::kMax);
STATIC_ASSERT(CurrencyDisplay::SYMBOL <= CurrencyDisplayBits::kMax);
STATIC_ASSERT(CurrencyDisplay::NAME <= CurrencyDisplayBits::kMax);
STATIC_ASSERT(20 <= MinimumFractionDigitsBits::kMax);
STATIC_ASSERT(20 <= MaximumFractionDigitsBits::kMax);
DECL_ACCESSORS(locale, String)
DECL_ACCESSORS(icu_number_format, Managed<icu::NumberFormat>)
DECL_ACCESSORS(icu_number_formatter,
Managed<icu::number::LocalizedNumberFormatter>)
DECL_ACCESSORS(bound_format, Object)
DECL_INT_ACCESSORS(flags)
......
......@@ -164,9 +164,24 @@ MaybeHandle<JSPluralRules> JSPluralRules::Initialize(
CHECK_NOT_NULL(icu_decimal_format.get());
// 9. Perform ? SetNumberFormatDigitOptions(pluralRules, options, 0, 3).
Maybe<bool> done = Intl::SetNumberFormatDigitOptions(
isolate, icu_decimal_format.get(), options, 0, 3);
MAYBE_RETURN(done, MaybeHandle<JSPluralRules>());
Maybe<Intl::NumberFormatDigitOptions> maybe_digit_options =
Intl::SetNumberFormatDigitOptions(isolate, options, 0, 3);
MAYBE_RETURN(maybe_digit_options, MaybeHandle<JSPluralRules>());
Intl::NumberFormatDigitOptions digit_options = maybe_digit_options.FromJust();
icu_decimal_format->setRoundingMode(icu::DecimalFormat::kRoundHalfUp);
icu_decimal_format->setMinimumIntegerDigits(
digit_options.minimum_integer_digits);
icu_decimal_format->setMinimumFractionDigits(
digit_options.minimum_fraction_digits);
icu_decimal_format->setMaximumFractionDigits(
digit_options.maximum_fraction_digits);
if (digit_options.minimum_significant_digits > 0) {
icu_decimal_format->setMinimumSignificantDigits(
digit_options.minimum_significant_digits);
icu_decimal_format->setMaximumSignificantDigits(
digit_options.maximum_significant_digits);
}
Handle<Managed<icu::PluralRules>> managed_plural_rules =
Managed<icu::PluralRules>::FromUniquePtr(isolate, 0,
......
......@@ -22,6 +22,7 @@
#include "src/objects/object-macros.h"
namespace U_ICU_NAMESPACE {
class DecimalFormat;
class PluralRules;
} // namespace U_ICU_NAMESPACE
......
......@@ -306,49 +306,49 @@ KNOWN_MAPS = {
("read_only_space", 0x014b9): (98, "EnumCacheMap"),
("read_only_space", 0x01509): (115, "ArrayBoilerplateDescriptionMap"),
("read_only_space", 0x016e1): (101, "InterceptorInfoMap"),
("read_only_space", 0x03445): (89, "AccessCheckInfoMap"),
("read_only_space", 0x0346d): (90, "AccessorInfoMap"),
("read_only_space", 0x03495): (91, "AccessorPairMap"),
("read_only_space", 0x034bd): (92, "AliasedArgumentsEntryMap"),
("read_only_space", 0x034e5): (93, "AllocationMementoMap"),
("read_only_space", 0x0350d): (94, "AsmWasmDataMap"),
("read_only_space", 0x03535): (95, "AsyncGeneratorRequestMap"),
("read_only_space", 0x0355d): (96, "ClassPositionsMap"),
("read_only_space", 0x03585): (97, "DebugInfoMap"),
("read_only_space", 0x035ad): (99, "FunctionTemplateInfoMap"),
("read_only_space", 0x035d5): (100, "FunctionTemplateRareDataMap"),
("read_only_space", 0x035fd): (102, "InterpreterDataMap"),
("read_only_space", 0x03625): (103, "ModuleInfoEntryMap"),
("read_only_space", 0x0364d): (104, "ModuleMap"),
("read_only_space", 0x03675): (105, "ObjectTemplateInfoMap"),
("read_only_space", 0x0369d): (106, "PromiseCapabilityMap"),
("read_only_space", 0x036c5): (107, "PromiseReactionMap"),
("read_only_space", 0x036ed): (108, "PrototypeInfoMap"),
("read_only_space", 0x03715): (109, "ScriptMap"),
("read_only_space", 0x0373d): (110, "SourcePositionTableWithFrameCacheMap"),
("read_only_space", 0x03765): (111, "StackFrameInfoMap"),
("read_only_space", 0x0378d): (112, "StackTraceFrameMap"),
("read_only_space", 0x037b5): (113, "Tuple2Map"),
("read_only_space", 0x037dd): (114, "Tuple3Map"),
("read_only_space", 0x03805): (116, "WasmCapiFunctionDataMap"),
("read_only_space", 0x0382d): (117, "WasmDebugInfoMap"),
("read_only_space", 0x03855): (118, "WasmExceptionTagMap"),
("read_only_space", 0x0387d): (119, "WasmExportedFunctionDataMap"),
("read_only_space", 0x038a5): (120, "CallableTaskMap"),
("read_only_space", 0x038cd): (121, "CallbackTaskMap"),
("read_only_space", 0x038f5): (122, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x0391d): (123, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x03945): (124, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x0396d): (125, "FinalizationGroupCleanupJobTaskMap"),
("read_only_space", 0x03995): (126, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x039bd): (126, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x039e5): (161, "LoadHandler1Map"),
("read_only_space", 0x03a0d): (161, "LoadHandler2Map"),
("read_only_space", 0x03a35): (161, "LoadHandler3Map"),
("read_only_space", 0x03a5d): (169, "StoreHandler0Map"),
("read_only_space", 0x03a85): (169, "StoreHandler1Map"),
("read_only_space", 0x03aad): (169, "StoreHandler2Map"),
("read_only_space", 0x03ad5): (169, "StoreHandler3Map"),
("read_only_space", 0x03559): (89, "AccessCheckInfoMap"),
("read_only_space", 0x03581): (90, "AccessorInfoMap"),
("read_only_space", 0x035a9): (91, "AccessorPairMap"),
("read_only_space", 0x035d1): (92, "AliasedArgumentsEntryMap"),
("read_only_space", 0x035f9): (93, "AllocationMementoMap"),
("read_only_space", 0x03621): (94, "AsmWasmDataMap"),
("read_only_space", 0x03649): (95, "AsyncGeneratorRequestMap"),
("read_only_space", 0x03671): (96, "ClassPositionsMap"),
("read_only_space", 0x03699): (97, "DebugInfoMap"),
("read_only_space", 0x036c1): (99, "FunctionTemplateInfoMap"),
("read_only_space", 0x036e9): (100, "FunctionTemplateRareDataMap"),
("read_only_space", 0x03711): (102, "InterpreterDataMap"),
("read_only_space", 0x03739): (103, "ModuleInfoEntryMap"),
("read_only_space", 0x03761): (104, "ModuleMap"),
("read_only_space", 0x03789): (105, "ObjectTemplateInfoMap"),
("read_only_space", 0x037b1): (106, "PromiseCapabilityMap"),
("read_only_space", 0x037d9): (107, "PromiseReactionMap"),
("read_only_space", 0x03801): (108, "PrototypeInfoMap"),
("read_only_space", 0x03829): (109, "ScriptMap"),
("read_only_space", 0x03851): (110, "SourcePositionTableWithFrameCacheMap"),
("read_only_space", 0x03879): (111, "StackFrameInfoMap"),
("read_only_space", 0x038a1): (112, "StackTraceFrameMap"),
("read_only_space", 0x038c9): (113, "Tuple2Map"),
("read_only_space", 0x038f1): (114, "Tuple3Map"),
("read_only_space", 0x03919): (116, "WasmCapiFunctionDataMap"),
("read_only_space", 0x03941): (117, "WasmDebugInfoMap"),
("read_only_space", 0x03969): (118, "WasmExceptionTagMap"),
("read_only_space", 0x03991): (119, "WasmExportedFunctionDataMap"),
("read_only_space", 0x039b9): (120, "CallableTaskMap"),
("read_only_space", 0x039e1): (121, "CallbackTaskMap"),
("read_only_space", 0x03a09): (122, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x03a31): (123, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x03a59): (124, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x03a81): (125, "FinalizationGroupCleanupJobTaskMap"),
("read_only_space", 0x03aa9): (126, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x03ad1): (126, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x03af9): (161, "LoadHandler1Map"),
("read_only_space", 0x03b21): (161, "LoadHandler2Map"),
("read_only_space", 0x03b49): (161, "LoadHandler3Map"),
("read_only_space", 0x03b71): (169, "StoreHandler0Map"),
("read_only_space", 0x03b99): (169, "StoreHandler1Map"),
("read_only_space", 0x03bc1): (169, "StoreHandler2Map"),
("read_only_space", 0x03be9): (169, "StoreHandler3Map"),
("map_space", 0x00141): (1057, "ExternalMap"),
("map_space", 0x00169): (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