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

[Intl] move getNumberOption + defaultNumberOption to C++

Bug: v8:7979
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: Ic30da6f85b49fd34ee58faf253d9e976a460153c
Reviewed-on: https://chromium-review.googlesource.com/1150873Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54794}
parent fbbf85b6
...@@ -1053,42 +1053,21 @@ DEFINE_METHOD( ...@@ -1053,42 +1053,21 @@ DEFINE_METHOD(
} }
); );
function defaultNumberOption(value, min, max, fallback, property) {
if (!IS_UNDEFINED(value)) {
value = TO_NUMBER(value);
if (NUMBER_IS_NAN(value) || value < min || value > max) {
throw %make_range_error(kPropertyValueOutOfRange, property);
}
return %math_floor(value);
}
return fallback;
}
/**
* Returns the valid digit count for a property, or throws RangeError on
* a value out of the range.
*/
function getNumberOption(options, property, min, max, fallback) {
var value = options[property];
return defaultNumberOption(value, min, max, fallback, property);
}
// ECMA 402 #sec-setnfdigitoptions // ECMA 402 #sec-setnfdigitoptions
// SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault ) // SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault )
function SetNumberFormatDigitOptions(internalOptions, options, function SetNumberFormatDigitOptions(internalOptions, options,
mnfdDefault, mxfdDefault) { mnfdDefault, mxfdDefault) {
// Digit ranges. // Digit ranges.
var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1); var mnid = %GetNumberOption(options, 'minimumIntegerDigits', 1, 21, 1);
%DefineWEProperty(internalOptions, 'minimumIntegerDigits', mnid); %DefineWEProperty(internalOptions, 'minimumIntegerDigits', mnid);
var mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, var mnfd = %GetNumberOption(options, 'minimumFractionDigits', 0, 20,
mnfdDefault); mnfdDefault);
%DefineWEProperty(internalOptions, 'minimumFractionDigits', mnfd); %DefineWEProperty(internalOptions, 'minimumFractionDigits', mnfd);
var mxfdActualDefault = MathMax(mnfd, mxfdDefault); var mxfdActualDefault = MathMax(mnfd, mxfdDefault);
var mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, var mxfd = %GetNumberOption(options, 'maximumFractionDigits', mnfd, 20,
mxfdActualDefault); mxfdActualDefault);
%DefineWEProperty(internalOptions, 'maximumFractionDigits', mxfd); %DefineWEProperty(internalOptions, 'maximumFractionDigits', mxfd);
...@@ -1096,10 +1075,10 @@ function SetNumberFormatDigitOptions(internalOptions, options, ...@@ -1096,10 +1075,10 @@ function SetNumberFormatDigitOptions(internalOptions, options,
var mnsd = options['minimumSignificantDigits']; var mnsd = options['minimumSignificantDigits'];
var mxsd = options['maximumSignificantDigits']; var mxsd = options['maximumSignificantDigits'];
if (!IS_UNDEFINED(mnsd) || !IS_UNDEFINED(mxsd)) { if (!IS_UNDEFINED(mnsd) || !IS_UNDEFINED(mxsd)) {
mnsd = defaultNumberOption(mnsd, 1, 21, 1, 'minimumSignificantDigits'); mnsd = %DefaultNumberOption(mnsd, 1, 21, 1, 'minimumSignificantDigits');
%DefineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd); %DefineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd);
mxsd = defaultNumberOption(mxsd, mnsd, 21, 21, 'maximumSignificantDigits'); mxsd = %DefaultNumberOption(mxsd, mnsd, 21, 21, 'maximumSignificantDigits');
%DefineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd); %DefineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd);
} }
} }
......
...@@ -2023,5 +2023,46 @@ MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate, ...@@ -2023,5 +2023,46 @@ MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate,
return NumberFormat::FormatNumber(isolate, number_format_holder, number); return NumberFormat::FormatNumber(isolate, number_format_holder, number);
} }
// ecma402/#sec-defaultnumberoption
MaybeHandle<Smi> Intl::DefaultNumberOption(Isolate* isolate,
Handle<Object> value, int min,
int max, int fallback,
Handle<String> property) {
// 2. Else, return fallback.
if (value->IsUndefined()) {
return Handle<Smi>(Smi::FromInt(fallback), isolate);
}
// 1. If value is not undefined, then
// a. Let value be ? ToNumber(value).
Handle<Object> value_num;
ASSIGN_RETURN_ON_EXCEPTION(isolate, value_num,
Object::ToNumber(isolate, value), Smi);
DCHECK(value_num->IsNumber());
// b. If value is NaN or less than minimum or greater than maximum, throw a
// RangeError exception.
if (value_num->IsNaN() || value_num->Number() < min ||
value_num->Number() > max) {
THROW_NEW_ERROR(
isolate,
NewRangeError(MessageTemplate::kPropertyValueOutOfRange, property),
Smi);
}
// c. Return floor(value).
return Handle<Smi>(Smi::FromInt(floor(value_num->Number())), isolate);
}
// ecma402/#sec-getnumberoption
MaybeHandle<Smi> Intl::GetNumberOption(Isolate* isolate,
Handle<JSReceiver> options,
Handle<String> property, int min,
int max, int fallback) {
Handle<Object> value;
// 1. Let value be ? Get(options, property).
ASSIGN_RETURN_ON_EXCEPTION(
isolate, value, JSReceiver::GetProperty(isolate, options, property), Smi);
// Return ? DefaultNumberOption(value, minimum, maximum, fallback).
return DefaultNumberOption(isolate, value, min, max, fallback, property);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -335,6 +335,16 @@ class Intl { ...@@ -335,6 +335,16 @@ class Intl {
V8_WARN_UNUSED_RESULT static MaybeHandle<String> NumberToLocaleString( V8_WARN_UNUSED_RESULT static MaybeHandle<String> NumberToLocaleString(
Isolate* isolate, Handle<Object> num, Handle<Object> locales, Isolate* isolate, Handle<Object> num, Handle<Object> locales,
Handle<Object> options); Handle<Object> options);
// ecma402/#sec-defaultnumberoption
V8_WARN_UNUSED_RESULT static MaybeHandle<Smi> DefaultNumberOption(
Isolate* isolate, Handle<Object> value, int min, int max, int fallback,
Handle<String> property);
// ecma402/#sec-getnumberoption
V8_WARN_UNUSED_RESULT static MaybeHandle<Smi> GetNumberOption(
Isolate* isolate, Handle<JSReceiver> options, Handle<String> property,
int min, int max, int fallback);
}; };
} // namespace internal } // namespace internal
......
...@@ -53,6 +53,32 @@ ...@@ -53,6 +53,32 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
RUNTIME_FUNCTION(Runtime_GetNumberOption) {
HandleScope scope(isolate);
DCHECK_EQ(5, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, options, 0);
CONVERT_ARG_HANDLE_CHECKED(String, property, 1);
CONVERT_SMI_ARG_CHECKED(min, 2);
CONVERT_SMI_ARG_CHECKED(max, 3);
CONVERT_SMI_ARG_CHECKED(fallback, 4);
RETURN_RESULT_OR_FAILURE(
isolate,
Intl::GetNumberOption(isolate, options, property, min, max, fallback));
}
RUNTIME_FUNCTION(Runtime_DefaultNumberOption) {
HandleScope scope(isolate);
DCHECK_EQ(5, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
CONVERT_SMI_ARG_CHECKED(min, 1);
CONVERT_SMI_ARG_CHECKED(max, 2);
CONVERT_SMI_ARG_CHECKED(fallback, 3);
CONVERT_ARG_HANDLE_CHECKED(String, property, 4);
RETURN_RESULT_OR_FAILURE(
isolate,
Intl::DefaultNumberOption(isolate, value, min, max, fallback, property));
}
// ECMA 402 6.2.3 // ECMA 402 6.2.3
RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) { RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) {
HandleScope scope(isolate); HandleScope scope(isolate);
......
...@@ -217,7 +217,9 @@ namespace internal { ...@@ -217,7 +217,9 @@ namespace internal {
F(CreatePluralRules, 3, 1) \ F(CreatePluralRules, 3, 1) \
F(CurrencyDigits, 1, 1) \ F(CurrencyDigits, 1, 1) \
F(DateCacheVersion, 0, 1) \ F(DateCacheVersion, 0, 1) \
F(DefaultNumberOption, 5, 1) \
F(GetDefaultICULocale, 0, 1) \ F(GetDefaultICULocale, 0, 1) \
F(GetNumberOption, 5, 1) \
F(InternalCompare, 3, 1) \ F(InternalCompare, 3, 1) \
F(InternalDateFormat, 2, 1) \ F(InternalDateFormat, 2, 1) \
F(IntlUnwrapReceiver, 5, 1) \ F(IntlUnwrapReceiver, 5, 1) \
......
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