WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
210835
[JSC] NumberConstructor should accept BigInt
https://bugs.webkit.org/show_bug.cgi?id=210835
Summary
[JSC] NumberConstructor should accept BigInt
Yusuke Suzuki
Reported
2020-04-21 18:07:16 PDT
...
Attachments
Patch
(40.29 KB, patch)
2020-04-27 01:14 PDT
,
Yusuke Suzuki
no flags
Details
Formatted Diff
Diff
Patch
(32.18 KB, patch)
2020-04-27 01:19 PDT
,
Yusuke Suzuki
no flags
Details
Formatted Diff
Diff
Patch
(41.15 KB, patch)
2020-04-27 01:27 PDT
,
Yusuke Suzuki
no flags
Details
Formatted Diff
Diff
Patch
(40.93 KB, patch)
2020-04-27 01:35 PDT
,
Yusuke Suzuki
mark.lam
: review+
Details
Formatted Diff
Diff
Patch for landing
(43.67 KB, patch)
2020-04-27 22:04 PDT
,
Yusuke Suzuki
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Yusuke Suzuki
Comment 1
2020-04-21 18:07:59 PDT
This looks like a spec change from the original one.
https://tc39.es/ecma262/#sec-number-constructor-number-value
Yusuke Suzuki
Comment 2
2020-04-21 18:18:52 PDT
DFG/FTL support is also required since NumberConstructor is supported in DFG. Maybe, we should introduce CallNumberConstructor DFG node.
Yusuke Suzuki
Comment 3
2020-04-27 01:14:40 PDT
Created
attachment 397656
[details]
Patch
Yusuke Suzuki
Comment 4
2020-04-27 01:19:25 PDT
Created
attachment 397657
[details]
Patch
Yusuke Suzuki
Comment 5
2020-04-27 01:27:18 PDT
Created
attachment 397658
[details]
Patch
Yusuke Suzuki
Comment 6
2020-04-27 01:35:56 PDT
Created
attachment 397660
[details]
Patch
Mark Lam
Comment 7
2020-04-27 11:23:48 PDT
Comment on
attachment 397660
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=397660&action=review
Some comments while I continue reviewing. If you haven't already done so, can you also run the added tests against Chrome and Firefox as sanity check that there's no unexpected difference in behavior?
> Source/JavaScriptCore/runtime/JSBigInt.cpp:2256 > + mantissa >>= 12; // (12 = 64 - 52) (double's mantissa bit count).
12 is the non-mantissa bit count, i.e. exponent and sign bits. 52 is the mantissa it count.
> Source/JavaScriptCore/runtime/JSBigInt.cpp:2257 > + int32_t mantissaBitsUnset = shiftAmount - 12;
This equation was unclear to me at first, but after it working it out, I see that it's correct. Can you put the following in a comment her to explain how we derived this equation? unsetBits = 64 - setBits - 12 // 12 for non-mantissa bits setBits = 64 - (msdLeadingZeros + 1 + bitsNotAvailableDueToDigitSize); // 1 for hidden mantissa bit. = 64 - (msdLeadingZeros + 1 + (64 - digitBits)) = 64 - shiftAmount Hence, unsetBits = 64 - (64 - shiftAmount) - 12 = shiftAmount - 12
> Source/JavaScriptCore/runtime/JSBigInt.cpp:2266 > + if (mantissaBitsUnset >= static_cast<int32_t>(digitBits) && digitIndex > 0) { > + digitIndex--; > + currentDigit = static_cast<uint64_t>(bigInt->digit(digitIndex)); > + mantissa |= (currentDigit << (mantissaBitsUnset - digitBits)); > + mantissaBitsUnset -= digitBits; > + }
Can you wrap this in a "if constexpr (digitBits < 64)"? This code should be a no-op for 64 bit targets.
> Source/JavaScriptCore/runtime/JSBigInt.cpp:2292 > + uint64_t doubleBits = signBit | exponent | mantissa;
Can you add ASSERTs here to confirm that we didn't have a bug that results in any of the 3 components exceeding their bit boundaries? ASSERT(doubleBits & (1 << 63) == signBit); ASSERT(doubleBits & (0x7ff << 52) == exponent); ASSERT(doubleBits & ((1 << 52) - 1) == mantissa);
> Source/JavaScriptCore/runtime/JSBigInt.h:280 > + static constexpr unsigned doublePhysicalSignificandSize = 52;
You're using a mix of "Significand" and "mantissa" in this patch. Can you stick with just one? Maybe call this doublePhysicalMantissaSize instead?
> Source/JavaScriptCore/runtime/NumberConstructor.cpp:100 > + numeric = JSBigInt::toNumber(numeric);
Can you ASSERT(numeric.isBigInt()) at the top here?
Mark Lam
Comment 8
2020-04-27 11:41:29 PDT
Comment on
attachment 397660
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=397660&action=review
> JSTests/stress/number-constructor-bigint.js:29 > +// Around Infinity.
Can you also add some cases for mantissa rounding both near infinity (may rounD to infinity) and not near infinity?
Mark Lam
Comment 9
2020-04-27 14:23:47 PDT
Comment on
attachment 397660
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=397660&action=review
r=me
> Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:3102 > #if USE(BIGINT32)
Let's move this #if up around the "if (node->op() == CallNumberConstructor) {".
> Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:3109 > #endif
Move below } below.
Yusuke Suzuki
Comment 10
2020-04-27 21:26:47 PDT
Comment on
attachment 397660
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=397660&action=review
>> Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:3102 >> #if USE(BIGINT32) > > Let's move this #if up around the "if (node->op() == CallNumberConstructor) {".
Done.
>> Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:3109 >> #endif > > Move below } below.
Done
>> Source/JavaScriptCore/runtime/JSBigInt.cpp:2256 >> + mantissa >>= 12; // (12 = 64 - 52) (double's mantissa bit count). > > 12 is the non-mantissa bit count, i.e. exponent and sign bits. 52 is the mantissa it count.
Fixed.
>> Source/JavaScriptCore/runtime/JSBigInt.cpp:2266 >> + } > > Can you wrap this in a "if constexpr (digitBits < 64)"? This code should be a no-op for 64 bit targets.
Sounds nice! Fixed.
>> Source/JavaScriptCore/runtime/JSBigInt.cpp:2292 >> + uint64_t doubleBits = signBit | exponent | mantissa; > > Can you add ASSERTs here to confirm that we didn't have a bug that results in any of the 3 components exceeding their bit boundaries? > ASSERT(doubleBits & (1 << 63) == signBit); > ASSERT(doubleBits & (0x7ff << 52) == exponent); > ASSERT(doubleBits & ((1 << 52) - 1) == mantissa);
Sounds nice, fixed.
>> Source/JavaScriptCore/runtime/JSBigInt.h:280 >> + static constexpr unsigned doublePhysicalSignificandSize = 52; > > You're using a mix of "Significand" and "mantissa" in this patch. Can you stick with just one? Maybe call this doublePhysicalMantissaSize instead?
Fixed, nice.
>> Source/JavaScriptCore/runtime/NumberConstructor.cpp:100 >> + numeric = JSBigInt::toNumber(numeric); > > Can you ASSERT(numeric.isBigInt()) at the top here?
Sounds good. Fixed.
>> JSTests/stress/number-constructor-bigint.js:29 >> +// Around Infinity. > > Can you also add some cases for mantissa rounding both near infinity (may rounD to infinity) and not near infinity?
near infinity thing is already added (`shouldBe(Number(0x3fffffffffffffn << 969n), 8.98846567431158e+307);`), I'll add non-near infinity case.
Yusuke Suzuki
Comment 11
2020-04-27 21:27:30 PDT
Comment on
attachment 397660
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=397660&action=review
>> Source/JavaScriptCore/runtime/JSBigInt.cpp:2257 >> + int32_t mantissaBitsUnset = shiftAmount - 12; > > This equation was unclear to me at first, but after it working it out, I see that it's correct. Can you put the following in a comment her to explain how we derived this equation? > > unsetBits = 64 - setBits - 12 // 12 for non-mantissa bits > setBits = 64 - (msdLeadingZeros + 1 + bitsNotAvailableDueToDigitSize); // 1 for hidden mantissa bit. > = 64 - (msdLeadingZeros + 1 + (64 - digitBits)) > = 64 - shiftAmount > Hence, unsetBits = 64 - (64 - shiftAmount) - 12 = shiftAmount - 12
Added, thanks!
Yusuke Suzuki
Comment 12
2020-04-27 22:04:23 PDT
Created
attachment 397805
[details]
Patch for landing
Yusuke Suzuki
Comment 13
2020-04-28 11:04:58 PDT
Committed
r260834
: <
https://trac.webkit.org/changeset/260834
>
Radar WebKit Bug Importer
Comment 14
2020-04-28 11:05:16 PDT
<
rdar://problem/62531125
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug