[intl] NumberFormat v3 sync w/ spec PR 85 and 91

PR85 https://github.com/tc39/proposal-intl-numberformat-v3/pull/85
Throw RangeError while roundingIncrement is not 1 and
minimumFractionDigits != maximumFractionDigits
Test by new test cases in intl/number-format/rounding-increment-v3.js

Add more unit test to check the resolved options of roundingIncrement,
minimumFractionDigits, and maximumFractionDigits.

PR91 https://github.com/tc39/proposal-intl-numberformat-v3/pull/91
Throw TypeError instead of RangeError while roundingIncrement is not 1
and RoundingType is not fractionDigits
Test by intl402/NumberFormat/constructor-roundingIncrement-invalid.js
in test262

Bug: v8:10776
Change-Id: I071bfe8b3e844c5999144d74bb5f79ea9811e37b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3603059
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80196}
This commit is contained in:
Frank Tang 2022-04-26 12:42:49 -07:00 committed by V8 LUCI CQ
parent 9143c55387
commit f47452080c
7 changed files with 78 additions and 38 deletions

View File

@ -42,6 +42,7 @@ namespace internal {
"await can not be used when evaluating code " \
"while paused in the debugger") \
T(AtomicsWaitNotAllowed, "Atomics.wait cannot be called in this context") \
T(BadRoundingType, "RoundingType is not fractionDigits") \
T(BadSortComparisonFunction, \
"The comparison function must be either a function or undefined") \
T(BigIntFromNumber, \
@ -376,6 +377,8 @@ namespace internal {
T(InvalidTypedArrayLength, "Invalid typed array length: %") \
T(LetInLexicalBinding, "let is disallowed as a lexically bound name") \
T(LocaleMatcher, "Illegal value for localeMatcher:%") \
T(MaximumFractionDigitsNotEqualMinimumFractionDigits, \
"maximumFractionDigits not equal to minimumFractionDigits") \
T(NormalizationForm, "The normalization form should be one of %.") \
T(OutOfMemory, "%: Out of memory") \
T(ParameterOfFunctionOutOfRange, \

View File

@ -1451,18 +1451,31 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
factory->roundingIncrement_string()),
JSNumberFormat);
}
// 23. If roundingIncrement is not 1 and numberFormat.[[RoundingType]] is
// not fractionDigits, throw a RangeError exception.
if (rounding_increment != 1 &&
digit_options.rounding_type != Intl::RoundingType::kFractionDigits) {
THROW_NEW_ERROR(isolate,
NewRangeError(MessageTemplate::kPropertyValueOutOfRange,
factory->roundingIncrement_string()),
JSNumberFormat);
if (rounding_increment != 1) {
// 23. If roundingIncrement is not 1 and numberFormat.[[RoundingType]] is
// not fractionDigits, throw a TypeError exception.
if (digit_options.rounding_type != Intl::RoundingType::kFractionDigits) {
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kBadRoundingType),
JSNumberFormat);
}
// 24. If roundingIncrement is not 1 and
// numberFormat.[[MaximumFractionDigits]] is not equal to
// numberFormat.[[MinimumFractionDigits]], throw a RangeError exception.
if (digit_options.maximum_fraction_digits !=
digit_options.minimum_fraction_digits) {
THROW_NEW_ERROR(
isolate,
NewRangeError(
MessageTemplate::
kMaximumFractionDigitsNotEqualMinimumFractionDigits),
JSNumberFormat);
}
}
// 24. Set _numberFormat.[[RoundingIncrement]] to roundingIncrement.
// 25. Let trailingZeroDisplay be ? GetOption(options,
// 25. Set _numberFormat.[[RoundingIncrement]] to roundingIncrement.
// 26. Let trailingZeroDisplay be ? GetOption(options,
// "trailingZeroDisplay", "string", « "auto", "stripIfInteger" », "auto").
Maybe<TrailingZeroDisplay> maybe_trailing_zero_display =
GetStringOption<TrailingZeroDisplay>(
@ -1474,7 +1487,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
TrailingZeroDisplay trailing_zero_display =
maybe_trailing_zero_display.FromJust();
// 26. Set numberFormat.[[TrailingZeroDisplay]] to trailingZeroDisplay.
// 27. Set numberFormat.[[TrailingZeroDisplay]] to trailingZeroDisplay.
settings = SetDigitOptionsToFormatterV3(
settings, digit_options, rounding_increment,
trailing_zero_display == TrailingZeroDisplay::STRIP_IF_INTEGER
@ -1484,7 +1497,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
settings = SetDigitOptionsToFormatterV2(settings, digit_options);
}
// 27. Let compactDisplay be ? GetOption(options, "compactDisplay",
// 28. Let compactDisplay be ? GetOption(options, "compactDisplay",
// "string", « "short", "long" », "short").
Maybe<CompactDisplay> maybe_compact_display = GetStringOption<CompactDisplay>(
isolate, options, "compactDisplay", service, {"short", "long"},

View File

@ -83,7 +83,7 @@ bytecodes: [
/* 48 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0),
/* 53 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 58 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(298),
B(Wide), B(LdaSmi), I16(300),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
@ -115,7 +115,7 @@ bytecodes: [
/* 41 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0),
/* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 51 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(297),
B(Wide), B(LdaSmi), I16(299),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
@ -149,7 +149,7 @@ bytecodes: [
B(Star2),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 58 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(298),
B(Wide), B(LdaSmi), I16(300),
B(Star3),
B(LdaConstant), U8(0),
B(Star4),
@ -181,7 +181,7 @@ bytecodes: [
/* 41 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0),
/* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 51 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(297),
B(Wide), B(LdaSmi), I16(299),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),

View File

@ -58,7 +58,7 @@ bytecodes: [
B(Star2),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 54 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(296),
B(Wide), B(LdaSmi), I16(298),
B(Star3),
B(LdaConstant), U8(0),
B(Star4),
@ -91,7 +91,7 @@ bytecodes: [
/* 44 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0),
/* 49 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 54 E> */ B(GetKeyedProperty), R(this), U8(2),
B(Wide), B(LdaSmi), I16(296),
B(Wide), B(LdaSmi), I16(298),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),

View File

@ -24,7 +24,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(1),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(290),
B(Wide), B(LdaSmi), I16(292),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
@ -61,13 +61,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(290),
B(Wide), B(LdaSmi), I16(292),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
/* 61 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(296),
B(Wide), B(LdaSmi), I16(298),
B(Star2),
B(LdaConstant), U8(1),
B(Star3),
@ -99,13 +99,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(290),
B(Wide), B(LdaSmi), I16(292),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
/* 61 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(296),
B(Wide), B(LdaSmi), I16(298),
B(Star1),
B(LdaConstant), U8(1),
B(Star2),
@ -145,7 +145,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(290),
B(Wide), B(LdaSmi), I16(292),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
@ -167,7 +167,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(290),
B(Wide), B(LdaSmi), I16(292),
B(Star3),
B(LdaConstant), U8(0),
B(Star4),
@ -182,7 +182,7 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(290),
B(Wide), B(LdaSmi), I16(292),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
@ -216,13 +216,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(290),
B(Wide), B(LdaSmi), I16(292),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
/* 65 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(298),
B(Wide), B(LdaSmi), I16(300),
B(Star1),
B(LdaConstant), U8(1),
B(Star2),
@ -253,13 +253,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(290),
B(Wide), B(LdaSmi), I16(292),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),
/* 58 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(297),
B(Wide), B(LdaSmi), I16(299),
B(Star1),
B(LdaConstant), U8(1),
B(Star2),
@ -292,13 +292,13 @@ bytecodes: [
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(16),
B(Wide), B(LdaSmi), I16(290),
B(Wide), B(LdaSmi), I16(292),
B(Star2),
B(LdaConstant), U8(0),
B(Star3),
/* 65 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
B(Wide), B(LdaSmi), I16(298),
B(Wide), B(LdaSmi), I16(300),
B(Star2),
B(LdaConstant), U8(1),
B(Star3),
@ -327,7 +327,7 @@ bytecode array length: 19
bytecodes: [
/* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 51 E> */ B(GetKeyedProperty), R(this), U8(0),
B(Wide), B(LdaSmi), I16(297),
B(Wide), B(LdaSmi), I16(299),
B(Star1),
B(LdaConstant), U8(0),
B(Star2),

View File

@ -8,16 +8,41 @@ let validRoundingIncrements = [
1, 2, 5, 10, 20, 25, 50, 100, 200, 250, 500, 1000, 2000, 2500, 5000];
let invalidRoundingIncrements = [
-1, -5, 0, 3, 1001, 1100, 5500, 10000, 20000, 25000, 100000, 200000, 500005, 10000000
-1, -5, 0, 3, 1001, 1100, 5500, 10000, 20000, 25000, 100000, 200000, 500005,
10000000
];
validRoundingIncrements.forEach(function(roundingIncrement) {
assertDoesNotThrow(() => {
new Intl.NumberFormat(undefined, {roundingIncrement})});
new Intl.NumberFormat(undefined, {roundingIncrement,
minimumFractionDigits:3})});
for (mfd = 0; mfd < 20; mfd++) {
let fn = new Intl.NumberFormat(undefined, {
roundingIncrement,
minimumFractionDigits: mfd, maximumFractionDigits: mfd});
let res = fn.resolvedOptions();
assertEquals(roundingIncrement, res.roundingIncrement);
assertEquals(mfd, res.minimumFractionDigits);
assertEquals(mfd, res.maximumFractionDigits);
}
// Test
// "If roundingIncrement is not 1 and numberFormat.[[MaximumFractionDigits]]
// is not equal to numberFormat.[[MinimumFractionDigits]], throw a RangeError
// exception.
if (roundingIncrement == 1) return;
for (mnfd = 0; mnfd < 20; mnfd++) {
for (mxfd = mnfd+1; mxfd < 20; mxfd++) {
assertThrows(() => {
let nf = new Intl.NumberFormat(undefined, {
roundingIncrement, minimumFractionDigits:mnfd,
maximumFractionDigits: mxfd})},
RangeError);
}
}
});
invalidRoundingIncrements.forEach(function(roundingIncrement) {
assertThrows(() => {
let nf = new Intl.NumberFormat(undefined, {roundingIncrement})},
assertThrows(() => { let nf = new Intl.NumberFormat(undefined, {roundingIncrement,
minimumFractionDigits:3})},
RangeError);
});

View File

@ -2850,7 +2850,6 @@
# https://bugs.chromium.org/p/v8/issues/detail?id=10776
'intl402/NumberFormat/constructor-roundingIncrement': [FAIL],
'intl402/NumberFormat/constructor-roundingIncrement-invalid': [FAIL],
# NumberFormat.prototype.formatRange
'intl402/NumberFormat/prototype/formatRange/en-US': [FAIL],
'intl402/NumberFormat/prototype/formatRange/pt-PT': [FAIL],