RESOLVED FIXED Bug 229826
[JSC] Implement Temporal.Instant
https://bugs.webkit.org/show_bug.cgi?id=229826
Summary [JSC] Implement Temporal.Instant
Philip Chimento
Reported 2021-09-02 13:10:04 PDT
Temporal.Instant and its methods except for toZonedDateTime/toZonedDateTimeISO, and Temporal.Now.instant() Blocks bug 223166
Attachments
Patch (15.68 KB, patch)
2021-09-03 17:50 PDT, Philip Chimento
no flags
Various tweaks in preparation for Temporal.Instant (14.51 KB, patch)
2021-09-03 18:01 PDT, Philip Chimento
no flags
WIP - Temporal.Instant - not ready for review (66.03 KB, patch)
2021-09-03 18:10 PDT, Philip Chimento
no flags
Various tweaks in preparation for Temporal.Instant (10.29 KB, patch)
2021-09-15 16:48 PDT, Philip Chimento
no flags
Various tweaks in preparation for Temporal.Instant (9.58 KB, patch)
2021-09-15 16:55 PDT, Philip Chimento
ews-feeder: commit-queue-
Patch for preliminary review (120.07 KB, patch)
2021-09-23 18:34 PDT, Philip Chimento
no flags
Patch for preliminary review (120.36 KB, patch)
2021-09-27 11:29 PDT, Philip Chimento
no flags
Patch for preliminary review (120.45 KB, patch)
2021-09-30 10:31 PDT, Philip Chimento
no flags
Patch (in progress) (123.76 KB, patch)
2021-10-06 13:01 PDT, Philip Chimento
no flags
Patch (in progress) (123.76 KB, patch)
2021-10-06 14:52 PDT, Philip Chimento
no flags
Patch (120.20 KB, patch)
2021-10-12 17:24 PDT, Philip Chimento
no flags
Patch (156.40 KB, patch)
2021-10-21 21:54 PDT, Philip Chimento
ews-feeder: commit-queue-
Patch (156.45 KB, patch)
2021-10-21 22:12 PDT, Philip Chimento
no flags
Patch (160.33 KB, patch)
2021-10-22 18:50 PDT, Philip Chimento
no flags
Patch (136.03 KB, patch)
2021-10-25 14:06 PDT, Philip Chimento
no flags
Patch (138.14 KB, patch)
2021-10-25 16:02 PDT, Philip Chimento
ews-feeder: commit-queue-
Patch (139.88 KB, patch)
2021-10-25 16:11 PDT, Philip Chimento
no flags
Patch (135.87 KB, patch)
2021-10-25 18:41 PDT, Philip Chimento
no flags
Patch (135.87 KB, patch)
2021-10-26 09:21 PDT, Philip Chimento
no flags
Patch (137.63 KB, patch)
2021-11-01 14:46 PDT, Philip Chimento
no flags
Philip Chimento
Comment 1 2021-09-03 17:50:36 PDT
Philip Chimento
Comment 2 2021-09-03 18:01:54 PDT
Created attachment 437329 [details] Various tweaks in preparation for Temporal.Instant
Philip Chimento
Comment 3 2021-09-03 18:10:43 PDT
Created attachment 437332 [details] WIP - Temporal.Instant - not ready for review
Philip Chimento
Comment 4 2021-09-03 18:21:53 PDT
The WIP patch doesn't cover string parsing yet. Additionally one corner that I intentionally cut was to store epochNanoseconds as a double, so I'll have to go back and change that. It actually requires at least 74 bits to store with the required precision. I haven't decided yet if it's best to store epochNanoseconds as a JSBigInt in TemporalInstant, or, e.g. store epochMilliseconds and up to 1e6 nanoseconds as separate integers, or even store epochMilliseconds as a double (using that convenient WTF::Seconds type) and nanoseconds separately.
Radar WebKit Bug Importer
Comment 5 2021-09-09 13:11:16 PDT
Philip Chimento
Comment 6 2021-09-15 16:48:22 PDT
Created attachment 438302 [details] Various tweaks in preparation for Temporal.Instant
Philip Chimento
Comment 7 2021-09-15 16:55:33 PDT
Created attachment 438304 [details] Various tweaks in preparation for Temporal.Instant
Yusuke Suzuki
Comment 8 2021-09-15 17:10:28 PDT
Comment on attachment 438304 [details] Various tweaks in preparation for Temporal.Instant Talked with Philip. This patch is not "Implement Temporal.Instant", so it should be uploaded in a different bugzilla.
Philip Chimento
Comment 9 2021-09-23 18:34:21 PDT
Created attachment 439114 [details] Patch for preliminary review
Philip Chimento
Comment 10 2021-09-23 18:39:50 PDT
There are still a few outstanding FIXMEs and I need to add more tests, but I think this patch has reached the point where some preliminary review is worth it, especially for a relative JSC newbie like me. I'll also be AFK until Monday so that's another reason I'm uploading something now. (I think the 3 style checker failures are spurious: there is a missing copyright in wtf/Int128.h, and the variable name checker flags `unsigned s` and `unsigned ns` as unnecessary whereas the other arguments to that function (y, mon, d, h, min, ms, micros) are OK)
Yusuke Suzuki
Comment 11 2021-09-23 19:22:52 PDT
Comment on attachment 439114 [details] Patch for preliminary review View in context: https://bugs.webkit.org/attachment.cgi?id=439114&action=review Nice, some quick comments. > Source/JavaScriptCore/runtime/ISO8601.h:185 > + static constexpr Int128 DAY_RANGE_S {86400'00000000}; // 1e8 days > + static constexpr Int128 NS_PER_MICROS {1000}; > + static constexpr Int128 NS_PER_MS {1'000'000}; > + static constexpr Int128 NS_PER_S {1'000'000'000}; > + static constexpr Int128 NS_PER_MINUTE = NS_PER_S * 60; > + static constexpr Int128 NS_PER_HOUR = NS_PER_MINUTE * 60; > + static constexpr Int128 MIN_VALUE = -DAY_RANGE_S * NS_PER_S; > + static constexpr Int128 MAX_VALUE = DAY_RANGE_S * NS_PER_S; We do not use capital constants. Rename them like, dayRangeSeconds etc. > Source/JavaScriptCore/runtime/JSBigInt.cpp:251 > + if ((unsignedValue & 0xffff'ffff'ffff'ffff) == unsignedValue) unsignedValue <= UINT64_MAX would be simpler. > Source/JavaScriptCore/runtime/JSBigInt.cpp:254 > + if (sizeof(Digit) == 8) { Use `if constexpr`. > Source/JavaScriptCore/runtime/JSBigInt.cpp:259 > + Digit lowBits = static_cast<Digit>(unsignedValue & 0xffff'ffff'ffff'ffff); > + Digit highBits = static_cast<Digit>((unsignedValue >> 64) & 0xffff'ffff'ffff'ffff); I think we do not need these &. Just casting is suffice. > Source/JavaScriptCore/runtime/JSBigInt.cpp:274 > + Digit digit0 = static_cast<Digit>(unsignedValue & 0xffff'ffff); > + Digit digit1 = static_cast<Digit>((unsignedValue >> 32) & 0xffff'ffff); > + Digit digit2 = static_cast<Digit>((unsignedValue >> 64) & 0xffff'ffff); > + Digit digit3 = static_cast<Digit>((unsignedValue >> 96) & 0xffff'ffff); Ditto.
Philip Chimento
Comment 12 2021-09-27 11:29:43 PDT
Created attachment 439371 [details] Patch for preliminary review
Philip Chimento
Comment 13 2021-09-30 10:31:26 PDT
Created attachment 439756 [details] Patch for preliminary review
Yusuke Suzuki
Comment 14 2021-10-03 00:18:09 PDT
Comment on attachment 439756 [details] Patch for preliminary review View in context: https://bugs.webkit.org/attachment.cgi?id=439756&action=review Commented. Please update DerivedSources-input.xcfilelist and DerivedSources-output.xcfilelist too. > Source/JavaScriptCore/runtime/ISO8601.cpp:907 > + return {ExactTime::fromISOPartsAndOffset(date.year(), date.month(), date.day(), time.hour(), time.minute(), time.second(), time.millisecond(), time.microsecond(), time.nanosecond(), offset)}; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.cpp:1017 > + double utcMs = (dateDays * msPerDay + timeMs); () is not necessary. > Source/JavaScriptCore/runtime/ISO8601.cpp:1018 > + Int128 utcNs = Int128 {static_cast<int64_t>(utcMs)} * 1'000'000 + micros * 1000 + ns; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.cpp:1019 > + return ExactTime {utcNs - offset}; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.cpp:1038 > + resultNs += Int128 {static_cast<int64_t>(duration.hours())} * ExactTime::nsPerHour; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.cpp:1041 > + resultNs += Int128 {static_cast<int64_t>(duration.minutes())} * ExactTime::nsPerMinute; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.cpp:1044 > + resultNs += Int128 {static_cast<int64_t>(duration.seconds())} * ExactTime::nsPerSecond; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.cpp:1047 > + resultNs += Int128 {static_cast<int64_t>(duration.milliseconds())} * ExactTime::nsPerMillisecond; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.cpp:1050 > + resultNs += Int128 {static_cast<int64_t>(duration.microseconds())} * ExactTime::nsPerMicrosecond; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.cpp:1051 > + resultNs += Int128 {static_cast<int64_t>(duration.nanoseconds())}; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.cpp:1053 > + ExactTime result {resultNs}; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.cpp:1056 > + return {result}; {} is not necessary. > Source/JavaScriptCore/runtime/ISO8601.cpp:1061 > + Int128 incrementNs {increment}; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.cpp:1085 > + return ExactTime {round(m_epochNanoseconds, increment, unit, roundingMode)}; Add space around {. > Source/JavaScriptCore/runtime/ISO8601.h:88 > + constexpr ExactTime(const ExactTime& other) : m_epochNanoseconds(other.m_epochNanoseconds) { } This is not necessary. > Source/JavaScriptCore/runtime/ISO8601.h:92 > + return ExactTime(Int128 {epochSeconds} * ExactTime::nsPerSecond); Add space around {. > Source/JavaScriptCore/runtime/ISO8601.h:96 > + return ExactTime(Int128 {epochMilliseconds} * ExactTime::nsPerMillisecond); Add space around {. > Source/JavaScriptCore/runtime/ISO8601.h:100 > + return ExactTime(Int128 {epochMicroseconds} * ExactTime::nsPerMicrosecond); Add space around {. > Source/JavaScriptCore/runtime/ISO8601.h:139 > + String print() const > + { > + StringBuilder builder; > + if (m_epochNanoseconds < 0) { > + builder.append('-'); > + printImpl(builder, -m_epochNanoseconds); > + } else > + printImpl(builder, m_epochNanoseconds); > + return builder.toString(); > + } "print" function should be used for printing string to dataLog. Please rename it. > Source/JavaScriptCore/runtime/ISO8601.h:181 > + static constexpr Int128 dayRangeSeconds {86400'00000000}; // 1e8 days > + static constexpr Int128 nsPerMicrosecond {1000}; > + static constexpr Int128 nsPerMillisecond {1'000'000}; > + static constexpr Int128 nsPerSecond {1'000'000'000}; Add space around { and }. > Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp:99 > + return dateNowImpl().toNumber(globalObject); Use RELEASE_AND_RETURN(scope, dateNowImpl().toNumber(globalObject)); > Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp:111 > + auto scope = DECLARE_THROW_SCOPE(vm); VM& vm = globalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); should be defined in the prologue of the function. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:58 > +void TemporalInstant::finishCreation(VM& vm) > +{ > + Base::finishCreation(vm); > + ASSERT(inherits(vm, info())); > +} We do not need to define it. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:91 > + JSBigInt* bigint = asHeapBigInt(epochNanoseconds); Add BIGINT32 case. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:94 > + ISO8601::ExactTime exactTime {(high << 64 | low) * (bigint->sign() ? -1 : 1)}; Add space around {. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:97 > + String argAsString {bigint->toString(globalObject, 10)}; In this case, use argsAsString = bigint->toString(globalObject, 10) > Source/JavaScriptCore/runtime/TemporalInstant.cpp:120 > + // TODO: when Temporal.ZonedDateTime lands TODO is not used in WebKit. Use FIXME > Source/JavaScriptCore/runtime/TemporalInstant.cpp:200 > + JSBigInt* bigint = asHeapBigInt(epochMicroseconds); Add BIGINT32 case. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:222 > + VM& vm = globalObject->vm(); > + auto scope = DECLARE_THROW_SCOPE(vm); > + This is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:281 > + double seconds {static_cast<double>(static_cast<int64_t>(roundedDiff / 1'000'000'000))}; Add space around {. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:282 > + double nanosecondsRemainder {static_cast<double>(static_cast<int64_t>(roundedDiff % 1'000'000'000))}; Add space around {. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:283 > + ISO8601::Duration result {0, 0, 0, 0, 0, 0, seconds, 0, 0, nanosecondsRemainder}; Add space around {. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:406 > + char buffer[20]; > + // If the year is outside the bounds of 0 and 9999 inclusive we want to use > + // the extended year format (PadISOYear). > + int charactersWritten; > + if (gregorianDateTime.year() > 9999 || gregorianDateTime.year() < 1000) > + charactersWritten = snprintf(buffer, sizeof(buffer), "%+07d-%02d-%02dT%02d:%02d", gregorianDateTime.year(), gregorianDateTime.month() + 1, gregorianDateTime.monthDay(), gregorianDateTime.hour(), gregorianDateTime.minute()); > + else > + charactersWritten = snprintf(buffer, sizeof(buffer), "%04d-%02d-%02dT%02d:%02d", gregorianDateTime.year(), gregorianDateTime.month() + 1, gregorianDateTime.monthDay(), gregorianDateTime.hour(), gregorianDateTime.minute()); > + ASSERT(charactersWritten > 0 && static_cast<unsigned>(charactersWritten) < sizeof(buffer)); > + if (static_cast<unsigned>(charactersWritten) >= sizeof(buffer)) > + return ""_s; > + > + StringBuilder builder; > + builder.append(buffer); Let's not use snprintf. It is very slow compared to the other way. You can use makeString, pad() etc. instead. > Source/JavaScriptCore/runtime/TemporalInstantPrototype.cpp:121 > + const std::optional<ISO8601::ExactTime> newExactTime = instant->exactTime().add(duration); We don't use const in this case. > Source/JavaScriptCore/runtime/TemporalInstantPrototype.cpp:142 > + const std::optional<ISO8601::ExactTime> newExactTime = instant->exactTime().add(-duration); We don't use const in this case.
Philip Chimento
Comment 15 2021-10-05 14:10:19 PDT
(In reply to Yusuke Suzuki from comment #14) > > Source/JavaScriptCore/runtime/TemporalInstant.cpp:406 > > + char buffer[20]; > > + // If the year is outside the bounds of 0 and 9999 inclusive we want to use > > + // the extended year format (PadISOYear). > > + int charactersWritten; > > + if (gregorianDateTime.year() > 9999 || gregorianDateTime.year() < 1000) > > + charactersWritten = snprintf(buffer, sizeof(buffer), "%+07d-%02d-%02dT%02d:%02d", gregorianDateTime.year(), gregorianDateTime.month() + 1, gregorianDateTime.monthDay(), gregorianDateTime.hour(), gregorianDateTime.minute()); > > + else > > + charactersWritten = snprintf(buffer, sizeof(buffer), "%04d-%02d-%02dT%02d:%02d", gregorianDateTime.year(), gregorianDateTime.month() + 1, gregorianDateTime.monthDay(), gregorianDateTime.hour(), gregorianDateTime.minute()); > > + ASSERT(charactersWritten > 0 && static_cast<unsigned>(charactersWritten) < sizeof(buffer)); > > + if (static_cast<unsigned>(charactersWritten) >= sizeof(buffer)) > > + return ""_s; > > + > > + StringBuilder builder; > > + builder.append(buffer); > > Let's not use snprintf. It is very slow compared to the other way. You can > use makeString, pad() etc. instead. Got it, thanks. Originally I adapted this code from dateProtoFuncToISOString() in runtime/DatePrototype.cpp; I assume we should not change that?
Philip Chimento
Comment 16 2021-10-05 14:41:09 PDT
(In reply to Yusuke Suzuki from comment #14) > > Source/JavaScriptCore/runtime/ISO8601.h:88 > > + constexpr ExactTime(const ExactTime& other) : m_epochNanoseconds(other.m_epochNanoseconds) { } > > This is not necessary. I remembered why I put this in; it seems that Clang doesn't correctly generate the copy constructor when we have a __int128 member. I've added a comment explaining why this "useless" copy constructor is here, and will try to isolate a minimum reproducible example and hopefully report a Clang bug. (Or find out what my mistake was :-)
Yusuke Suzuki
Comment 17 2021-10-06 02:12:46 PDT
Comment on attachment 439756 [details] Patch for preliminary review View in context: https://bugs.webkit.org/attachment.cgi?id=439756&action=review Added some more style nits. > Source/JavaScriptCore/runtime/TemporalDuration.cpp:170 > +const ISO8601::Duration TemporalDuration::toLimitedDuration(JSGlobalObject* globalObject, JSValue itemValue, std::initializer_list<TemporalUnit> disallowedUnits) This const is not necessary. > Source/JavaScriptCore/runtime/TemporalDuration.h:49 > + static const ISO8601::Duration toLimitedDuration(JSGlobalObject*, JSValue, std::initializer_list<TemporalUnit> disallowedUnits); const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:48 > +TemporalInstant::TemporalInstant(VM& vm, Structure* structure, const ISO8601::ExactTime exactTime) const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:60 > +TemporalInstant* TemporalInstant::create(VM& vm, Structure* structure, const ISO8601::ExactTime exactTime) const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:70 > +TemporalInstant* TemporalInstant::tryCreateIfValid(JSGlobalObject* globalObject, const ISO8601::ExactTime exactTime, Structure* structure) const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:246 > +const ISO8601::Duration TemporalInstant::difference(JSGlobalObject* globalObject, TemporalInstant* other, JSValue optionsValue) const const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:308 > +const ISO8601::ExactTime TemporalInstant::round(JSGlobalObject* globalObject, JSValue optionsValue) const const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:385 > +String TemporalInstant::toString(const ISO8601::ExactTime exactTime, JSObject* timeZone, PrecisionData precision) const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.h:46 > + static TemporalInstant* create(VM&, Structure*, const ISO8601::ExactTime); const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.h:47 > + static TemporalInstant* tryCreateIfValid(JSGlobalObject*, const ISO8601::ExactTime, Structure* = nullptr); const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.h:61 > + constexpr const ISO8601::ExactTime exactTime() const { return m_exactTime; } const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.h:64 > + const ISO8601::Duration difference(JSGlobalObject*, TemporalInstant*, JSValue options) const; > + const ISO8601::ExactTime round(JSGlobalObject*, JSValue options) const; const iISO8601::XXX's const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.h:72 > + TemporalInstant(VM&, Structure*, const ISO8601::ExactTime); const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.h:77 > + static const ISO8601::ExactTime fromObject(JSGlobalObject*, JSObject*); const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstant.h:79 > + static String toString(const ISO8601::ExactTime, JSObject* timeZone, PrecisionData); const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstantPrototype.cpp:118 > + const ISO8601::Duration duration = TemporalDuration::toLimitedDuration(globalObject, callFrame->argument(0), disallowedAdditionUnits); const is not necessary. > Source/JavaScriptCore/runtime/TemporalInstantPrototype.cpp:139 > + const ISO8601::Duration duration = TemporalDuration::toLimitedDuration(globalObject, callFrame->argument(0), disallowedAdditionUnits); const is not necessary.
Yusuke Suzuki
Comment 18 2021-10-06 02:29:20 PDT
(In reply to Philip Chimento from comment #16) > (In reply to Yusuke Suzuki from comment #14) > > > Source/JavaScriptCore/runtime/ISO8601.h:88 > > > + constexpr ExactTime(const ExactTime& other) : m_epochNanoseconds(other.m_epochNanoseconds) { } > > > > This is not necessary. > > I remembered why I put this in; it seems that Clang doesn't correctly > generate the copy constructor when we have a __int128 member. I've added a > comment explaining why this "useless" copy constructor is here, and will try > to isolate a minimum reproducible example and hopefully report a Clang bug. > (Or find out what my mistake was :-) I think probably I found what is happening. This statement itself is not related. So let's remove that. The problem is that, `alignof(__int128_t)` is 16!, which is probably only the data type usually we see. JSC GC-managed object is allocated with 8byte alignment (for MarkBlock allocations, it is 16-byte aligned. But for PreciseAllocation, it is 8-byte aligned. And first several objects of the same type can be allocated from PreciseAllocation). This means that, 16 byte alignment requirement can be broken. I reproduced JSC EWS crash locally. And the crash is 0x102ecb2f4 <+164>: jne 0x102ecb325 ; <+213> at TemporalInstant.cpp:351:20 0x102ecb2f6 <+166>: xorl %eax, %eax 0x102ecb2f8 <+168>: movq %rax, -0x80(%rbp) 0x102ecb2fc <+172>: jmp 0x102ecb344 ; <+244> at TemporalInstant.cpp:355:26 -> 0x102ecb2fe <+174>: movaps 0x10(%r12), %xmm0 0x102ecb304 <+180>: movaps %xmm0, -0x70(%rbp) 0x102ecb308 <+184>: leaq -0x70(%rbp), %rsi 0x102ecb30c <+188>: movabsq $0x100000009, %r8 ; imm = 0x100000009 0x102ecb316 <+198>: movl $0x2, %ecx And r12 is 0x00000001005958d8. So 0x10(%r12) is not 16-byte aligned while the compiler is using movaps since it assumes that TemporalInstant is allocated with 16byte aligned, but it is not. For now, you can just try simple way like this. https://gist.github.com/Constellation/71dd37e75b013e3130104e64a85e254b
Philip Chimento
Comment 19 2021-10-06 13:01:09 PDT
Created attachment 440419 [details] Patch (in progress)
Philip Chimento
Comment 20 2021-10-06 13:02:19 PDT
Thanks for the comments. Here's a new patch - no need to review it right away, I'm mainly posting it to make sure the bots now pass it. I'll be adding some more tests and trying to resolve the remaining open questions.
Philip Chimento
Comment 21 2021-10-06 14:52:38 PDT
Created attachment 440440 [details] Patch (in progress)
Philip Chimento
Comment 22 2021-10-12 17:24:47 PDT
Philip Chimento
Comment 23 2021-10-12 17:26:08 PDT
I rebased the patch again. I still need to add more tests, so this isn't 100% ready for review, but any thoughts on the remaining FIXMEs would be appreciated. I will intend to resume this next week.
Yusuke Suzuki
Comment 24 2021-10-15 17:42:42 PDT
Comment on attachment 441022 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=441022&action=review Commented about HeapBigInt. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:85 > + JSBigInt* bigint = asHeapBigInt(epochNanoseconds); This is not correct. In BIGINT32 environment, epochMicroseconds can be BigInt32. So we should check it first before casting it to HeapBigInt via asHeapBigInt. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:210 > + JSBigInt* bigint = asHeapBigInt(epochMicroseconds); > +#if USE(BIGINT32) > + bool bigIntTooLong = bigint->length() > 2; > +#else > + bool bigIntTooLong = bigint->length() > 1; > +#endif > + ISO8601::ExactTime exactTime = ISO8601::ExactTime::fromEpochMicroseconds(JSBigInt::toBigUInt64(bigint)); This is not correct. In BIGINT32 environment, epochMicroseconds can be BigInt32. So we should check it first before casting it to HeapBigInt via asHeapBigInt.
Philip Chimento
Comment 25 2021-10-21 21:54:14 PDT
Philip Chimento
Comment 26 2021-10-21 22:12:56 PDT
Philip Chimento
Comment 27 2021-10-22 18:50:05 PDT
Philip Chimento
Comment 28 2021-10-25 14:06:32 PDT
Philip Chimento
Comment 29 2021-10-25 16:02:31 PDT
Philip Chimento
Comment 30 2021-10-25 16:11:14 PDT
Philip Chimento
Comment 31 2021-10-25 16:11:59 PDT
This patch temporarily contains the one from bug 232270, should be rebased when that one lands
Philip Chimento
Comment 32 2021-10-25 18:41:18 PDT
Philip Chimento
Comment 33 2021-10-26 09:21:49 PDT
Yusuke Suzuki
Comment 34 2021-10-28 23:24:18 PDT
Comment on attachment 442498 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=442498&action=review r=me with nits. > Source/JavaScriptCore/runtime/TemporalInstant.cpp:109 > + if constexpr (sizeof(JSBigInt::Digit) == 4) { > + Int128 d0 { bigint->length() > 0 ? bigint->digit(0) : 0 }; > + Int128 d1 { bigint->length() > 1 ? bigint->digit(1) : 0 }; > + Int128 d2 { bigint->length() > 2 ? bigint->digit(2) : 0 }; > + total = d2 << 64 | d1 << 32 | d0; > + bigIntTooLong = bigint->length() > 3; > + } else { > + ASSERT(sizeof(JSBigInt::Digit) == 8); > + Int128 low { bigint->length() > 0 ? bigint->digit(0) : 0 }; > + Int128 high { bigint->length() > 1 ? bigint->digit(1) : 0 }; > + total = high << 64 | low; > + bigIntTooLong = bigint->length() > 2; > + } INT128_MIN case is not handled properly (-1 * INT128_MIN is undefined). Can you check it? (and can you add a test?) > Source/JavaScriptCore/runtime/TemporalInstant.cpp:233 > + int64_t microseconds = JSBigInt::toBigInt64(bigint); It is not handling negative Int128 ranges (if JSBigInt's 2 digits are larger than INT128_MAX, then if it is signed, it is not within Int128 range). Can you fix it and add test for this? > Source/JavaScriptCore/runtime/TemporalObject.cpp:470 > + Let's add `ASSERT(increment != 0)`
Philip Chimento
Comment 35 2021-11-01 14:46:46 PDT
Philip Chimento
Comment 36 2021-11-01 14:49:37 PDT
(In reply to Yusuke Suzuki from comment #34) > > Source/JavaScriptCore/runtime/TemporalInstant.cpp:233 > > + int64_t microseconds = JSBigInt::toBigInt64(bigint); > > It is not handling negative Int128 ranges (if JSBigInt's 2 digits are larger > than INT128_MAX, then if it is signed, it is not within Int128 range). > Can you fix it and add test for this? I guess you mean INT64_MAX here? I've fixed these cases, added tests, and added the assertion. Additionally I adjusted the test with the BigInt('9'.repeat(2147483648)) case, because I suspect that constructing that string was what was making the jsc-armv7 tests fail. (Anyway, the test was not actually testing what we thought it would, because BigInts that large are not allowed.) Hopefully ready to land this time.
EWS
Comment 37 2021-11-02 12:57:48 PDT
Committed r285178 (243811@main): <https://commits.webkit.org/243811@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 443019 [details].
Note You need to log in before you can comment on or make changes to this bug.