[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:
parent
9143c55387
commit
f47452080c
@ -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, \
|
||||
|
@ -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"},
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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],
|
||||
|
Loading…
Reference in New Issue
Block a user