Commit e110b59c authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[bigint] Fix early-return in asIntN

For "top digit" (of the result) comparison to be applicable, we must
also check that there are no further digits in the source.

Bug: v8:7150
Change-Id: I6ad317f6f600e11fef59b9907da1055e5586a3a8
Reviewed-on: https://chromium-review.googlesource.com/804639Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49846}
parent aaa7c4c9
......@@ -1928,12 +1928,13 @@ Handle<BigInt> BigInt::AsIntN(uint64_t n, Handle<BigInt> x) {
if (x->is_zero()) return x;
if (n == 0) return MutableBigInt::Zero(x->GetIsolate());
uint64_t needed_length = (n + kDigitBits - 1) / kDigitBits;
uint64_t x_length = static_cast<uint64_t>(x->length());
// If {x} has less than {n} bits, return it directly.
if (static_cast<uint64_t>(x->length()) < needed_length) return x;
if (x_length < needed_length) return x;
DCHECK_LE(needed_length, kMaxInt);
digit_t top_digit = x->digit(static_cast<int>(needed_length) - 1);
digit_t compare_digit = static_cast<digit_t>(1) << ((n - 1) % kDigitBits);
if (top_digit < compare_digit) return x;
if (x_length == needed_length && top_digit < compare_digit) return x;
// Otherwise we have to truncate (which is a no-op in the special case
// of x == -2^(n-1)), and determine the right sign. We also might have
// to subtract from 2^n to simulate having two's complement representation.
......
......@@ -145,6 +145,8 @@
}{
assertThrows(() => BigInt.asIntN(3, 12), TypeError);
assertEquals(-4n, BigInt.asIntN(3, "12"));
assertEquals(0x123456789abcdefn,
BigInt.asIntN(64, 0xabcdef0123456789abcdefn));
}
// BigInt.asUintN
......
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