Commit 4db42a36 authored by Frank Tang's avatar Frank Tang Committed by V8 LUCI CQ

[Temporal] Fix Duration ToString

Use SNPrintf to handle bigger unit duration fields.

Spec Text:
https://tc39.es/proposal-temporal/#sec-temporal-temporaldurationtostring

Fix test:
https://github.com/tc39/test262/blob/main/test/built-ins/Temporal/Duration/prototype/toString/precision-formatted-as-decimal-number.js

Bug: v8:11544
Change-Id: I63a6e823652a0826216593cd153ef5103f94e7a9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3834437Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82573}
parent 299c2393
...@@ -1409,11 +1409,16 @@ Handle<String> TemporalDurationToString(Isolate* isolate, ...@@ -1409,11 +1409,16 @@ Handle<String> TemporalDurationToString(Isolate* isolate,
// 8. Let datePart be "". // 8. Let datePart be "".
IncrementalStringBuilder date_part(isolate); IncrementalStringBuilder date_part(isolate);
// Number.MAX_VALUE.toString() is "1.7976931348623157e+308"
// We add several more spaces to 320.
base::ScopedVector<char> buf(320);
// 9. If years is not 0, then // 9. If years is not 0, then
if (dur.years != 0) { if (dur.years != 0) {
// a. Set datePart to the string concatenation of abs(years) formatted as a // a. Set datePart to the string concatenation of abs(years) formatted as a
// decimal number and the code unit 0x0059 (LATIN CAPITAL LETTER Y). // decimal number and the code unit 0x0059 (LATIN CAPITAL LETTER Y).
date_part.AppendInt(static_cast<int32_t>(std::abs(dur.years))); SNPrintF(buf, "%.0f", std::abs(dur.years));
date_part.AppendCString(buf.data());
date_part.AppendCharacter('Y'); date_part.AppendCharacter('Y');
} }
// 10. If months is not 0, then // 10. If months is not 0, then
...@@ -1421,7 +1426,8 @@ Handle<String> TemporalDurationToString(Isolate* isolate, ...@@ -1421,7 +1426,8 @@ Handle<String> TemporalDurationToString(Isolate* isolate,
// a. Set datePart to the string concatenation of datePart, // a. Set datePart to the string concatenation of datePart,
// abs(months) formatted as a decimal number, and the code unit // abs(months) formatted as a decimal number, and the code unit
// 0x004D (LATIN CAPITAL LETTER M). // 0x004D (LATIN CAPITAL LETTER M).
date_part.AppendInt(static_cast<int32_t>(std::abs(dur.months))); SNPrintF(buf, "%.0f", std::abs(dur.months));
date_part.AppendCString(buf.data());
date_part.AppendCharacter('M'); date_part.AppendCharacter('M');
} }
// 11. If weeks is not 0, then // 11. If weeks is not 0, then
...@@ -1429,7 +1435,8 @@ Handle<String> TemporalDurationToString(Isolate* isolate, ...@@ -1429,7 +1435,8 @@ Handle<String> TemporalDurationToString(Isolate* isolate,
// a. Set datePart to the string concatenation of datePart, // a. Set datePart to the string concatenation of datePart,
// abs(weeks) formatted as a decimal number, and the code unit // abs(weeks) formatted as a decimal number, and the code unit
// 0x0057 (LATIN CAPITAL LETTER W). // 0x0057 (LATIN CAPITAL LETTER W).
date_part.AppendInt(static_cast<int32_t>(std::abs(dur.weeks))); SNPrintF(buf, "%.0f", std::abs(dur.weeks));
date_part.AppendCString(buf.data());
date_part.AppendCharacter('W'); date_part.AppendCharacter('W');
} }
// 12. If days is not 0, then // 12. If days is not 0, then
...@@ -1437,7 +1444,8 @@ Handle<String> TemporalDurationToString(Isolate* isolate, ...@@ -1437,7 +1444,8 @@ Handle<String> TemporalDurationToString(Isolate* isolate,
// a. Set datePart to the string concatenation of datePart, // a. Set datePart to the string concatenation of datePart,
// abs(days) formatted as a decimal number, and the code unit 0x0044 // abs(days) formatted as a decimal number, and the code unit 0x0044
// (LATIN CAPITAL LETTER D). // (LATIN CAPITAL LETTER D).
date_part.AppendInt(static_cast<int32_t>(std::abs(dur.time_duration.days))); SNPrintF(buf, "%.0f", std::abs(dur.time_duration.days));
date_part.AppendCString(buf.data());
date_part.AppendCharacter('D'); date_part.AppendCharacter('D');
} }
// 13. Let timePart be "". // 13. Let timePart be "".
...@@ -1446,8 +1454,8 @@ Handle<String> TemporalDurationToString(Isolate* isolate, ...@@ -1446,8 +1454,8 @@ Handle<String> TemporalDurationToString(Isolate* isolate,
if (dur.time_duration.hours != 0) { if (dur.time_duration.hours != 0) {
// a. Set timePart to the string concatenation of abs(hours) formatted as a // a. Set timePart to the string concatenation of abs(hours) formatted as a
// decimal number and the code unit 0x0048 (LATIN CAPITAL LETTER H). // decimal number and the code unit 0x0048 (LATIN CAPITAL LETTER H).
time_part.AppendInt( SNPrintF(buf, "%.0f", std::abs(dur.time_duration.hours));
static_cast<int32_t>(std::abs(dur.time_duration.hours))); time_part.AppendCString(buf.data());
time_part.AppendCharacter('H'); time_part.AppendCharacter('H');
} }
// 15. If minutes is not 0, then // 15. If minutes is not 0, then
...@@ -1455,11 +1463,11 @@ Handle<String> TemporalDurationToString(Isolate* isolate, ...@@ -1455,11 +1463,11 @@ Handle<String> TemporalDurationToString(Isolate* isolate,
// a. Set timePart to the string concatenation of timePart, // a. Set timePart to the string concatenation of timePart,
// abs(minutes) formatted as a decimal number, and the code unit // abs(minutes) formatted as a decimal number, and the code unit
// 0x004D (LATIN CAPITAL LETTER M). // 0x004D (LATIN CAPITAL LETTER M).
time_part.AppendInt( SNPrintF(buf, "%.0f", std::abs(dur.time_duration.minutes));
static_cast<int32_t>(std::abs(dur.time_duration.minutes))); time_part.AppendCString(buf.data());
time_part.AppendCharacter('M'); time_part.AppendCharacter('M');
} }
IncrementalStringBuilder second_part(isolate); IncrementalStringBuilder seconds_part(isolate);
IncrementalStringBuilder decimal_part(isolate); IncrementalStringBuilder decimal_part(isolate);
// 16. If any of seconds, milliseconds, microseconds, and nanoseconds are not // 16. If any of seconds, milliseconds, microseconds, and nanoseconds are not
// 0; or years, months, weeks, days, hours, and minutes are all 0, or // 0; or years, months, weeks, days, hours, and minutes are all 0, or
...@@ -1506,20 +1514,20 @@ Handle<String> TemporalDurationToString(Isolate* isolate, ...@@ -1506,20 +1514,20 @@ Handle<String> TemporalDurationToString(Isolate* isolate,
} }
} }
// f. Let secondsPart be abs(seconds) formatted as a decimal number. // f. Let secondsPart be abs(seconds) formatted as a decimal number.
second_part.AppendInt( SNPrintF(buf, "%.0f", std::abs(dur.time_duration.seconds));
static_cast<int32_t>(std::abs(dur.time_duration.seconds))); seconds_part.AppendCString(buf.data());
// g. If decimalPart is not "", then // g. If decimalPart is not "", then
if (decimal_part.Length() != 0) { if (decimal_part.Length() != 0) {
// i. Set secondsPart to the string-concatenation of secondsPart, the code // i. Set secondsPart to the string-concatenation of secondsPart, the code
// unit 0x002E (FULL STOP), and decimalPart. // unit 0x002E (FULL STOP), and decimalPart.
second_part.AppendCharacter('.'); seconds_part.AppendCharacter('.');
second_part.AppendString(decimal_part.Finish().ToHandleChecked()); seconds_part.AppendString(decimal_part.Finish().ToHandleChecked());
} }
// h. Set timePart to the string concatenation of timePart, secondsPart, and // h. Set timePart to the string concatenation of timePart, secondsPart, and
// the code unit 0x0053 (LATIN CAPITAL LETTER S). // the code unit 0x0053 (LATIN CAPITAL LETTER S).
time_part.AppendString(second_part.Finish().ToHandleChecked()); time_part.AppendString(seconds_part.Finish().ToHandleChecked());
time_part.AppendCharacter('S'); time_part.AppendCharacter('S');
} }
// 17. Let signPart be the code unit 0x002D (HYPHEN-MINUS) if sign < 0, and // 17. Let signPart be the code unit 0x002D (HYPHEN-MINUS) if sign < 0, and
......
...@@ -709,7 +709,6 @@ ...@@ -709,7 +709,6 @@
'built-ins/Temporal/Duration/prototype/round/total-duration-nanoseconds-too-large-with-zoned-datetime': [PASS, FAIL], 'built-ins/Temporal/Duration/prototype/round/total-duration-nanoseconds-too-large-with-zoned-datetime': [PASS, FAIL],
'built-ins/Temporal/Duration/prototype/subtract/days-is-number-max-value': [FAIL], 'built-ins/Temporal/Duration/prototype/subtract/days-is-number-max-value': [FAIL],
'built-ins/Temporal/Duration/prototype/subtract/nanoseconds-is-number-max-value-1': [FAIL], 'built-ins/Temporal/Duration/prototype/subtract/nanoseconds-is-number-max-value-1': [FAIL],
'built-ins/Temporal/Duration/prototype/toString/precision-formatted-as-decimal-number': [FAIL],
'built-ins/Temporal/Duration/prototype/total/relativeto-zoneddatetime-with-fractional-days-different-sign': [FAIL], 'built-ins/Temporal/Duration/prototype/total/relativeto-zoneddatetime-with-fractional-days-different-sign': [FAIL],
'built-ins/Temporal/Duration/prototype/total/relativeto-zoneddatetime-with-fractional-days': [FAIL], 'built-ins/Temporal/Duration/prototype/total/relativeto-zoneddatetime-with-fractional-days': [FAIL],
'built-ins/Temporal/PlainTime/prototype/add/argument-string-duration-too-large': [FAIL], 'built-ins/Temporal/PlainTime/prototype/add/argument-string-duration-too-large': [FAIL],
......
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