RESOLVED FIXED 215438
[JSC] Implement IntlNumberFormat v3
https://bugs.webkit.org/show_bug.cgi?id=215438
Summary [JSC] Implement IntlNumberFormat v3
Yusuke Suzuki
Reported 2020-08-12 20:56:50 PDT
...
Attachments
Patch (30.90 KB, patch)
2021-08-25 21:57 PDT, Yusuke Suzuki
no flags
Patch (12.21 KB, patch)
2021-10-24 00:55 PDT, Yusuke Suzuki
ews-feeder: commit-queue-
Patch (45.14 KB, patch)
2021-10-24 01:10 PDT, Yusuke Suzuki
ews-feeder: commit-queue-
Patch (45.18 KB, patch)
2021-10-24 01:13 PDT, Yusuke Suzuki
no flags
Patch (51.95 KB, patch)
2021-10-24 02:07 PDT, Yusuke Suzuki
ews-feeder: commit-queue-
Patch (52.05 KB, patch)
2021-10-24 02:13 PDT, Yusuke Suzuki
no flags
Patch (51.89 KB, patch)
2021-10-24 02:17 PDT, Yusuke Suzuki
no flags
Patch (54.97 KB, patch)
2021-10-24 02:56 PDT, Yusuke Suzuki
no flags
Patch (55.49 KB, patch)
2021-10-24 03:33 PDT, Yusuke Suzuki
no flags
Patch (58.43 KB, patch)
2021-10-24 04:14 PDT, Yusuke Suzuki
no flags
Patch (61.34 KB, patch)
2021-10-24 04:21 PDT, Yusuke Suzuki
no flags
Patch (61.17 KB, patch)
2021-10-24 04:25 PDT, Yusuke Suzuki
no flags
Patch (94.02 KB, patch)
2021-10-25 22:19 PDT, Yusuke Suzuki
no flags
Patch (142.69 KB, patch)
2021-10-26 01:25 PDT, Yusuke Suzuki
no flags
Patch (143.12 KB, patch)
2021-10-26 03:29 PDT, Yusuke Suzuki
no flags
Patch (143.27 KB, patch)
2021-10-26 09:56 PDT, Yusuke Suzuki
no flags
Patch (144.30 KB, patch)
2021-10-26 11:18 PDT, Yusuke Suzuki
no flags
Patch (147.99 KB, patch)
2021-10-26 15:47 PDT, Yusuke Suzuki
no flags
Patch (148.00 KB, patch)
2021-10-26 17:52 PDT, Yusuke Suzuki
no flags
Patch (154.33 KB, patch)
2021-10-26 19:46 PDT, Yusuke Suzuki
ross.kirsling: review+
ews-feeder: commit-queue-
Yusuke Suzuki
Comment 1 2020-08-12 20:57:56 PDT
Radar WebKit Bug Importer
Comment 2 2020-08-19 20:57:13 PDT
Yusuke Suzuki
Comment 3 2021-08-24 12:33:44 PDT
Hmm, many APIs are requiring ICU 69. 1. New useGrouping 2. trailingZeroDisplay 3. halfCeil / halfFloor 4. signDisplay: "negative"
Yusuke Suzuki
Comment 4 2021-08-25 21:57:30 PDT
Yusuke Suzuki
Comment 5 2021-10-24 00:55:54 PDT
Yusuke Suzuki
Comment 6 2021-10-24 01:10:08 PDT
Yusuke Suzuki
Comment 7 2021-10-24 01:13:33 PDT
Yusuke Suzuki
Comment 8 2021-10-24 02:07:14 PDT
Yusuke Suzuki
Comment 9 2021-10-24 02:13:07 PDT
Yusuke Suzuki
Comment 10 2021-10-24 02:17:14 PDT
Yusuke Suzuki
Comment 11 2021-10-24 02:56:23 PDT
Yusuke Suzuki
Comment 12 2021-10-24 03:33:36 PDT
Yusuke Suzuki
Comment 13 2021-10-24 04:14:00 PDT
Yusuke Suzuki
Comment 14 2021-10-24 04:21:41 PDT
Yusuke Suzuki
Comment 15 2021-10-24 04:25:46 PDT
Yusuke Suzuki
Comment 16 2021-10-25 22:19:30 PDT
Yusuke Suzuki
Comment 17 2021-10-26 01:25:23 PDT
Yusuke Suzuki
Comment 18 2021-10-26 03:29:17 PDT
Yusuke Suzuki
Comment 19 2021-10-26 09:56:15 PDT
Yusuke Suzuki
Comment 20 2021-10-26 11:18:01 PDT
Yusuke Suzuki
Comment 21 2021-10-26 15:47:50 PDT
Yusuke Suzuki
Comment 22 2021-10-26 15:53:08 PDT
Comment on attachment 442540 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=442540&action=review > Source/JavaScriptCore/ChangeLog:18 > + - halfCeil / halfFloor (requires ICU 68) > + - signDisplay: "negative" (requires ICU 68) Ah, they are ICU 69. > Source/JavaScriptCore/ChangeLog:19 > + - formatRangeToParts (requires ICU 69) And ICU 70.
Yusuke Suzuki
Comment 23 2021-10-26 17:52:09 PDT
Ross Kirsling
Comment 24 2021-10-26 18:36:56 PDT
View in context: https://bugs.webkit.org/attachment.cgi?id=442540&action=review Fantastic. :D > Source/JavaScriptCore/runtime/IntlNumberFormat.cpp:402 > + bool invalidRoundingIncrement = true; > + for (unsigned candidate : roundingIncrementCandidates) { > + if (m_roundingIncrement == candidate) { > + invalidRoundingIncrement = false; > + break; > + } > + } > + if (invalidRoundingIncrement) { How about std::none_of? :) > Source/JavaScriptCore/runtime/IntlNumberFormat.cpp:839 > + if (std::signbit(end) && !end && start >= 0) I wonder if we should have an inlined helper function for negative zero? > Source/JavaScriptCore/runtime/IntlNumberFormat.h:212 > + enum class TrailingZeroDisplay : uint8_t { Auto, StripIfInteger }; Would there be any benefit to having this (and CompactDisplay) be bool? > Source/JavaScriptCore/runtime/IntlNumberFormat.h:214 > + enum class RoundingMode : uint8_t { Ceil, Floor, Expand, Trunc, HalfCeil, HalfFloor, HalfExpand, HalfTrunc, HalfEven }; Sounds like Temporal is intended to use the same RoundingMode values as NumberFormat V3, so I think we should move and update the existing enum. (See editor's note @ https://tc39.es/proposal-temporal/#sec-temporal-totemporalroundingmode) > Source/JavaScriptCore/runtime/IntlNumberFormatInlines.h:71 > + bool hasSd = !minimumSignificantDigitsValue.isUndefined() || !maximumSignificantDigitsValue.isUndefined(); > + bool hasFd = !minimumFractionDigitsValue.isUndefined() || !maximumFractionDigitsValue.isUndefined(); > + bool needSd = hasSd || roundingPriority != IntlRoundingPriority::Auto; > + bool needFd = (!hasSd && notation != IntlNotation::Compact) || roundingPriority != IntlRoundingPriority::Auto; nit: Seems like it should be "has"/"needs" or "have"/"need". Also if we're going to abbreviate, I think it should be "SD" and "FD". > JSTests/ChangeLog:10 > + * stress/intl-numberformat-format-range-v3.js: Added. Seems like many of the new test files just deal with en-US -- maybe we should ensure that each new feature is getting checked for multiple locales? > JSTests/stress/intl-numberformat-format-range-v3.js:54 > + ['formatRange'].forEach(function(method) { Why the forEach?
Yusuke Suzuki
Comment 25 2021-10-26 19:37:36 PDT
(In reply to Ross Kirsling from comment #24) > View in context: > https://bugs.webkit.org/attachment.cgi?id=442540&action=review > > Fantastic. :D > > > Source/JavaScriptCore/runtime/IntlNumberFormat.cpp:402 > > + bool invalidRoundingIncrement = true; > > + for (unsigned candidate : roundingIncrementCandidates) { > > + if (m_roundingIncrement == candidate) { > > + invalidRoundingIncrement = false; > > + break; > > + } > > + } > > + if (invalidRoundingIncrement) { > > How about std::none_of? :) Sounds good. > > > Source/JavaScriptCore/runtime/IntlNumberFormat.cpp:839 > > + if (std::signbit(end) && !end && start >= 0) > > I wonder if we should have an inlined helper function for negative zero? Added isNegativeZero. > > > Source/JavaScriptCore/runtime/IntlNumberFormat.h:212 > > + enum class TrailingZeroDisplay : uint8_t { Auto, StripIfInteger }; > > Would there be any benefit to having this (and CompactDisplay) be bool? Useful for stringifying function (strongly typed enum ensures the right parameter is passed). And this is aligned to the other options. Since it is not true/false option, we should use uint8_t. > > > Source/JavaScriptCore/runtime/IntlNumberFormat.h:214 > > + enum class RoundingMode : uint8_t { Ceil, Floor, Expand, Trunc, HalfCeil, HalfFloor, HalfExpand, HalfTrunc, HalfEven }; > > Sounds like Temporal is intended to use the same RoundingMode values as > NumberFormat V3, so I think we should move and update the existing enum. > (See editor's note @ > https://tc39.es/proposal-temporal/#sec-temporal-totemporalroundingmode) Changed. > > > Source/JavaScriptCore/runtime/IntlNumberFormatInlines.h:71 > > + bool hasSd = !minimumSignificantDigitsValue.isUndefined() || !maximumSignificantDigitsValue.isUndefined(); > > + bool hasFd = !minimumFractionDigitsValue.isUndefined() || !maximumFractionDigitsValue.isUndefined(); > > + bool needSd = hasSd || roundingPriority != IntlRoundingPriority::Auto; > > + bool needFd = (!hasSd && notation != IntlNotation::Compact) || roundingPriority != IntlRoundingPriority::Auto; > > nit: Seems like it should be "has"/"needs" or "have"/"need". Also if we're > going to abbreviate, I think it should be "SD" and "FD". This is aligned to the spec's names strictly since this is complicated. > > > JSTests/ChangeLog:10 > > + * stress/intl-numberformat-format-range-v3.js: Added. > > Seems like many of the new test files just deal with en-US -- maybe we > should ensure that each new feature is getting checked for multiple locales? Added some tests. > > > JSTests/stress/intl-numberformat-format-range-v3.js:54 > > + ['formatRange'].forEach(function(method) { > > Why the forEach? Because originally it also included "formatRangeToParts", which cannot be implemented with the current ICU version. I left forEach since I would like to keep V8 test as is as much as possible.
Yusuke Suzuki
Comment 26 2021-10-26 19:46:19 PDT
Ross Kirsling
Comment 27 2021-10-26 19:59:48 PDT
Comment on attachment 442558 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=442558&action=review r=me > Source/JavaScriptCore/runtime/IntlNumberFormat.cpp:422 > + m_roundingMode = intlOption<RoundingMode>(globalObject, options, vm.propertyNames->roundingMode, { I think ultimately we should update temporalRoundingMode and use it here (or actually probably turn it into intlRoundingMode and use it from Temporal)? But I guess we could wait for that spec to actually get updated with the intended behaviors. > Source/JavaScriptCore/runtime/MathCommon.h:68 > + return std::signbit(value) && value == 0; I think the style checker prefers `!value`?
Yusuke Suzuki
Comment 28 2021-10-26 20:17:12 PDT
Comment on attachment 442558 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=442558&action=review >> Source/JavaScriptCore/runtime/IntlNumberFormat.cpp:422 >> + m_roundingMode = intlOption<RoundingMode>(globalObject, options, vm.propertyNames->roundingMode, { > > I think ultimately we should update temporalRoundingMode and use it here (or actually probably turn it into intlRoundingMode and use it from Temporal)? > But I guess we could wait for that spec to actually get updated with the intended behaviors. Yes. Since TemporalObject and the spec is not handling these options, we should keep it separated for now. >> Source/JavaScriptCore/runtime/MathCommon.h:68 >> + return std::signbit(value) && value == 0; > > I think the style checker prefers `!value`? I think it does not work if value is signed NaN.
Yusuke Suzuki
Comment 29 2021-11-08 11:20:54 PST
Yusuke Suzuki
Comment 30 2021-11-08 11:34:35 PST
Yusuke Suzuki
Comment 31 2021-11-09 10:11:47 PST
Note You need to log in before you can comment on or make changes to this bug.