tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

BigIntType.cpp (125738B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /*
      8 * Portions of this code taken from WebKit, whose copyright is as follows:
      9 *
     10 *   Copyright (C) 2017 Caio Lima <ticaiolima@gmail.com>
     11 *   Copyright (C) 2017-2018 Apple Inc. All rights reserved.
     12 *
     13 *   Redistribution and use in source and binary forms, with or without
     14 *   modification, are permitted provided that the following conditions
     15 *   are met:
     16 *   1. Redistributions of source code must retain the above copyright
     17 *      notice, this list of conditions and the following disclaimer.
     18 *   2. Redistributions in binary form must reproduce the above copyright
     19 *      notice, this list of conditions and the following disclaimer in the
     20 *      documentation and/or other materials provided with the distribution.
     21 *
     22 *   THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     23 *   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24 *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     25 *   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     26 *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     27 *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     28 *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     29 *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     30 *   OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     31 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     32 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33 *
     34 * Portions of this code taken from V8, whose copyright notice is as follows:
     35 *
     36 *   Copyright 2017 the V8 project authors. All rights reserved.
     37 *   Redistribution and use in source and binary forms, with or without
     38 *   modification, are permitted provided that the following conditions are
     39 *   met:
     40 *       * Redistributions of source code must retain the above copyright
     41 *         notice, this list of conditions and the following disclaimer.
     42 *       * Redistributions in binary form must reproduce the above
     43 *         copyright notice, this list of conditions and the following
     44 *         disclaimer in the documentation and/or other materials provided
     45 *         with the distribution.
     46 *       * Neither the name of Google Inc. nor the names of its
     47 *         contributors may be used to endorse or promote products derived
     48 *         from this software without specific prior written permission.
     49 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     50 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     51 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     52 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     53 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     54 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     55 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     56 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     57 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     58 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     59 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     60 *
     61 * Portions of this code taken from Dart, whose copyright notice is as follows:
     62 *
     63 *   Copyright (c) 2014 the Dart project authors.  Please see the AUTHORS file
     64 * [1] for details. All rights reserved. Use of this source code is governed by
     65 * a BSD-style license that can be found in the LICENSE file [2].
     66 *
     67 *   [1] https://github.com/dart-lang/sdk/blob/master/AUTHORS
     68 *   [2] https://github.com/dart-lang/sdk/blob/master/LICENSE
     69 *
     70 * Portions of this code taken from Go, whose copyright notice is as follows:
     71 *
     72 *   Copyright 2009 The Go Authors. All rights reserved.
     73 *   Use of this source code is governed by a BSD-style
     74 *   license that can be found in the LICENSE file [3].
     75 *
     76 *   [3] https://golang.org/LICENSE
     77 */
     78 
     79 #include "vm/BigIntType.h"
     80 
     81 #include "mozilla/Casting.h"
     82 #include "mozilla/CheckedArithmetic.h"
     83 #include "mozilla/CheckedInt.h"
     84 #include "mozilla/FloatingPoint.h"
     85 #include "mozilla/HashFunctions.h"
     86 #include "mozilla/MathAlgorithms.h"
     87 #include "mozilla/Maybe.h"
     88 #include "mozilla/MemoryChecking.h"
     89 #include "mozilla/Range.h"
     90 #include "mozilla/RangedPtr.h"
     91 #include "mozilla/Span.h"  // mozilla::Span
     92 #include "mozilla/TextUtils.h"
     93 #include "mozilla/Try.h"
     94 #include "mozilla/WrappingOperations.h"
     95 
     96 #include <charconv>
     97 #include <functional>
     98 #include <limits>
     99 #include <memory>
    100 #include <type_traits>  // std::is_same_v
    101 
    102 #include "jsnum.h"
    103 
    104 #include "gc/GCEnum.h"
    105 #include "js/BigInt.h"
    106 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
    107 #include "js/Printer.h"               // js::GenericPrinter
    108 #include "js/StableStringChars.h"
    109 #include "js/Utility.h"
    110 #include "util/DifferentialTesting.h"
    111 #include "vm/JSONPrinter.h"  // js::JSONPrinter
    112 #include "vm/StaticStrings.h"
    113 
    114 #include "gc/BufferAllocator-inl.h"
    115 #include "gc/GCContext-inl.h"
    116 #include "gc/Nursery-inl.h"
    117 #include "vm/JSContext-inl.h"
    118 #include "vm/StringType-inl.h"
    119 
    120 using namespace js;
    121 
    122 using JS::AutoStableStringChars;
    123 using mozilla::Abs;
    124 using mozilla::AssertedCast;
    125 using mozilla::Maybe;
    126 using mozilla::NegativeInfinity;
    127 using mozilla::Nothing;
    128 using mozilla::PositiveInfinity;
    129 using mozilla::Range;
    130 using mozilla::RangedPtr;
    131 using mozilla::Some;
    132 using mozilla::WrapToSigned;
    133 
    134 static inline unsigned DigitLeadingZeroes(BigInt::Digit x) {
    135  return sizeof(x) == 4 ? mozilla::CountLeadingZeroes32(x)
    136                        : mozilla::CountLeadingZeroes64(x);
    137 }
    138 
    139 #ifdef DEBUG
    140 static bool HasLeadingZeroes(const BigInt* bi) {
    141  return bi->digitLength() > 0 && bi->digit(bi->digitLength() - 1) == 0;
    142 }
    143 #endif
    144 
    145 BigInt* BigInt::createUninitialized(JSContext* cx, size_t digitLength,
    146                                    bool isNegative, gc::Heap heap) {
    147  if (digitLength > MaxDigitLength) {
    148    ReportOversizedAllocation(cx, JSMSG_BIGINT_TOO_LARGE);
    149    return nullptr;
    150  }
    151 
    152  BigInt* x = cx->newCell<BigInt>(heap);
    153  if (!x) {
    154    return nullptr;
    155  }
    156 
    157  x->setLengthAndFlags(digitLength, isNegative ? SignBit : 0);
    158 
    159  MOZ_ASSERT(x->digitLength() == digitLength);
    160  MOZ_ASSERT(x->isNegative() == isNegative);
    161 
    162  if (digitLength > InlineDigitsLength) {
    163    x->heapDigits_ = js::AllocateCellBuffer<Digit>(cx, x, digitLength);
    164    if (!x->heapDigits_) {
    165      // |x| is partially initialized, expose it as a BigInt using inline digits
    166      // to the GC.
    167      x->setLengthAndFlags(0, 0);
    168      return nullptr;
    169    }
    170  }
    171 
    172  return x;
    173 }
    174 
    175 void BigInt::initializeDigitsToZero() {
    176  auto digs = digits();
    177  std::uninitialized_fill_n(digs.begin(), digs.Length(), 0);
    178 }
    179 
    180 js::HashNumber BigInt::hash() const {
    181  js::HashNumber h =
    182      mozilla::HashBytes(digits().data(), digitLength() * sizeof(Digit));
    183  return mozilla::AddToHash(h, isNegative());
    184 }
    185 
    186 size_t BigInt::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
    187  return hasInlineDigits() ? 0 : gc::GetAllocSize(zone(), heapDigits_);
    188 }
    189 
    190 size_t BigInt::sizeOfExcludingThisInNursery(
    191    mozilla::MallocSizeOf mallocSizeOf) const {
    192  MOZ_ASSERT(!isTenured());
    193 
    194  if (hasInlineDigits()) {
    195    return 0;
    196  }
    197 
    198  const Nursery& nursery = runtimeFromMainThread()->gc.nursery();
    199  if (nursery.isInside(heapDigits_)) {
    200    // Buffer allocations are aligned to the size of JS::Value.
    201    return RoundUp(digitLength() * sizeof(Digit), sizeof(Value));
    202  }
    203 
    204  return gc::GetAllocSize(zone(), heapDigits_);
    205 }
    206 
    207 BigInt* BigInt::zero(JSContext* cx, gc::Heap heap) {
    208  return createUninitialized(cx, 0, false, heap);
    209 }
    210 
    211 BigInt* BigInt::createFromDigit(JSContext* cx, Digit d, bool isNegative,
    212                                gc::Heap heap) {
    213  MOZ_ASSERT(d != 0);
    214  BigInt* res = createUninitialized(cx, 1, isNegative, heap);
    215  if (!res) {
    216    return nullptr;
    217  }
    218  res->setDigit(0, d);
    219  return res;
    220 }
    221 
    222 BigInt* BigInt::one(JSContext* cx) { return createFromDigit(cx, 1, false); }
    223 
    224 BigInt* BigInt::negativeOne(JSContext* cx) {
    225  return createFromDigit(cx, 1, true);
    226 }
    227 
    228 BigInt* BigInt::createFromNonZeroRawUint64(JSContext* cx, uint64_t n,
    229                                           bool isNegative) {
    230  MOZ_ASSERT(n != 0);
    231 
    232  size_t resultLength = 1;
    233  if (DigitBits == 32 && (n >> 32) != 0) {
    234    resultLength = 2;
    235  }
    236 
    237  BigInt* result = createUninitialized(cx, resultLength, isNegative);
    238  if (!result) {
    239    return nullptr;
    240  }
    241  result->setDigit(0, n);
    242  if (DigitBits == 32 && resultLength > 1) {
    243    result->setDigit(1, n >> 32);
    244  }
    245 
    246  MOZ_ASSERT(!HasLeadingZeroes(result));
    247  return result;
    248 }
    249 
    250 BigInt* BigInt::neg(JSContext* cx, HandleBigInt x) {
    251  if (x->isZero()) {
    252    return x;
    253  }
    254 
    255  BigInt* result = copy(cx, x);
    256  if (!result) {
    257    return nullptr;
    258  }
    259  result->toggleHeaderFlagBit(SignBit);
    260  return result;
    261 }
    262 
    263 #if !defined(JS_64BIT)
    264 #  define HAVE_TWO_DIGIT 1
    265 using TwoDigit = uint64_t;
    266 #elif defined(__SIZEOF_INT128__)
    267 #  define HAVE_TWO_DIGIT 1
    268 using TwoDigit = __uint128_t;
    269 #endif
    270 
    271 inline BigInt::Digit BigInt::digitMul(Digit a, Digit b, Digit* high) {
    272 #if defined(HAVE_TWO_DIGIT)
    273  TwoDigit result = static_cast<TwoDigit>(a) * static_cast<TwoDigit>(b);
    274  *high = result >> DigitBits;
    275 
    276  return static_cast<Digit>(result);
    277 #else
    278  // Multiply in half-pointer-sized chunks.
    279  // For inputs [AH AL]*[BH BL], the result is:
    280  //
    281  //            [AL*BL]  // rLow
    282  //    +    [AL*BH]     // rMid1
    283  //    +    [AH*BL]     // rMid2
    284  //    + [AH*BH]        // rHigh
    285  //    = [R4 R3 R2 R1]  // high = [R4 R3], low = [R2 R1]
    286  //
    287  // Where of course we must be careful with carries between the columns.
    288  Digit aLow = a & HalfDigitMask;
    289  Digit aHigh = a >> HalfDigitBits;
    290  Digit bLow = b & HalfDigitMask;
    291  Digit bHigh = b >> HalfDigitBits;
    292 
    293  Digit rLow = aLow * bLow;
    294  Digit rMid1 = aLow * bHigh;
    295  Digit rMid2 = aHigh * bLow;
    296  Digit rHigh = aHigh * bHigh;
    297 
    298  Digit carry = 0;
    299  Digit low = digitAdd(rLow, rMid1 << HalfDigitBits, &carry);
    300  low = digitAdd(low, rMid2 << HalfDigitBits, &carry);
    301 
    302  *high = (rMid1 >> HalfDigitBits) + (rMid2 >> HalfDigitBits) + rHigh + carry;
    303 
    304  return low;
    305 #endif
    306 }
    307 
    308 BigInt::Digit BigInt::digitDiv(Digit high, Digit low, Digit divisor,
    309                               Digit* remainder) {
    310  MOZ_ASSERT(high < divisor, "division must not overflow");
    311 #if defined(__x86_64__)
    312  Digit quotient;
    313  Digit rem;
    314  __asm__("divq  %[divisor]"
    315          // Outputs: `quotient` will be in rax, `rem` in rdx.
    316          : "=a"(quotient), "=d"(rem)
    317          // Inputs: put `high` into rdx, `low` into rax, and `divisor` into
    318          // any register or stack slot.
    319          : "d"(high), "a"(low), [divisor] "rm"(divisor));
    320  *remainder = rem;
    321  return quotient;
    322 #elif defined(__i386__)
    323  Digit quotient;
    324  Digit rem;
    325  __asm__("divl  %[divisor]"
    326          // Outputs: `quotient` will be in eax, `rem` in edx.
    327          : "=a"(quotient), "=d"(rem)
    328          // Inputs: put `high` into edx, `low` into eax, and `divisor` into
    329          // any register or stack slot.
    330          : "d"(high), "a"(low), [divisor] "rm"(divisor));
    331  *remainder = rem;
    332  return quotient;
    333 #else
    334  static constexpr Digit HalfDigitBase = 1ull << HalfDigitBits;
    335  // Adapted from Warren, Hacker's Delight, p. 152.
    336  unsigned s = DigitLeadingZeroes(divisor);
    337  // If `s` is DigitBits here, it causes an undefined behavior.
    338  // But `s` is never DigitBits since `divisor` is never zero here.
    339  MOZ_ASSERT(s != DigitBits);
    340  divisor <<= s;
    341 
    342  Digit vn1 = divisor >> HalfDigitBits;
    343  Digit vn0 = divisor & HalfDigitMask;
    344 
    345  // `sZeroMask` which is 0 if s == 0 and all 1-bits otherwise.
    346  //
    347  // `s` can be 0. If `s` is 0, performing "low >> (DigitBits - s)" must not
    348  // be done since it causes an undefined behavior since `>> DigitBits` is
    349  // undefined in C++. Quoted from C++ spec, "The type of the result is that of
    350  // the promoted left operand.
    351  //
    352  // The behavior is undefined if the right operand is negative, or greater
    353  // than or equal to the length in bits of the promoted left operand". We
    354  // mask the right operand of the shift by `shiftMask` (`DigitBits - 1`),
    355  // which makes `DigitBits - 0` zero.
    356  //
    357  // This shifting produces a value which covers 0 < `s` <= (DigitBits - 1)
    358  // cases. `s` == DigitBits never happen as we asserted.  Since `sZeroMask`
    359  // clears the value in the case of `s` == 0, `s` == 0 case is also covered.
    360  static_assert(sizeof(intptr_t) == sizeof(Digit),
    361                "unexpected size of BigInt::Digit");
    362  Digit sZeroMask =
    363      static_cast<Digit>((-static_cast<intptr_t>(s)) >> (DigitBits - 1));
    364  static constexpr unsigned shiftMask = DigitBits - 1;
    365  Digit un32 =
    366      (high << s) | ((low >> ((DigitBits - s) & shiftMask)) & sZeroMask);
    367 
    368  Digit un10 = low << s;
    369  Digit un1 = un10 >> HalfDigitBits;
    370  Digit un0 = un10 & HalfDigitMask;
    371  Digit q1 = un32 / vn1;
    372  Digit rhat = un32 - q1 * vn1;
    373 
    374  while (q1 >= HalfDigitBase || q1 * vn0 > rhat * HalfDigitBase + un1) {
    375    q1--;
    376    rhat += vn1;
    377    if (rhat >= HalfDigitBase) {
    378      break;
    379    }
    380  }
    381 
    382  Digit un21 = un32 * HalfDigitBase + un1 - q1 * divisor;
    383  Digit q0 = un21 / vn1;
    384  rhat = un21 - q0 * vn1;
    385 
    386  while (q0 >= HalfDigitBase || q0 * vn0 > rhat * HalfDigitBase + un0) {
    387    q0--;
    388    rhat += vn1;
    389    if (rhat >= HalfDigitBase) {
    390      break;
    391    }
    392  }
    393 
    394  *remainder = (un21 * HalfDigitBase + un0 - q0 * divisor) >> s;
    395  return q1 * HalfDigitBase + q0;
    396 #endif
    397 }
    398 
    399 // Multiplies `source` with `factor` and adds `summand` to the result.
    400 // `result` and `source` may be the same BigInt for inplace modification.
    401 void BigInt::internalMultiplyAdd(const BigInt* source, Digit factor,
    402                                 Digit summand, unsigned n, BigInt* result) {
    403  MOZ_ASSERT(source->digitLength() >= n);
    404  MOZ_ASSERT(result->digitLength() >= n);
    405 
    406  Digit carry = summand;
    407  Digit high = 0;
    408  for (unsigned i = 0; i < n; i++) {
    409    Digit current = source->digit(i);
    410    Digit newCarry = 0;
    411 
    412    // Compute this round's multiplication.
    413    Digit newHigh = 0;
    414    current = digitMul(current, factor, &newHigh);
    415 
    416    // Add last round's carryovers.
    417    current = digitAdd(current, high, &newCarry);
    418    current = digitAdd(current, carry, &newCarry);
    419 
    420    // Store result and prepare for next round.
    421    result->setDigit(i, current);
    422    carry = newCarry;
    423    high = newHigh;
    424  }
    425 
    426  if (result->digitLength() > n) {
    427    result->setDigit(n++, carry + high);
    428 
    429    // Current callers don't pass in such large results, but let's be robust.
    430    while (n < result->digitLength()) {
    431      result->setDigit(n++, 0);
    432    }
    433  } else {
    434    MOZ_ASSERT(!(carry + high));
    435  }
    436 }
    437 
    438 // Multiplies `this` with `factor` and adds `summand` to the result.
    439 void BigInt::inplaceMultiplyAdd(Digit factor, Digit summand) {
    440  internalMultiplyAdd(this, factor, summand, digitLength(), this);
    441 }
    442 
    443 // Multiplies `multiplicand` with `multiplier` and adds the result to
    444 // `accumulator`, starting at `accumulatorIndex` for the least-significant
    445 // digit.  Callers must ensure that `accumulator`'s digitLength and
    446 // corresponding digit storage is long enough to hold the result.
    447 void BigInt::multiplyAccumulate(const BigInt* multiplicand, Digit multiplier,
    448                                BigInt* accumulator,
    449                                unsigned accumulatorIndex) {
    450  MOZ_ASSERT(accumulator->digitLength() >
    451             multiplicand->digitLength() + accumulatorIndex);
    452  if (!multiplier) {
    453    return;
    454  }
    455 
    456  Digit carry = 0;
    457  Digit high = 0;
    458  for (unsigned i = 0; i < multiplicand->digitLength();
    459       i++, accumulatorIndex++) {
    460    Digit acc = accumulator->digit(accumulatorIndex);
    461    Digit newCarry = 0;
    462 
    463    // Add last round's carryovers.
    464    acc = digitAdd(acc, high, &newCarry);
    465    acc = digitAdd(acc, carry, &newCarry);
    466 
    467    // Compute this round's multiplication.
    468    Digit multiplicandDigit = multiplicand->digit(i);
    469    Digit low = digitMul(multiplier, multiplicandDigit, &high);
    470    acc = digitAdd(acc, low, &newCarry);
    471 
    472    // Store result and prepare for next round.
    473    accumulator->setDigit(accumulatorIndex, acc);
    474    carry = newCarry;
    475  }
    476 
    477  while (carry || high) {
    478    MOZ_ASSERT(accumulatorIndex < accumulator->digitLength());
    479    Digit acc = accumulator->digit(accumulatorIndex);
    480    Digit newCarry = 0;
    481    acc = digitAdd(acc, high, &newCarry);
    482    high = 0;
    483    acc = digitAdd(acc, carry, &newCarry);
    484    accumulator->setDigit(accumulatorIndex, acc);
    485    carry = newCarry;
    486    accumulatorIndex++;
    487  }
    488 }
    489 
    490 inline int8_t BigInt::absoluteCompare(const BigInt* x, const BigInt* y) {
    491  MOZ_ASSERT(!HasLeadingZeroes(x));
    492  MOZ_ASSERT(!HasLeadingZeroes(y));
    493 
    494  // Sanity checks to catch negative zeroes escaping to the wild.
    495  MOZ_ASSERT(!x->isNegative() || !x->isZero());
    496  MOZ_ASSERT(!y->isNegative() || !y->isZero());
    497 
    498  int diff = x->digitLength() - y->digitLength();
    499  if (diff) {
    500    return diff < 0 ? -1 : 1;
    501  }
    502 
    503  int i = x->digitLength() - 1;
    504  while (i >= 0 && x->digit(i) == y->digit(i)) {
    505    i--;
    506  }
    507 
    508  if (i < 0) {
    509    return 0;
    510  }
    511 
    512  return x->digit(i) > y->digit(i) ? 1 : -1;
    513 }
    514 
    515 BigInt* BigInt::absoluteAdd(JSContext* cx, HandleBigInt x, HandleBigInt y,
    516                            bool resultNegative) {
    517  bool swap = x->digitLength() < y->digitLength();
    518  // Ensure `left` has at least as many digits as `right`.
    519  HandleBigInt& left = swap ? y : x;
    520  HandleBigInt& right = swap ? x : y;
    521 
    522  if (left->isZero()) {
    523    MOZ_ASSERT(right->isZero());
    524    return left;
    525  }
    526 
    527  if (right->isZero()) {
    528    return resultNegative == left->isNegative() ? left : neg(cx, left);
    529  }
    530 
    531  // Fast path for the likely-common case of up to a uint64_t of magnitude.
    532  if (left->absFitsInUint64()) {
    533    MOZ_ASSERT(right->absFitsInUint64());
    534 
    535    uint64_t lhs = left->uint64FromAbsNonZero();
    536    uint64_t rhs = right->uint64FromAbsNonZero();
    537 
    538    uint64_t res = lhs + rhs;
    539    bool overflow = res < lhs;
    540    MOZ_ASSERT(res != 0 || overflow);
    541 
    542    size_t resultLength = 1;
    543    if (DigitBits == 32) {
    544      if (overflow) {
    545        resultLength = 3;
    546      } else if (res >> 32) {
    547        resultLength = 2;
    548      }
    549    } else {
    550      if (overflow) {
    551        resultLength = 2;
    552      }
    553    }
    554    BigInt* result = createUninitialized(cx, resultLength, resultNegative);
    555    if (!result) {
    556      return nullptr;
    557    }
    558    result->setDigit(0, res);
    559    if (DigitBits == 32 && resultLength > 1) {
    560      result->setDigit(1, res >> 32);
    561    }
    562    if (overflow) {
    563      constexpr size_t overflowIndex = DigitBits == 32 ? 2 : 1;
    564      result->setDigit(overflowIndex, 1);
    565    }
    566 
    567    MOZ_ASSERT(!HasLeadingZeroes(result));
    568    return result;
    569  }
    570 
    571  BigInt* result =
    572      createUninitialized(cx, left->digitLength() + 1, resultNegative);
    573  if (!result) {
    574    return nullptr;
    575  }
    576  Digit carry = 0;
    577  unsigned i = 0;
    578  for (; i < right->digitLength(); i++) {
    579    Digit newCarry = 0;
    580    Digit sum = digitAdd(left->digit(i), right->digit(i), &newCarry);
    581    sum = digitAdd(sum, carry, &newCarry);
    582    result->setDigit(i, sum);
    583    carry = newCarry;
    584  }
    585 
    586  for (; i < left->digitLength(); i++) {
    587    Digit newCarry = 0;
    588    Digit sum = digitAdd(left->digit(i), carry, &newCarry);
    589    result->setDigit(i, sum);
    590    carry = newCarry;
    591  }
    592 
    593  result->setDigit(i, carry);
    594 
    595  return destructivelyTrimHighZeroDigits(cx, result);
    596 }
    597 
    598 BigInt* BigInt::absoluteSub(JSContext* cx, HandleBigInt x, HandleBigInt y,
    599                            bool resultNegative) {
    600  MOZ_ASSERT(x->digitLength() >= y->digitLength());
    601  MOZ_ASSERT(absoluteCompare(x, y) > 0);
    602  MOZ_ASSERT(!x->isZero());
    603 
    604  if (y->isZero()) {
    605    return resultNegative == x->isNegative() ? x : neg(cx, x);
    606  }
    607 
    608  // Fast path for the likely-common case of up to a uint64_t of magnitude.
    609  if (x->absFitsInUint64()) {
    610    MOZ_ASSERT(y->absFitsInUint64());
    611 
    612    uint64_t lhs = x->uint64FromAbsNonZero();
    613    uint64_t rhs = y->uint64FromAbsNonZero();
    614    MOZ_ASSERT(lhs > rhs);
    615 
    616    uint64_t res = lhs - rhs;
    617    MOZ_ASSERT(res != 0);
    618 
    619    return createFromNonZeroRawUint64(cx, res, resultNegative);
    620  }
    621 
    622  BigInt* result = createUninitialized(cx, x->digitLength(), resultNegative);
    623  if (!result) {
    624    return nullptr;
    625  }
    626  Digit borrow = 0;
    627  unsigned i = 0;
    628  for (; i < y->digitLength(); i++) {
    629    Digit newBorrow = 0;
    630    Digit difference = digitSub(x->digit(i), y->digit(i), &newBorrow);
    631    difference = digitSub(difference, borrow, &newBorrow);
    632    result->setDigit(i, difference);
    633    borrow = newBorrow;
    634  }
    635 
    636  for (; i < x->digitLength(); i++) {
    637    Digit newBorrow = 0;
    638    Digit difference = digitSub(x->digit(i), borrow, &newBorrow);
    639    result->setDigit(i, difference);
    640    borrow = newBorrow;
    641  }
    642 
    643  MOZ_ASSERT(!borrow);
    644  return destructivelyTrimHighZeroDigits(cx, result);
    645 }
    646 
    647 // Divides `x` by `divisor`, returning the result in `quotient` and `remainder`.
    648 // Mathematically, the contract is:
    649 //
    650 //   quotient = (x - remainder) / divisor, with 0 <= remainder < divisor.
    651 //
    652 // If `quotient` is an empty handle, an appropriately sized BigInt will be
    653 // allocated for it; otherwise the caller must ensure that it is big enough.
    654 // `quotient` can be the same as `x` for an in-place division. `quotient` can
    655 // also be `Nothing()` if the caller is only interested in the remainder.
    656 //
    657 // This function returns false if `quotient` is an empty handle, but allocating
    658 // the quotient failed.  Otherwise it returns true, indicating success.
    659 bool BigInt::absoluteDivWithDigitDivisor(
    660    JSContext* cx, HandleBigInt x, Digit divisor,
    661    const Maybe<MutableHandleBigInt>& quotient, Digit* remainder,
    662    bool quotientNegative) {
    663  MOZ_ASSERT(divisor);
    664 
    665  MOZ_ASSERT(!x->isZero());
    666  *remainder = 0;
    667  if (divisor == 1) {
    668    if (quotient) {
    669      BigInt* q;
    670      if (x->isNegative() == quotientNegative) {
    671        q = x;
    672      } else {
    673        q = neg(cx, x);
    674        if (!q) {
    675          return false;
    676        }
    677      }
    678      quotient.value().set(q);
    679    }
    680    return true;
    681  }
    682 
    683  unsigned length = x->digitLength();
    684  if (quotient) {
    685    if (!quotient.value()) {
    686      BigInt* q = createUninitialized(cx, length, quotientNegative);
    687      if (!q) {
    688        return false;
    689      }
    690      quotient.value().set(q);
    691    }
    692 
    693    for (int i = length - 1; i >= 0; i--) {
    694      Digit q = digitDiv(*remainder, x->digit(i), divisor, remainder);
    695      quotient.value()->setDigit(i, q);
    696    }
    697  } else {
    698    for (int i = length - 1; i >= 0; i--) {
    699      digitDiv(*remainder, x->digit(i), divisor, remainder);
    700    }
    701  }
    702 
    703  return true;
    704 }
    705 
    706 // Adds `summand` onto `this`, starting with `summand`'s 0th digit
    707 // at `this`'s `startIndex`'th digit. Returns the "carry" (0 or 1).
    708 BigInt::Digit BigInt::absoluteInplaceAdd(const BigInt* summand,
    709                                         unsigned startIndex) {
    710  Digit carry = 0;
    711  unsigned n = summand->digitLength();
    712  MOZ_ASSERT(digitLength() > startIndex,
    713             "must start adding at an in-range digit");
    714  MOZ_ASSERT(digitLength() - startIndex >= n,
    715             "digits being added to must not extend above the digits in "
    716             "this (except for the returned carry digit)");
    717  for (unsigned i = 0; i < n; i++) {
    718    Digit newCarry = 0;
    719    Digit sum = digitAdd(digit(startIndex + i), summand->digit(i), &newCarry);
    720    sum = digitAdd(sum, carry, &newCarry);
    721    setDigit(startIndex + i, sum);
    722    carry = newCarry;
    723  }
    724 
    725  return carry;
    726 }
    727 
    728 // Subtracts `subtrahend` from this, starting with `subtrahend`'s 0th digit
    729 // at `this`'s `startIndex`-th digit. Returns the "borrow" (0 or 1).
    730 BigInt::Digit BigInt::absoluteInplaceSub(const BigInt* subtrahend,
    731                                         unsigned startIndex) {
    732  Digit borrow = 0;
    733  unsigned n = subtrahend->digitLength();
    734  MOZ_ASSERT(digitLength() > startIndex,
    735             "must start subtracting from an in-range digit");
    736  MOZ_ASSERT(digitLength() - startIndex >= n,
    737             "digits being subtracted from must not extend above the "
    738             "digits in this (except for the returned borrow digit)");
    739  for (unsigned i = 0; i < n; i++) {
    740    Digit newBorrow = 0;
    741    Digit difference =
    742        digitSub(digit(startIndex + i), subtrahend->digit(i), &newBorrow);
    743    difference = digitSub(difference, borrow, &newBorrow);
    744    setDigit(startIndex + i, difference);
    745    borrow = newBorrow;
    746  }
    747 
    748  return borrow;
    749 }
    750 
    751 // Returns whether (factor1 * factor2) > (high << kDigitBits) + low.
    752 inline bool BigInt::productGreaterThan(Digit factor1, Digit factor2, Digit high,
    753                                       Digit low) {
    754  Digit resultHigh;
    755  Digit resultLow = digitMul(factor1, factor2, &resultHigh);
    756  return resultHigh > high || (resultHigh == high && resultLow > low);
    757 }
    758 
    759 void BigInt::inplaceRightShiftLowZeroBits(unsigned shift) {
    760  MOZ_ASSERT(shift < DigitBits);
    761  MOZ_ASSERT(!(digit(0) & ((static_cast<Digit>(1) << shift) - 1)),
    762             "should only be shifting away zeroes");
    763 
    764  if (!shift) {
    765    return;
    766  }
    767 
    768  Digit carry = digit(0) >> shift;
    769  unsigned last = digitLength() - 1;
    770  for (unsigned i = 0; i < last; i++) {
    771    Digit d = digit(i + 1);
    772    setDigit(i, (d << (DigitBits - shift)) | carry);
    773    carry = d >> shift;
    774  }
    775  setDigit(last, carry);
    776 }
    777 
    778 // Always copies the input, even when `shift` == 0.
    779 BigInt* BigInt::absoluteLeftShiftAlwaysCopy(JSContext* cx, HandleBigInt x,
    780                                            unsigned shift,
    781                                            LeftShiftMode mode) {
    782  MOZ_ASSERT(shift < DigitBits);
    783  MOZ_ASSERT(!x->isZero());
    784 
    785  unsigned n = x->digitLength();
    786  unsigned resultLength = mode == LeftShiftMode::AlwaysAddOneDigit ? n + 1 : n;
    787  BigInt* result = createUninitialized(cx, resultLength, x->isNegative());
    788  if (!result) {
    789    return nullptr;
    790  }
    791 
    792  if (!shift) {
    793    for (unsigned i = 0; i < n; i++) {
    794      result->setDigit(i, x->digit(i));
    795    }
    796    if (mode == LeftShiftMode::AlwaysAddOneDigit) {
    797      result->setDigit(n, 0);
    798    }
    799 
    800    return result;
    801  }
    802 
    803  Digit carry = 0;
    804  for (unsigned i = 0; i < n; i++) {
    805    Digit d = x->digit(i);
    806    result->setDigit(i, (d << shift) | carry);
    807    carry = d >> (DigitBits - shift);
    808  }
    809 
    810  if (mode == LeftShiftMode::AlwaysAddOneDigit) {
    811    result->setDigit(n, carry);
    812  } else {
    813    MOZ_ASSERT(mode == LeftShiftMode::SameSizeResult);
    814    MOZ_ASSERT(!carry);
    815  }
    816 
    817  return result;
    818 }
    819 
    820 // Divides `dividend` by `divisor`, returning the result in `quotient` and
    821 // `remainder`. Mathematically, the contract is:
    822 //
    823 //   quotient = (dividend - remainder) / divisor, with 0 <= remainder < divisor.
    824 //
    825 // Both `quotient` and `remainder` are optional, for callers that are only
    826 // interested in one of them.  See Knuth, Volume 2, section 4.3.1, Algorithm D.
    827 // Also see the overview of the algorithm by Jan Marthedal Rasmussen over at
    828 // https://janmr.com/blog/2014/04/basic-multiple-precision-long-division/.
    829 bool BigInt::absoluteDivWithBigIntDivisor(
    830    JSContext* cx, HandleBigInt dividend, HandleBigInt divisor,
    831    const Maybe<MutableHandleBigInt>& quotient,
    832    const Maybe<MutableHandleBigInt>& remainder, bool isNegative) {
    833  MOZ_ASSERT(divisor->digitLength() >= 2);
    834  MOZ_ASSERT(dividend->digitLength() >= divisor->digitLength());
    835 
    836  // Any early error return is detectable by checking the quotient and/or
    837  // remainder output values.
    838  MOZ_ASSERT(!quotient || !quotient.value());
    839  MOZ_ASSERT(!remainder || !remainder.value());
    840 
    841  // The unusual variable names inside this function are consistent with
    842  // Knuth's book, as well as with Go's implementation of this algorithm.
    843  // Maintaining this consistency is probably more useful than trying to
    844  // come up with more descriptive names for them.
    845  const unsigned n = divisor->digitLength();
    846  const unsigned m = dividend->digitLength() - n;
    847 
    848  RootedTuple<BigInt*, BigInt*, BigInt*, BigInt*> roots(cx);
    849 
    850  // The quotient to be computed.
    851  RootedField<BigInt*, 0> q(roots);
    852  if (quotient) {
    853    q = createUninitialized(cx, m + 1, isNegative);
    854    if (!q) {
    855      return false;
    856    }
    857  }
    858 
    859  // In each iteration, `qhatv` holds `divisor` * `current quotient digit`.
    860  // "v" is the book's name for `divisor`, `qhat` the current quotient digit.
    861  RootedField<BigInt*, 1> qhatv(roots,
    862                                createUninitialized(cx, n + 1, isNegative));
    863  if (!qhatv) {
    864    return false;
    865  }
    866 
    867  // D1.
    868  // Left-shift inputs so that the divisor's MSB is set. This is necessary to
    869  // prevent the digit-wise divisions (see digitDiv call below) from
    870  // overflowing (they take a two digits wide input, and return a one digit
    871  // result).
    872  Digit lastDigit = divisor->digit(n - 1);
    873  unsigned shift = DigitLeadingZeroes(lastDigit);
    874 
    875  RootedField<BigInt*, 2> shiftedDivisor(roots);
    876  if (shift > 0) {
    877    shiftedDivisor = absoluteLeftShiftAlwaysCopy(cx, divisor, shift,
    878                                                 LeftShiftMode::SameSizeResult);
    879    if (!shiftedDivisor) {
    880      return false;
    881    }
    882  } else {
    883    shiftedDivisor = divisor;
    884  }
    885 
    886  // Holds the (continuously updated) remaining part of the dividend, which
    887  // eventually becomes the remainder.
    888  RootedField<BigInt*, 3> u(
    889      roots, absoluteLeftShiftAlwaysCopy(cx, dividend, shift,
    890                                         LeftShiftMode::AlwaysAddOneDigit));
    891  if (!u) {
    892    return false;
    893  }
    894 
    895  // D2.
    896  // Iterate over the dividend's digit (like the "grade school" algorithm).
    897  // `vn1` is the divisor's most significant digit.
    898  Digit vn1 = shiftedDivisor->digit(n - 1);
    899  for (int j = m; j >= 0; j--) {
    900    // D3.
    901    // Estimate the current iteration's quotient digit (see Knuth for details).
    902    // `qhat` is the current quotient digit.
    903    Digit qhat = std::numeric_limits<Digit>::max();
    904 
    905    // `ujn` is the dividend's most significant remaining digit.
    906    Digit ujn = u->digit(j + n);
    907    if (ujn != vn1) {
    908      // `rhat` is the current iteration's remainder.
    909      Digit rhat = 0;
    910      // Estimate the current quotient digit by dividing the most significant
    911      // digits of dividend and divisor. The result will not be too small,
    912      // but could be a bit too large.
    913      qhat = digitDiv(ujn, u->digit(j + n - 1), vn1, &rhat);
    914 
    915      // Decrement the quotient estimate as needed by looking at the next
    916      // digit, i.e. by testing whether
    917      // qhat * v_{n-2} > (rhat << DigitBits) + u_{j+n-2}.
    918      Digit vn2 = shiftedDivisor->digit(n - 2);
    919      Digit ujn2 = u->digit(j + n - 2);
    920      while (productGreaterThan(qhat, vn2, rhat, ujn2)) {
    921        qhat--;
    922        Digit prevRhat = rhat;
    923        rhat += vn1;
    924        // v[n-1] >= 0, so this tests for overflow.
    925        if (rhat < prevRhat) {
    926          break;
    927        }
    928      }
    929    }
    930 
    931    // D4.
    932    // Multiply the divisor with the current quotient digit, and subtract
    933    // it from the dividend. If there was "borrow", then the quotient digit
    934    // was one too high, so we must correct it and undo one subtraction of
    935    // the (shifted) divisor.
    936    internalMultiplyAdd(shiftedDivisor, qhat, 0, n, qhatv);
    937    Digit c = u->absoluteInplaceSub(qhatv, j);
    938    if (c) {
    939      c = u->absoluteInplaceAdd(shiftedDivisor, j);
    940      u->setDigit(j + n, u->digit(j + n) + c);
    941      qhat--;
    942    }
    943 
    944    if (quotient) {
    945      q->setDigit(j, qhat);
    946    }
    947  }
    948 
    949  if (quotient) {
    950    BigInt* bi = destructivelyTrimHighZeroDigits(cx, q);
    951    if (!bi) {
    952      return false;
    953    }
    954    quotient.value().set(q);
    955  }
    956 
    957  if (remainder) {
    958    u->inplaceRightShiftLowZeroBits(shift);
    959    remainder.value().set(u);
    960  }
    961 
    962  return true;
    963 }
    964 
    965 // Helper for Absolute{And,AndNot,Or,Xor}.
    966 // Performs the given binary `op` on digit pairs of `x` and `y`; when the
    967 // end of the shorter of the two is reached, `kind` configures how
    968 // remaining digits are handled.
    969 // Example:
    970 //       y:             [ y2 ][ y1 ][ y0 ]
    971 //       x:       [ x3 ][ x2 ][ x1 ][ x0 ]
    972 //                   |     |     |     |
    973 //                (Fill)  (op)  (op)  (op)
    974 //                   |     |     |     |
    975 //                   v     v     v     v
    976 //  result: [  0 ][ x3 ][ r2 ][ r1 ][ r0 ]
    977 template <BigInt::BitwiseOpKind kind, typename BitwiseOp>
    978 inline BigInt* BigInt::absoluteBitwiseOp(JSContext* cx, HandleBigInt x,
    979                                         HandleBigInt y, BitwiseOp&& op) {
    980  unsigned xLength = x->digitLength();
    981  unsigned yLength = y->digitLength();
    982  unsigned numPairs = std::min(xLength, yLength);
    983  unsigned resultLength;
    984  if (kind == BitwiseOpKind::SymmetricTrim) {
    985    resultLength = numPairs;
    986  } else if (kind == BitwiseOpKind::SymmetricFill) {
    987    resultLength = std::max(xLength, yLength);
    988  } else {
    989    MOZ_ASSERT(kind == BitwiseOpKind::AsymmetricFill);
    990    resultLength = xLength;
    991  }
    992  bool resultNegative = false;
    993 
    994  BigInt* result = createUninitialized(cx, resultLength, resultNegative);
    995  if (!result) {
    996    return nullptr;
    997  }
    998 
    999  unsigned i = 0;
   1000  for (; i < numPairs; i++) {
   1001    result->setDigit(i, op(x->digit(i), y->digit(i)));
   1002  }
   1003 
   1004  if (kind != BitwiseOpKind::SymmetricTrim) {
   1005    BigInt* source = kind == BitwiseOpKind::AsymmetricFill ? x
   1006                     : xLength == i                        ? y
   1007                                                           : x;
   1008    for (; i < resultLength; i++) {
   1009      result->setDigit(i, source->digit(i));
   1010    }
   1011  }
   1012 
   1013  MOZ_ASSERT(i == resultLength);
   1014 
   1015  return destructivelyTrimHighZeroDigits(cx, result);
   1016 }
   1017 
   1018 BigInt* BigInt::absoluteAnd(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   1019  return absoluteBitwiseOp<BitwiseOpKind::SymmetricTrim>(cx, x, y,
   1020                                                         std::bit_and<Digit>());
   1021 }
   1022 
   1023 BigInt* BigInt::absoluteOr(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   1024  return absoluteBitwiseOp<BitwiseOpKind::SymmetricFill>(cx, x, y,
   1025                                                         std::bit_or<Digit>());
   1026 }
   1027 
   1028 BigInt* BigInt::absoluteAndNot(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   1029  auto digitOperation = [](Digit a, Digit b) { return a & ~b; };
   1030  return absoluteBitwiseOp<BitwiseOpKind::AsymmetricFill>(cx, x, y,
   1031                                                          digitOperation);
   1032 }
   1033 
   1034 BigInt* BigInt::absoluteXor(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   1035  return absoluteBitwiseOp<BitwiseOpKind::SymmetricFill>(cx, x, y,
   1036                                                         std::bit_xor<Digit>());
   1037 }
   1038 
   1039 BigInt* BigInt::absoluteAddOne(JSContext* cx, HandleBigInt x,
   1040                               bool resultNegative) {
   1041  unsigned inputLength = x->digitLength();
   1042  // The addition will overflow into a new digit if all existing digits are
   1043  // at maximum.
   1044  bool willOverflow = true;
   1045  for (unsigned i = 0; i < inputLength; i++) {
   1046    if (std::numeric_limits<Digit>::max() != x->digit(i)) {
   1047      willOverflow = false;
   1048      break;
   1049    }
   1050  }
   1051 
   1052  unsigned resultLength = inputLength + willOverflow;
   1053  BigInt* result = createUninitialized(cx, resultLength, resultNegative);
   1054  if (!result) {
   1055    return nullptr;
   1056  }
   1057 
   1058  Digit carry = 1;
   1059  for (unsigned i = 0; i < inputLength; i++) {
   1060    Digit newCarry = 0;
   1061    result->setDigit(i, digitAdd(x->digit(i), carry, &newCarry));
   1062    carry = newCarry;
   1063  }
   1064  if (resultLength > inputLength) {
   1065    MOZ_ASSERT(carry == 1);
   1066    result->setDigit(inputLength, 1);
   1067  } else {
   1068    MOZ_ASSERT(!carry);
   1069  }
   1070 
   1071  return destructivelyTrimHighZeroDigits(cx, result);
   1072 }
   1073 
   1074 BigInt* BigInt::absoluteSubOne(JSContext* cx, HandleBigInt x,
   1075                               bool resultNegative) {
   1076  MOZ_ASSERT(!x->isZero());
   1077 
   1078  unsigned length = x->digitLength();
   1079 
   1080  if (length == 1) {
   1081    Digit d = x->digit(0);
   1082    if (d == 1) {
   1083      // Ignore resultNegative.
   1084      return zero(cx);
   1085    }
   1086    return createFromDigit(cx, d - 1, resultNegative);
   1087  }
   1088 
   1089  BigInt* result = createUninitialized(cx, length, resultNegative);
   1090  if (!result) {
   1091    return nullptr;
   1092  }
   1093 
   1094  Digit borrow = 1;
   1095  for (unsigned i = 0; i < length; i++) {
   1096    Digit newBorrow = 0;
   1097    result->setDigit(i, digitSub(x->digit(i), borrow, &newBorrow));
   1098    borrow = newBorrow;
   1099  }
   1100  MOZ_ASSERT(!borrow);
   1101 
   1102  return destructivelyTrimHighZeroDigits(cx, result);
   1103 }
   1104 
   1105 BigInt* BigInt::inc(JSContext* cx, HandleBigInt x) {
   1106  if (x->isZero()) {
   1107    return one(cx);
   1108  }
   1109 
   1110  bool isNegative = x->isNegative();
   1111  if (isNegative) {
   1112    return absoluteSubOne(cx, x, isNegative);
   1113  }
   1114 
   1115  return absoluteAddOne(cx, x, isNegative);
   1116 }
   1117 
   1118 BigInt* BigInt::dec(JSContext* cx, HandleBigInt x) {
   1119  if (x->isZero()) {
   1120    return negativeOne(cx);
   1121  }
   1122 
   1123  bool isNegative = x->isNegative();
   1124  if (isNegative) {
   1125    return absoluteAddOne(cx, x, isNegative);
   1126  }
   1127 
   1128  return absoluteSubOne(cx, x, isNegative);
   1129 }
   1130 
   1131 // Lookup table for the maximum number of bits required per character of a
   1132 // base-N string representation of a number. To increase accuracy, the array
   1133 // value is the actual value multiplied by 32. To generate this table:
   1134 // for (var i = 0; i <= 36; i++) { print(Math.ceil(Math.log2(i) * 32) + ","); }
   1135 static constexpr uint8_t maxBitsPerCharTable[] = {
   1136    0,   0,   32,  51,  64,  75,  83,  90,  96,  // 0..8
   1137    102, 107, 111, 115, 119, 122, 126, 128,      // 9..16
   1138    131, 134, 136, 139, 141, 143, 145, 147,      // 17..24
   1139    149, 151, 153, 154, 156, 158, 159, 160,      // 25..32
   1140    162, 163, 165, 166,                          // 33..36
   1141 };
   1142 
   1143 static constexpr unsigned bitsPerCharTableShift = 5;
   1144 static constexpr size_t bitsPerCharTableMultiplier = 1u
   1145                                                     << bitsPerCharTableShift;
   1146 static constexpr char radixDigits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
   1147 
   1148 static inline uint64_t CeilDiv(uint64_t numerator, uint64_t denominator) {
   1149  MOZ_ASSERT(numerator != 0);
   1150  return 1 + (numerator - 1) / denominator;
   1151 };
   1152 
   1153 // Compute (an overapproximation of) the length of the string representation of
   1154 // a BigInt.  In base B an X-digit number has maximum value:
   1155 //
   1156 //   B**X - 1
   1157 //
   1158 // We're trying to find N for an N-digit number in base |radix| full
   1159 // representing a |bitLength|-digit number in base 2, so we have:
   1160 //
   1161 //   radix**N - 1 ≥ 2**bitLength - 1
   1162 //   radix**N ≥ 2**bitLength
   1163 //   N ≥ log2(2**bitLength) / log2(radix)
   1164 //   N ≥ bitLength / log2(radix)
   1165 //
   1166 // so the smallest N is:
   1167 //
   1168 //   N = ⌈bitLength / log2(radix)⌉
   1169 //
   1170 // We want to avoid floating-point computations and precompute the logarithm, so
   1171 // we multiply both sides of the division by |bitsPerCharTableMultiplier|:
   1172 //
   1173 //   N = ⌈(bPCTM * bitLength) / (bPCTM * log2(radix))⌉
   1174 //
   1175 // and then because |maxBitsPerChar| representing the denominator may have been
   1176 // rounded *up* -- which could produce an overall under-computation -- we reduce
   1177 // by one to undo any rounding and conservatively compute:
   1178 //
   1179 //   N ≥ ⌈(bPCTM * bitLength) / (maxBitsPerChar - 1)⌉
   1180 //
   1181 size_t BigInt::calculateMaximumCharactersRequired(HandleBigInt x,
   1182                                                  unsigned radix) {
   1183  MOZ_ASSERT(!x->isZero());
   1184  MOZ_ASSERT(radix >= 2 && radix <= 36);
   1185 
   1186  size_t length = x->digitLength();
   1187  Digit lastDigit = x->digit(length - 1);
   1188  size_t bitLength = length * DigitBits - DigitLeadingZeroes(lastDigit);
   1189 
   1190  uint8_t maxBitsPerChar = maxBitsPerCharTable[radix];
   1191  uint64_t maximumCharactersRequired =
   1192      CeilDiv(static_cast<uint64_t>(bitsPerCharTableMultiplier) * bitLength,
   1193              maxBitsPerChar - 1);
   1194  maximumCharactersRequired += x->isNegative();
   1195 
   1196  return AssertedCast<size_t>(maximumCharactersRequired);
   1197 }
   1198 
   1199 template <AllowGC allowGC>
   1200 JSLinearString* BigInt::toStringBasePowerOfTwo(JSContext* cx, HandleBigInt x,
   1201                                               unsigned radix) {
   1202  MOZ_ASSERT(mozilla::IsPowerOfTwo(radix));
   1203  MOZ_ASSERT(radix >= 2 && radix <= 32);
   1204  MOZ_ASSERT(!x->isZero());
   1205  MOZ_ASSERT(x->digitLength() > 1);
   1206 
   1207  const unsigned length = x->digitLength();
   1208  const bool sign = x->isNegative();
   1209  const unsigned bitsPerChar = mozilla::CountTrailingZeroes32(radix);
   1210  const unsigned charMask = radix - 1;
   1211  // Compute the length of the resulting string: divide the bit length of the
   1212  // BigInt by the number of bits representable per character (rounding up).
   1213  const Digit msd = x->digit(length - 1);
   1214 
   1215  const size_t bitLength = length * DigitBits - DigitLeadingZeroes(msd);
   1216  const size_t charsRequired = CeilDiv(bitLength, bitsPerChar) + sign;
   1217 
   1218  static_assert(MaxBitLength + 1 <= JSString::MAX_LENGTH,
   1219                "Base 2 representation (including leading sign) of the largest "
   1220                "possible BigInt fits into a string");
   1221 
   1222  MOZ_RELEASE_ASSERT(charsRequired <= JSString::MAX_LENGTH);
   1223 
   1224  StringChars<JS::Latin1Char> stringChars(cx);
   1225  if (!stringChars.maybeAlloc(cx, charsRequired)) {
   1226    if constexpr (!allowGC) {
   1227      cx->recoverFromOutOfMemory();
   1228    }
   1229    return nullptr;
   1230  }
   1231 
   1232  {
   1233    JS::AutoCheckCannotGC nogc;
   1234    auto* resultChars = stringChars.data(nogc);
   1235 
   1236    Digit digit = 0;
   1237    // Keeps track of how many unprocessed bits there are in |digit|.
   1238    unsigned availableBits = 0;
   1239    size_t pos = charsRequired;
   1240    for (unsigned i = 0; i < length - 1; i++) {
   1241      Digit newDigit = x->digit(i);
   1242      // Take any leftover bits from the last iteration into account.
   1243      unsigned current = (digit | (newDigit << availableBits)) & charMask;
   1244      MOZ_ASSERT(pos);
   1245      resultChars[--pos] = radixDigits[current];
   1246      unsigned consumedBits = bitsPerChar - availableBits;
   1247      digit = newDigit >> consumedBits;
   1248      availableBits = DigitBits - consumedBits;
   1249      while (availableBits >= bitsPerChar) {
   1250        MOZ_ASSERT(pos);
   1251        resultChars[--pos] = radixDigits[digit & charMask];
   1252        digit >>= bitsPerChar;
   1253        availableBits -= bitsPerChar;
   1254      }
   1255    }
   1256 
   1257    // Write out the character containing the lowest-order bit of |msd|.
   1258    //
   1259    // This character may include leftover bits from the Digit below |msd|.  For
   1260    // example, if |x === 2n**64n| and |radix == 32|: the preceding loop writes
   1261    // twelve zeroes for low-order bits 0-59 in |x->digit(0)| (and |x->digit(1)|
   1262    // on 32-bit); then the highest 4 bits of of |x->digit(0)| (or |x->digit(1)|
   1263    // on 32-bit) and bit 0 of |x->digit(1)| (|x->digit(2)| on 32-bit) will
   1264    // comprise the |current == 0b1'0000| computed below for the high-order 'g'
   1265    // character.
   1266    unsigned current = (digit | (msd << availableBits)) & charMask;
   1267    MOZ_ASSERT(pos);
   1268    resultChars[--pos] = radixDigits[current];
   1269 
   1270    // Write out remaining characters represented by |msd|.  (There may be none,
   1271    // as in the example above.)
   1272    digit = msd >> (bitsPerChar - availableBits);
   1273    while (digit != 0) {
   1274      MOZ_ASSERT(pos);
   1275      resultChars[--pos] = radixDigits[digit & charMask];
   1276      digit >>= bitsPerChar;
   1277    }
   1278 
   1279    if (sign) {
   1280      MOZ_ASSERT(pos);
   1281      resultChars[--pos] = '-';
   1282    }
   1283    MOZ_ASSERT(pos == 0);
   1284  }
   1285 
   1286  return stringChars.toStringDontDeflateNonStatic<allowGC>(cx, charsRequired);
   1287 }
   1288 
   1289 template <AllowGC allowGC>
   1290 JSLinearString* BigInt::toStringSingleDigit(JSContext* cx, Digit digit,
   1291                                            bool isNegative, unsigned radix) {
   1292  MOZ_ASSERT(digit != 0, "zero case should have been handled in toString");
   1293 
   1294  if (digit <= Digit(INT32_MAX)) {
   1295    int32_t val = AssertedCast<int32_t>(digit);
   1296    return Int32ToStringWithBase<allowGC>(cx, isNegative ? -val : val, radix,
   1297                                          /* lowerCase = */ true);
   1298  }
   1299 
   1300  // Plus one to include the sign.
   1301  constexpr size_t maxLength = std::numeric_limits<Digit>::digits + 1;
   1302  static_assert(maxLength == 33 || maxLength == 65,
   1303                "unexpected single digit string length");
   1304 
   1305  char resultChars[maxLength];
   1306 
   1307  char* chars = resultChars;
   1308  if (isNegative) {
   1309    *chars++ = '-';
   1310  }
   1311 
   1312  auto result = std::to_chars(chars, std::end(resultChars), digit, radix);
   1313  MOZ_ASSERT(result.ec == std::errc());
   1314 
   1315  size_t length = result.ptr - resultChars;
   1316  MOZ_ASSERT(length <= maxLength);
   1317 
   1318  return NewStringCopyN<allowGC>(cx, resultChars, length);
   1319 }
   1320 
   1321 static constexpr BigInt::Digit MaxPowerInDigit(uint8_t radix) {
   1322  BigInt::Digit result = 1;
   1323  while (result < BigInt::Digit(-1) / radix) {
   1324    result *= radix;
   1325  }
   1326  return result;
   1327 }
   1328 
   1329 static constexpr uint8_t MaxExponentInDigit(uint8_t radix) {
   1330  uint8_t exp = 0;
   1331  BigInt::Digit result = 1;
   1332  while (result < BigInt::Digit(-1) / radix) {
   1333    result *= radix;
   1334    exp += 1;
   1335  }
   1336  return exp;
   1337 }
   1338 
   1339 struct RadixInfo {
   1340  BigInt::Digit maxPowerInDigit;
   1341  uint8_t maxExponentInDigit;
   1342 
   1343  constexpr RadixInfo(BigInt::Digit maxPower, uint8_t maxExponent)
   1344      : maxPowerInDigit(maxPower), maxExponentInDigit(maxExponent) {}
   1345 
   1346  explicit constexpr RadixInfo(uint8_t radix)
   1347      : RadixInfo(MaxPowerInDigit(radix), MaxExponentInDigit(radix)) {}
   1348 };
   1349 
   1350 static constexpr const RadixInfo toStringInfo[37] = {
   1351    {0, 0},        {0, 0},        RadixInfo(2),  RadixInfo(3),  RadixInfo(4),
   1352    RadixInfo(5),  RadixInfo(6),  RadixInfo(7),  RadixInfo(8),  RadixInfo(9),
   1353    RadixInfo(10), RadixInfo(11), RadixInfo(12), RadixInfo(13), RadixInfo(14),
   1354    RadixInfo(15), RadixInfo(16), RadixInfo(17), RadixInfo(18), RadixInfo(19),
   1355    RadixInfo(20), RadixInfo(21), RadixInfo(22), RadixInfo(23), RadixInfo(24),
   1356    RadixInfo(25), RadixInfo(26), RadixInfo(27), RadixInfo(28), RadixInfo(29),
   1357    RadixInfo(30), RadixInfo(31), RadixInfo(32), RadixInfo(33), RadixInfo(34),
   1358    RadixInfo(35), RadixInfo(36),
   1359 };
   1360 
   1361 JSLinearString* BigInt::toStringGeneric(JSContext* cx, HandleBigInt x,
   1362                                        unsigned radix) {
   1363  MOZ_ASSERT(radix >= 2 && radix <= 36);
   1364  MOZ_ASSERT(!x->isZero());
   1365  MOZ_ASSERT(x->digitLength() > 1);
   1366  MOZ_ASSERT(!mozilla::IsPowerOfTwo(radix));
   1367 
   1368  size_t maximumCharactersRequired =
   1369      calculateMaximumCharactersRequired(x, radix);
   1370  if (maximumCharactersRequired > JSString::MAX_LENGTH) {
   1371    ReportAllocationOverflow(cx);
   1372    return nullptr;
   1373  }
   1374 
   1375  auto resultString = cx->make_pod_array<char>(maximumCharactersRequired);
   1376  if (!resultString) {
   1377    return nullptr;
   1378  }
   1379 
   1380  size_t writePos = maximumCharactersRequired;
   1381 
   1382  unsigned chunkChars = toStringInfo[radix].maxExponentInDigit;
   1383  Digit chunkDivisor = toStringInfo[radix].maxPowerInDigit;
   1384 
   1385  unsigned length = x->digitLength();
   1386  unsigned nonZeroDigit = length - 1;
   1387  MOZ_ASSERT(x->digit(nonZeroDigit) != 0);
   1388 
   1389  // `rest` holds the part of the BigInt that we haven't looked at yet.
   1390  // Not to be confused with "remainder"!
   1391  RootedBigInt rest(cx);
   1392 
   1393  // In the first round, divide the input, allocating a new BigInt for
   1394  // the result == rest; from then on divide the rest in-place.
   1395  //
   1396  // FIXME: absoluteDivWithDigitDivisor doesn't
   1397  // destructivelyTrimHighZeroDigits for in-place divisions, leading to
   1398  // worse constant factors.  See
   1399  // https://bugzilla.mozilla.org/show_bug.cgi?id=1510213.
   1400  RootedBigInt dividend(cx, x);
   1401  do {
   1402    Digit chunk;
   1403    if (!absoluteDivWithDigitDivisor(cx, dividend, chunkDivisor, Some(&rest),
   1404                                     &chunk, dividend->isNegative())) {
   1405      return nullptr;
   1406    }
   1407 
   1408    dividend = rest;
   1409    for (unsigned i = 0; i < chunkChars; i++) {
   1410      MOZ_ASSERT(writePos > 0);
   1411      resultString[--writePos] = radixDigits[chunk % radix];
   1412      chunk /= radix;
   1413    }
   1414    MOZ_ASSERT(!chunk);
   1415 
   1416    if (!rest->digit(nonZeroDigit)) {
   1417      nonZeroDigit--;
   1418    }
   1419 
   1420    MOZ_ASSERT(rest->digit(nonZeroDigit) != 0,
   1421               "division by a single digit can't remove more than one "
   1422               "digit from a number");
   1423  } while (nonZeroDigit > 0);
   1424 
   1425  Digit lastDigit = rest->digit(0);
   1426  do {
   1427    MOZ_ASSERT(writePos > 0);
   1428    resultString[--writePos] = radixDigits[lastDigit % radix];
   1429    lastDigit /= radix;
   1430  } while (lastDigit > 0);
   1431  MOZ_ASSERT(writePos < maximumCharactersRequired);
   1432  MOZ_ASSERT(maximumCharactersRequired - writePos <=
   1433             static_cast<size_t>(maximumCharactersRequired));
   1434 
   1435  // Remove leading zeroes.
   1436  while (writePos + 1 < maximumCharactersRequired &&
   1437         resultString[writePos] == '0') {
   1438    writePos++;
   1439  }
   1440 
   1441  if (x->isNegative()) {
   1442    MOZ_ASSERT(writePos > 0);
   1443    resultString[--writePos] = '-';
   1444  }
   1445 
   1446  MOZ_ASSERT(writePos < maximumCharactersRequired);
   1447  // Would be better to somehow adopt resultString directly.
   1448  return NewStringCopyN<CanGC>(cx, resultString.get() + writePos,
   1449                               maximumCharactersRequired - writePos);
   1450 }
   1451 
   1452 BigInt* BigInt::destructivelyTrimHighZeroDigits(JSContext* cx, BigInt* x) {
   1453  if (x->isZero()) {
   1454    MOZ_ASSERT(!x->isNegative());
   1455    return x;
   1456  }
   1457  MOZ_ASSERT(x->digitLength());
   1458 
   1459  int nonZeroIndex = x->digitLength() - 1;
   1460  while (nonZeroIndex >= 0 && x->digit(nonZeroIndex) == 0) {
   1461    nonZeroIndex--;
   1462  }
   1463 
   1464  if (nonZeroIndex < 0) {
   1465    return zero(cx);
   1466  }
   1467 
   1468  if (nonZeroIndex == static_cast<int>(x->digitLength() - 1)) {
   1469    return x;
   1470  }
   1471 
   1472  unsigned newLength = nonZeroIndex + 1;
   1473 
   1474  if (newLength > InlineDigitsLength) {
   1475    MOZ_ASSERT(x->hasHeapDigits());
   1476 
   1477    size_t oldLength = x->digitLength();
   1478    Digit* newdigits = ReallocateCellBuffer<Digit>(cx, x, x->heapDigits_,
   1479                                                   oldLength, newLength);
   1480    if (!newdigits) {
   1481      return nullptr;
   1482    }
   1483    x->heapDigits_ = newdigits;
   1484  } else {
   1485    if (x->hasHeapDigits()) {
   1486      Digit digits[InlineDigitsLength];
   1487      std::copy_n(x->heapDigits_, InlineDigitsLength, digits);
   1488      if (!cx->nursery().isInside(x->heapDigits_)) {
   1489        FreeBuffer(x->zone(), x->heapDigits_);
   1490      }
   1491      std::copy_n(digits, InlineDigitsLength, x->inlineDigits_);
   1492    }
   1493  }
   1494 
   1495  x->setLengthAndFlags(newLength, x->isNegative() ? SignBit : 0);
   1496 
   1497  return x;
   1498 }
   1499 
   1500 // The maximum value `radix**charCount - 1` must be represented as a max number
   1501 // `2**(N * DigitBits) - 1` for `N` digits, so
   1502 //
   1503 //   2**(N * DigitBits) - 1 ≥ radix**charcount - 1
   1504 //   2**(N * DigitBits) ≥ radix**charcount
   1505 //   N * DigitBits ≥ log2(radix**charcount)
   1506 //   N * DigitBits ≥ charcount * log2(radix)
   1507 //   N ≥ ⌈charcount * log2(radix) / DigitBits⌉ (conservatively)
   1508 //
   1509 // or in the code's terms (all numbers promoted to exact mathematical values),
   1510 //
   1511 //   N ≥ ⌈charcount * bitsPerChar / (DigitBits * bitsPerCharTableMultiplier)⌉
   1512 //
   1513 // Note that `N` is computed even more conservatively here because `bitsPerChar`
   1514 // is rounded up.
   1515 bool BigInt::calculateMaximumDigitsRequired(JSContext* cx, uint8_t radix,
   1516                                            size_t charcount, size_t* result) {
   1517  MOZ_ASSERT(2 <= radix && radix <= 36);
   1518 
   1519  uint8_t bitsPerChar = maxBitsPerCharTable[radix];
   1520 
   1521  MOZ_ASSERT(charcount > 0);
   1522  MOZ_ASSERT(charcount <= std::numeric_limits<uint64_t>::max() / bitsPerChar);
   1523  static_assert(
   1524      MaxDigitLength < std::numeric_limits<size_t>::max(),
   1525      "can't safely cast calculateMaximumDigitsRequired result to size_t");
   1526 
   1527  uint64_t n = CeilDiv(static_cast<uint64_t>(charcount) * bitsPerChar,
   1528                       DigitBits * bitsPerCharTableMultiplier);
   1529  if (n > MaxDigitLength) {
   1530    ReportOversizedAllocation(cx, JSMSG_BIGINT_TOO_LARGE);
   1531    return false;
   1532  }
   1533 
   1534  *result = n;
   1535  return true;
   1536 }
   1537 
   1538 static BigInt::Digit PowerOf(BigInt::Digit base, size_t n) {
   1539  MOZ_ASSERT(n > 0);
   1540  mozilla::CheckedInt<BigInt::Digit> result = base;
   1541  for (size_t i = 1; i < n; i++) {
   1542    result *= base;
   1543  }
   1544  MOZ_ASSERT(result.isValid(), "unexpected overflow");
   1545  return result.value();
   1546 }
   1547 
   1548 template <typename CharT>
   1549 static bool ParseLiteralDigit(Range<const CharT> chars, unsigned radix,
   1550                              BigInt::Digit* result) {
   1551  MOZ_ASSERT(chars.length() > 0);
   1552  RangedPtr<const CharT> start = chars.begin();
   1553  RangedPtr<const CharT> end = chars.end();
   1554 
   1555  mozilla::CheckedInt<BigInt::Digit> d = 0;
   1556  for (; start < end; start++) {
   1557    uint32_t digit;
   1558    CharT c = *start;
   1559    if (c >= '0' && c <= '9') {
   1560      digit = c - '0';
   1561    } else if (c >= 'a' && c <= 'z') {
   1562      digit = c - 'a' + 10;
   1563    } else if (c >= 'A' && c <= 'Z') {
   1564      digit = c - 'A' + 10;
   1565    } else {
   1566      return false;
   1567    }
   1568    if (MOZ_UNLIKELY(digit >= radix)) {
   1569      return false;
   1570    }
   1571 
   1572    d = d * radix + digit;
   1573  }
   1574  MOZ_ASSERT(d.isValid(), "unexpected overflow");
   1575 
   1576  *result = d.value();
   1577  return true;
   1578 }
   1579 
   1580 template <typename CharT>
   1581 BigInt* BigInt::parseLiteralDigits(JSContext* cx, Range<const CharT> chars,
   1582                                   unsigned radix, bool isNegative,
   1583                                   bool* haveParseError, gc::Heap heap) {
   1584  static_assert(
   1585      std::is_same_v<CharT, JS::Latin1Char> || std::is_same_v<CharT, char16_t>,
   1586      "only the bare minimum character types are supported, to avoid "
   1587      "excessively instantiating this template");
   1588 
   1589  MOZ_ASSERT(chars.length());
   1590 
   1591  RangedPtr<const CharT> start = chars.begin();
   1592  RangedPtr<const CharT> end = chars.end();
   1593 
   1594  // Skipping leading zeroes.
   1595  while (start[0] == '0') {
   1596    start++;
   1597    if (start == end) {
   1598      return zero(cx, heap);
   1599    }
   1600  }
   1601 
   1602  size_t length;
   1603  if (!calculateMaximumDigitsRequired(cx, radix, end - start, &length)) {
   1604    return nullptr;
   1605  }
   1606  MOZ_ASSERT(length > 0);
   1607 
   1608  // Fast path for the single digit case.
   1609  if (length == 1) {
   1610    BigInt::Digit digit = 0;
   1611    if (!ParseLiteralDigit(chars, radix, &digit)) {
   1612      *haveParseError = true;
   1613      return nullptr;
   1614    }
   1615    MOZ_ASSERT(digit > 0);
   1616    return BigInt::createFromDigit(cx, digit, isNegative, heap);
   1617  }
   1618 
   1619  BigInt* result = createUninitialized(cx, length, isNegative, heap);
   1620  if (!result) {
   1621    return nullptr;
   1622  }
   1623 
   1624  result->initializeDigitsToZero();
   1625 
   1626  // Numbers in radix 2, 4, and 16 can be directly stored into the result when
   1627  // parsing from right to left.
   1628  uint8_t log2 = mozilla::FloorLog2(radix);
   1629  if (mozilla::IsPowerOfTwo(log2)) {
   1630    size_t chunkChars = BigInt::DigitBits >> mozilla::FloorLog2(log2);
   1631 
   1632    size_t i = 0;
   1633    RangedPtr<const CharT> to = end;
   1634    while (to > start) {
   1635      RangedPtr<const CharT> from = to - std::min(to - start, chunkChars);
   1636 
   1637      Digit chunk = 0;
   1638      if (!ParseLiteralDigit(Range{from, to}, radix, &chunk)) {
   1639        *haveParseError = true;
   1640        return nullptr;
   1641      }
   1642 
   1643      result->setDigit(i++, chunk);
   1644      to = from;
   1645    }
   1646    MOZ_ASSERT(i == length, "unexpected over allocation");
   1647    MOZ_ASSERT(result->digit(length - 1) > 0, "unexpected leading zero");
   1648 
   1649    return result;
   1650  }
   1651 
   1652  size_t chunkChars = toStringInfo[radix].maxExponentInDigit;
   1653  Digit chunkMultiplier = toStringInfo[radix].maxPowerInDigit;
   1654 
   1655  while (start < end) {
   1656    RangedPtr<const CharT> limit = start + std::min(end - start, chunkChars);
   1657 
   1658    Digit chunk = 0;
   1659    if (!ParseLiteralDigit(Range{start, limit}, radix, &chunk)) {
   1660      *haveParseError = true;
   1661      return nullptr;
   1662    }
   1663 
   1664    BigInt::Digit multiplier = chunkMultiplier;
   1665    if ((limit - start) < chunkChars) {
   1666      multiplier = PowerOf(radix, limit - start);
   1667      MOZ_ASSERT(multiplier < chunkMultiplier);
   1668    }
   1669    result->inplaceMultiplyAdd(multiplier, chunk);
   1670    start = limit;
   1671  }
   1672 
   1673  return destructivelyTrimHighZeroDigits(cx, result);
   1674 }
   1675 
   1676 // BigInt proposal section 7.2
   1677 template <typename CharT>
   1678 BigInt* BigInt::parseLiteral(JSContext* cx, Range<const CharT> chars,
   1679                             bool* haveParseError, js::gc::Heap heap) {
   1680  RangedPtr<const CharT> start = chars.begin();
   1681  const RangedPtr<const CharT> end = chars.end();
   1682  bool isNegative = false;
   1683 
   1684  MOZ_ASSERT(chars.length());
   1685 
   1686  if (end - start > 2 && start[0] == '0') {
   1687    if (start[1] == 'b' || start[1] == 'B') {
   1688      // StringNumericLiteral ::: BinaryIntegerLiteral
   1689      return parseLiteralDigits(cx, Range<const CharT>(start + 2, end), 2,
   1690                                isNegative, haveParseError, heap);
   1691    }
   1692    if (start[1] == 'x' || start[1] == 'X') {
   1693      // StringNumericLiteral ::: HexIntegerLiteral
   1694      return parseLiteralDigits(cx, Range<const CharT>(start + 2, end), 16,
   1695                                isNegative, haveParseError, heap);
   1696    }
   1697    if (start[1] == 'o' || start[1] == 'O') {
   1698      // StringNumericLiteral ::: OctalIntegerLiteral
   1699      return parseLiteralDigits(cx, Range<const CharT>(start + 2, end), 8,
   1700                                isNegative, haveParseError, heap);
   1701    }
   1702  }
   1703 
   1704  return parseLiteralDigits(cx, Range<const CharT>(start, end), 10, isNegative,
   1705                            haveParseError, heap);
   1706 }
   1707 
   1708 BigInt* BigInt::createFromDouble(JSContext* cx, double d) {
   1709  MOZ_ASSERT(IsInteger(d), "Only integer-valued doubles can convert to BigInt");
   1710 
   1711  if (d == 0) {
   1712    return zero(cx);
   1713  }
   1714 
   1715  int exponent = mozilla::ExponentComponent(d);
   1716  MOZ_ASSERT(exponent >= 0);
   1717  int length = exponent / DigitBits + 1;
   1718  BigInt* result = createUninitialized(cx, length, d < 0);
   1719  if (!result) {
   1720    return nullptr;
   1721  }
   1722 
   1723  // We construct a BigInt from the double `d` by shifting its mantissa
   1724  // according to its exponent and mapping the bit pattern onto digits.
   1725  //
   1726  //               <----------- bitlength = exponent + 1 ----------->
   1727  //                <----- 52 ------> <------ trailing zeroes ------>
   1728  // mantissa:     1yyyyyyyyyyyyyyyyy 0000000000000000000000000000000
   1729  // digits:    0001xxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
   1730  //                <-->          <------>
   1731  //          msdTopBits          DigitBits
   1732  //
   1733  using Double = mozilla::FloatingPoint<double>;
   1734  uint64_t mantissa =
   1735      mozilla::BitwiseCast<uint64_t>(d) & Double::kSignificandBits;
   1736  // Add implicit high bit.
   1737  mantissa |= 1ull << Double::kSignificandWidth;
   1738 
   1739  const int mantissaTopBit = Double::kSignificandWidth;  // 0-indexed.
   1740 
   1741  // 0-indexed position of `d`'s most significant bit within the `msd`.
   1742  int msdTopBit = exponent % DigitBits;
   1743 
   1744  // Next digit under construction.
   1745  Digit digit;
   1746 
   1747  // First, build the MSD by shifting the mantissa appropriately.
   1748  if (msdTopBit < mantissaTopBit) {
   1749    int remainingMantissaBits = mantissaTopBit - msdTopBit;
   1750    digit = mantissa >> remainingMantissaBits;
   1751    mantissa = mantissa << (64 - remainingMantissaBits);
   1752  } else {
   1753    MOZ_ASSERT(msdTopBit >= mantissaTopBit);
   1754    digit = mantissa << (msdTopBit - mantissaTopBit);
   1755    mantissa = 0;
   1756  }
   1757  MOZ_ASSERT(digit != 0, "most significant digit should not be zero");
   1758  result->setDigit(--length, digit);
   1759 
   1760  // Fill in digits containing mantissa contributions.
   1761  while (mantissa) {
   1762    MOZ_ASSERT(length > 0,
   1763               "double bits were all non-fractional, so there must be "
   1764               "digits present to hold them");
   1765 
   1766    if (DigitBits == 64) {
   1767      result->setDigit(--length, mantissa);
   1768      break;
   1769    }
   1770 
   1771    MOZ_ASSERT(DigitBits == 32);
   1772    Digit current = mantissa >> 32;
   1773    mantissa = mantissa << 32;
   1774    result->setDigit(--length, current);
   1775  }
   1776 
   1777  // Fill in low-order zeroes.
   1778  for (int i = length - 1; i >= 0; i--) {
   1779    result->setDigit(i, 0);
   1780  }
   1781 
   1782  return result;
   1783 }
   1784 
   1785 BigInt* BigInt::createFromUint64(JSContext* cx, uint64_t n, gc::Heap heap) {
   1786  if (n == 0) {
   1787    return zero(cx, heap);
   1788  }
   1789 
   1790  const bool isNegative = false;
   1791 
   1792  if (DigitBits == 32) {
   1793    Digit low = n;
   1794    Digit high = n >> 32;
   1795    size_t length = high ? 2 : 1;
   1796 
   1797    BigInt* res = createUninitialized(cx, length, isNegative, heap);
   1798    if (!res) {
   1799      return nullptr;
   1800    }
   1801    res->setDigit(0, low);
   1802    if (high) {
   1803      res->setDigit(1, high);
   1804    }
   1805    return res;
   1806  }
   1807 
   1808  return createFromDigit(cx, n, isNegative, heap);
   1809 }
   1810 
   1811 BigInt* BigInt::createFromInt64(JSContext* cx, int64_t n, gc::Heap heap) {
   1812  BigInt* res = createFromUint64(cx, Abs(n), heap);
   1813  if (!res) {
   1814    return nullptr;
   1815  }
   1816 
   1817  if (n < 0) {
   1818    res->setHeaderFlagBit(SignBit);
   1819  }
   1820  MOZ_ASSERT(res->isNegative() == (n < 0));
   1821 
   1822  return res;
   1823 }
   1824 
   1825 BigInt* BigInt::createFromIntPtr(JSContext* cx, intptr_t n) {
   1826  static_assert(sizeof(intptr_t) == sizeof(BigInt::Digit));
   1827 
   1828  if (n == 0) {
   1829    return BigInt::zero(cx);
   1830  }
   1831  return BigInt::createFromDigit(cx, BigInt::Digit(Abs(n)), n < 0);
   1832 }
   1833 
   1834 // BigInt proposal section 5.1.2
   1835 BigInt* js::NumberToBigInt(JSContext* cx, double d) {
   1836  // Step 1 is an assertion checked by the caller.
   1837  // Step 2.
   1838  if (!IsInteger(d)) {
   1839    ToCStringBuf cbuf;
   1840    const char* str = NumberToCString(&cbuf, d);
   1841    MOZ_ASSERT(str);
   1842 
   1843    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
   1844                              JSMSG_NONINTEGER_NUMBER_TO_BIGINT, str);
   1845    return nullptr;
   1846  }
   1847 
   1848  // Step 3.
   1849  return BigInt::createFromDouble(cx, d);
   1850 }
   1851 
   1852 BigInt* BigInt::copy(JSContext* cx, HandleBigInt x, gc::Heap heap) {
   1853  if (x->isZero()) {
   1854    return zero(cx, heap);
   1855  }
   1856 
   1857  BigInt* result =
   1858      createUninitialized(cx, x->digitLength(), x->isNegative(), heap);
   1859  if (!result) {
   1860    return nullptr;
   1861  }
   1862  for (size_t i = 0; i < x->digitLength(); i++) {
   1863    result->setDigit(i, x->digit(i));
   1864  }
   1865  return result;
   1866 }
   1867 
   1868 // BigInt proposal section 1.1.7
   1869 BigInt* BigInt::add(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   1870  bool xNegative = x->isNegative();
   1871 
   1872  // x + y == x + y
   1873  // -x + -y == -(x + y)
   1874  if (xNegative == y->isNegative()) {
   1875    return absoluteAdd(cx, x, y, xNegative);
   1876  }
   1877 
   1878  // x + -y == x - y == -(y - x)
   1879  // -x + y == y - x == -(x - y)
   1880  int8_t compare = absoluteCompare(x, y);
   1881  if (compare == 0) {
   1882    return zero(cx);
   1883  }
   1884 
   1885  if (compare > 0) {
   1886    return absoluteSub(cx, x, y, xNegative);
   1887  }
   1888 
   1889  return absoluteSub(cx, y, x, !xNegative);
   1890 }
   1891 
   1892 // BigInt proposal section 1.1.8
   1893 BigInt* BigInt::sub(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   1894  bool xNegative = x->isNegative();
   1895  if (xNegative != y->isNegative()) {
   1896    // x - (-y) == x + y
   1897    // (-x) - y == -(x + y)
   1898    return absoluteAdd(cx, x, y, xNegative);
   1899  }
   1900 
   1901  // x - y == -(y - x)
   1902  // (-x) - (-y) == y - x == -(x - y)
   1903  int8_t compare = absoluteCompare(x, y);
   1904  if (compare == 0) {
   1905    return zero(cx);
   1906  }
   1907 
   1908  if (compare > 0) {
   1909    return absoluteSub(cx, x, y, xNegative);
   1910  }
   1911 
   1912  return absoluteSub(cx, y, x, !xNegative);
   1913 }
   1914 
   1915 // BigInt proposal section 1.1.4
   1916 BigInt* BigInt::mul(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   1917  if (x->isZero()) {
   1918    return x;
   1919  }
   1920  if (y->isZero()) {
   1921    return y;
   1922  }
   1923 
   1924  bool resultNegative = x->isNegative() != y->isNegative();
   1925 
   1926  // Fast path for the likely-common case of up to a uint64_t of magnitude.
   1927  if (x->absFitsInUint64() && y->absFitsInUint64()) {
   1928    uint64_t lhs = x->uint64FromAbsNonZero();
   1929    uint64_t rhs = y->uint64FromAbsNonZero();
   1930 
   1931    uint64_t res;
   1932    if (mozilla::SafeMul(lhs, rhs, &res)) {
   1933      MOZ_ASSERT(res != 0);
   1934      return createFromNonZeroRawUint64(cx, res, resultNegative);
   1935    }
   1936  }
   1937 
   1938  unsigned resultLength = x->digitLength() + y->digitLength();
   1939  BigInt* result = createUninitialized(cx, resultLength, resultNegative);
   1940  if (!result) {
   1941    return nullptr;
   1942  }
   1943  result->initializeDigitsToZero();
   1944 
   1945  // Reorder operands to minimize calls to multiplyAccumulate.
   1946  BigInt* left = x;
   1947  BigInt* right = y;
   1948  if (left->digitLength() < right->digitLength()) {
   1949    std::swap(left, right);
   1950  }
   1951 
   1952  for (size_t i = 0; i < right->digitLength(); i++) {
   1953    multiplyAccumulate(left, right->digit(i), result, i);
   1954  }
   1955 
   1956  return destructivelyTrimHighZeroDigits(cx, result);
   1957 }
   1958 
   1959 // BigInt proposal section 1.1.5
   1960 BigInt* BigInt::div(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   1961  // 1. If y is 0n, throw a RangeError exception.
   1962  if (y->isZero()) {
   1963    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
   1964                              JSMSG_BIGINT_DIVISION_BY_ZERO);
   1965    return nullptr;
   1966  }
   1967 
   1968  // 2. Let quotient be the mathematical value of x divided by y.
   1969  // 3. Return a BigInt representing quotient rounded towards 0 to the next
   1970  //    integral value.
   1971  if (x->isZero()) {
   1972    return x;
   1973  }
   1974 
   1975  if (absoluteCompare(x, y) < 0) {
   1976    return zero(cx);
   1977  }
   1978 
   1979  RootedBigInt quotient(cx);
   1980  bool resultNegative = x->isNegative() != y->isNegative();
   1981  if (y->digitLength() == 1) {
   1982    Digit divisor = y->digit(0);
   1983    if (divisor == 1) {
   1984      return resultNegative == x->isNegative() ? x : neg(cx, x);
   1985    }
   1986 
   1987    Digit remainder;
   1988    if (!absoluteDivWithDigitDivisor(cx, x, divisor, Some(&quotient),
   1989                                     &remainder, resultNegative)) {
   1990      return nullptr;
   1991    }
   1992  } else {
   1993    if (!absoluteDivWithBigIntDivisor(cx, x, y, Some(&quotient), Nothing(),
   1994                                      resultNegative)) {
   1995      return nullptr;
   1996    }
   1997  }
   1998 
   1999  return destructivelyTrimHighZeroDigits(cx, quotient);
   2000 }
   2001 
   2002 // BigInt proposal section 1.1.6
   2003 BigInt* BigInt::mod(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   2004  // 1. If y is 0n, throw a RangeError exception.
   2005  if (y->isZero()) {
   2006    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
   2007                              JSMSG_BIGINT_DIVISION_BY_ZERO);
   2008    return nullptr;
   2009  }
   2010 
   2011  // 2. If x is 0n, return x.
   2012  if (x->isZero()) {
   2013    return x;
   2014  }
   2015  // 3. Let r be the BigInt defined by the mathematical relation r = x - (y ×
   2016  // q) where q is a BigInt that is negative only if x/y is negative and
   2017  // positive only if x/y is positive, and whose magnitude is as large as
   2018  // possible without exceeding the magnitude of the true mathematical
   2019  // quotient of x and y.
   2020  if (absoluteCompare(x, y) < 0) {
   2021    return x;
   2022  }
   2023 
   2024  if (y->digitLength() == 1) {
   2025    Digit divisor = y->digit(0);
   2026    if (divisor == 1) {
   2027      return zero(cx);
   2028    }
   2029 
   2030    Digit remainderDigit;
   2031    bool unusedQuotientNegative = false;
   2032    if (!absoluteDivWithDigitDivisor(cx, x, divisor, Nothing(), &remainderDigit,
   2033                                     unusedQuotientNegative)) {
   2034      MOZ_CRASH("BigInt div by digit failed unexpectedly");
   2035    }
   2036 
   2037    if (!remainderDigit) {
   2038      return zero(cx);
   2039    }
   2040 
   2041    return createFromDigit(cx, remainderDigit, x->isNegative());
   2042  } else {
   2043    RootedBigInt remainder(cx);
   2044    if (!absoluteDivWithBigIntDivisor(cx, x, y, Nothing(), Some(&remainder),
   2045                                      x->isNegative())) {
   2046      return nullptr;
   2047    }
   2048    MOZ_ASSERT(remainder);
   2049    return destructivelyTrimHighZeroDigits(cx, remainder);
   2050  }
   2051 }
   2052 
   2053 bool BigInt::divmod(JSContext* cx, Handle<BigInt*> x, Handle<BigInt*> y,
   2054                    MutableHandle<BigInt*> quotient,
   2055                    MutableHandle<BigInt*> remainder) {
   2056  // 1. If y is 0n, throw a RangeError exception.
   2057  if (y->isZero()) {
   2058    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
   2059                              JSMSG_BIGINT_DIVISION_BY_ZERO);
   2060    return false;
   2061  }
   2062 
   2063  // 2. If x is 0n, quotient and remainder are zero, too.
   2064  if (x->isZero()) {
   2065    quotient.set(x);
   2066    remainder.set(x);
   2067    return true;
   2068  }
   2069 
   2070  // 3. Let r be the BigInt defined by the mathematical relation r = x - (y ×
   2071  // q) where q is a BigInt that is negative only if x/y is negative and
   2072  // positive only if x/y is positive, and whose magnitude is as large as
   2073  // possible without exceeding the magnitude of the true mathematical
   2074  // quotient of x and y.
   2075  if (absoluteCompare(x, y) < 0) {
   2076    auto* zero = BigInt::zero(cx);
   2077    if (!zero) {
   2078      return false;
   2079    }
   2080 
   2081    quotient.set(zero);
   2082    remainder.set(x);
   2083    return true;
   2084  }
   2085 
   2086  bool resultNegative = x->isNegative() != y->isNegative();
   2087 
   2088  if (y->digitLength() == 1) {
   2089    Digit divisor = y->digit(0);
   2090    if (divisor == 1) {
   2091      quotient.set(resultNegative == x->isNegative() ? x : neg(cx, x));
   2092      if (!quotient) {
   2093        return false;
   2094      }
   2095 
   2096      remainder.set(BigInt::zero(cx));
   2097      if (!remainder) {
   2098        return false;
   2099      }
   2100    } else {
   2101      Rooted<BigInt*> quot(cx);
   2102      Digit remainderDigit;
   2103      if (!absoluteDivWithDigitDivisor(cx, x, divisor, Some(&quot),
   2104                                       &remainderDigit, resultNegative)) {
   2105        return false;
   2106      }
   2107 
   2108      quotient.set(destructivelyTrimHighZeroDigits(cx, quot));
   2109      if (!quotient) {
   2110        return false;
   2111      }
   2112 
   2113      if (!remainderDigit) {
   2114        remainder.set(zero(cx));
   2115      } else {
   2116        remainder.set(createFromDigit(cx, remainderDigit, x->isNegative()));
   2117      }
   2118      if (!remainder) {
   2119        return false;
   2120      }
   2121    }
   2122  } else {
   2123    RootedBigInt quot(cx);
   2124    RootedBigInt rem(cx);
   2125    if (!absoluteDivWithBigIntDivisor(cx, x, y, Some(&quot), Some(&rem),
   2126                                      resultNegative)) {
   2127      return false;
   2128    }
   2129 
   2130    quotient.set(destructivelyTrimHighZeroDigits(cx, quot));
   2131    if (!quotient) {
   2132      return false;
   2133    }
   2134 
   2135    remainder.set(destructivelyTrimHighZeroDigits(cx, rem));
   2136    if (!remainder) {
   2137      return false;
   2138    }
   2139  }
   2140 
   2141  MOZ_ASSERT(quotient && remainder,
   2142             "quotient and remainder are computed on return");
   2143  MOZ_ASSERT(!quotient->isZero(), "zero quotient is handled earlier");
   2144  MOZ_ASSERT(quotient->isNegative() == resultNegative,
   2145             "quotient has the correct sign");
   2146  MOZ_ASSERT(
   2147      remainder->isZero() || (x->isNegative() == remainder->isNegative()),
   2148      "remainder has the correct sign");
   2149 
   2150  return true;
   2151 }
   2152 
   2153 // BigInt proposal section 1.1.3
   2154 BigInt* BigInt::pow(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   2155  // 1. If exponent is < 0, throw a RangeError exception.
   2156  if (y->isNegative()) {
   2157    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
   2158                              JSMSG_BIGINT_NEGATIVE_EXPONENT);
   2159    return nullptr;
   2160  }
   2161 
   2162  // 2. If base is 0n and exponent is 0n, return 1n.
   2163  if (y->isZero()) {
   2164    return one(cx);
   2165  }
   2166 
   2167  if (x->isZero()) {
   2168    return x;
   2169  }
   2170 
   2171  // 3. Return a BigInt representing the mathematical value of base raised
   2172  //    to the power exponent.
   2173  if (x->digitLength() == 1 && x->digit(0) == 1) {
   2174    // (-1) ** even_number == 1.
   2175    if (x->isNegative() && (y->digit(0) & 1) == 0) {
   2176      return neg(cx, x);
   2177    }
   2178    // (-1) ** odd_number == -1; 1 ** anything == 1.
   2179    return x;
   2180  }
   2181 
   2182  // For all bases >= 2, very large exponents would lead to unrepresentable
   2183  // results.
   2184  static_assert(MaxBitLength < std::numeric_limits<Digit>::max(),
   2185                "unexpectedly large MaxBitLength");
   2186  if (y->digitLength() > 1) {
   2187    ReportOversizedAllocation(cx, JSMSG_BIGINT_TOO_LARGE);
   2188    return nullptr;
   2189  }
   2190  Digit exponent = y->digit(0);
   2191  if (exponent == 1) {
   2192    return x;
   2193  }
   2194  if (exponent >= MaxBitLength) {
   2195    ReportOversizedAllocation(cx, JSMSG_BIGINT_TOO_LARGE);
   2196    return nullptr;
   2197  }
   2198 
   2199  static_assert(
   2200      MaxBitLength <= static_cast<unsigned>(std::numeric_limits<int>::max()),
   2201      "unexpectedly large MaxBitLength");
   2202  int n = static_cast<int>(exponent);
   2203  bool isOddPower = n & 1;
   2204 
   2205  if (x->digitLength() == 1 && mozilla::IsPowerOfTwo(x->digit(0))) {
   2206    // Fast path for (2^m)^n.
   2207 
   2208    // Result is negative for odd powers.
   2209    bool resultNegative = x->isNegative() && isOddPower;
   2210 
   2211    unsigned m = mozilla::FloorLog2(x->digit(0));
   2212    MOZ_ASSERT(m < DigitBits);
   2213 
   2214    static_assert(MaxBitLength * DigitBits > MaxBitLength,
   2215                  "n * m can't overflow");
   2216    n *= int(m);
   2217 
   2218    int length = 1 + (n / DigitBits);
   2219    BigInt* result = createUninitialized(cx, length, resultNegative);
   2220    if (!result) {
   2221      return nullptr;
   2222    }
   2223    result->initializeDigitsToZero();
   2224    result->setDigit(length - 1, static_cast<Digit>(1) << (n % DigitBits));
   2225    return result;
   2226  }
   2227 
   2228  RootedBigInt runningSquare(cx, x);
   2229  RootedBigInt result(cx, isOddPower ? x : nullptr);
   2230  n /= 2;
   2231 
   2232  // Fast path for the likely-common case of up to a uint64_t of magnitude.
   2233  if (x->absFitsInUint64()) {
   2234    bool resultNegative = x->isNegative() && isOddPower;
   2235 
   2236    uint64_t runningSquareInt = x->uint64FromAbsNonZero();
   2237    uint64_t resultInt = isOddPower ? runningSquareInt : 1;
   2238    while (true) {
   2239      uint64_t runningSquareStart = runningSquareInt;
   2240      uint64_t r;
   2241      if (!mozilla::SafeMul(runningSquareInt, runningSquareInt, &r)) {
   2242        break;
   2243      }
   2244      runningSquareInt = r;
   2245 
   2246      if (n & 1) {
   2247        if (!mozilla::SafeMul(resultInt, runningSquareInt, &r)) {
   2248          // Recover |runningSquare| before we restart the loop.
   2249          runningSquareInt = runningSquareStart;
   2250          break;
   2251        }
   2252        resultInt = r;
   2253      }
   2254 
   2255      n /= 2;
   2256      if (n == 0) {
   2257        return createFromNonZeroRawUint64(cx, resultInt, resultNegative);
   2258      }
   2259    }
   2260 
   2261    runningSquare = createFromNonZeroRawUint64(cx, runningSquareInt, false);
   2262    if (!runningSquare) {
   2263      return nullptr;
   2264    }
   2265 
   2266    result = createFromNonZeroRawUint64(cx, resultInt, resultNegative);
   2267    if (!result) {
   2268      return nullptr;
   2269    }
   2270  }
   2271 
   2272  // This implicitly sets the result's sign correctly.
   2273  while (true) {
   2274    runningSquare = mul(cx, runningSquare, runningSquare);
   2275    if (!runningSquare) {
   2276      return nullptr;
   2277    }
   2278 
   2279    if (n & 1) {
   2280      if (!result) {
   2281        result = runningSquare;
   2282      } else {
   2283        result = mul(cx, result, runningSquare);
   2284        if (!result) {
   2285          return nullptr;
   2286        }
   2287      }
   2288    }
   2289 
   2290    n /= 2;
   2291    if (n == 0) {
   2292      return result;
   2293    }
   2294  }
   2295 }
   2296 
   2297 bool BigInt::powIntPtr(intptr_t x, intptr_t y, intptr_t* result) {
   2298  if (y < 0) {
   2299    return false;
   2300  }
   2301  uintptr_t n = uintptr_t(y);
   2302 
   2303  // x^y where x == 1 returns 1 for any y.
   2304  if (x == 1) {
   2305    *result = 1;
   2306    return true;
   2307  }
   2308 
   2309  // x^y where x == -1 returns 1 for even y, and -1 for odd y.
   2310  if (x == -1) {
   2311    *result = (y & 1) ? -1 : 1;
   2312    return true;
   2313  }
   2314 
   2315  using CheckedIntPtr = mozilla::CheckedInt<intptr_t>;
   2316 
   2317  CheckedIntPtr runningSquare = x;
   2318  CheckedIntPtr res = 1;
   2319  while (true) {
   2320    if ((n & 1) != 0) {
   2321      res *= runningSquare;
   2322      if (!res.isValid()) {
   2323        return false;
   2324      }
   2325    }
   2326 
   2327    n >>= 1;
   2328    if (n == 0) {
   2329      *result = res.value();
   2330      return true;
   2331    }
   2332 
   2333    runningSquare *= runningSquare;
   2334    if (!runningSquare.isValid()) {
   2335      return false;
   2336    }
   2337  }
   2338 }
   2339 
   2340 BigInt* BigInt::lshByAbsolute(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   2341  if (x->isZero() || y->isZero()) {
   2342    return x;
   2343  }
   2344 
   2345  if (y->digitLength() > 1 || y->digit(0) > MaxBitLength) {
   2346    ReportOversizedAllocation(cx, JSMSG_BIGINT_TOO_LARGE);
   2347    if (js::SupportDifferentialTesting()) {
   2348      fprintf(stderr, "ReportOutOfMemory called\n");
   2349    }
   2350    return nullptr;
   2351  }
   2352  Digit shift = y->digit(0);
   2353  int digitShift = static_cast<int>(shift / DigitBits);
   2354  int bitsShift = static_cast<int>(shift % DigitBits);
   2355  int length = x->digitLength();
   2356  bool grow = bitsShift && (x->digit(length - 1) >> (DigitBits - bitsShift));
   2357  int resultLength = length + digitShift + grow;
   2358  BigInt* result = createUninitialized(cx, resultLength, x->isNegative());
   2359  if (!result) {
   2360    return nullptr;
   2361  }
   2362 
   2363  int i = 0;
   2364  for (; i < digitShift; i++) {
   2365    result->setDigit(i, 0);
   2366  }
   2367 
   2368  if (bitsShift == 0) {
   2369    for (int j = 0; i < resultLength; i++, j++) {
   2370      result->setDigit(i, x->digit(j));
   2371    }
   2372  } else {
   2373    Digit carry = 0;
   2374    for (int j = 0; j < length; i++, j++) {
   2375      Digit d = x->digit(j);
   2376      result->setDigit(i, (d << bitsShift) | carry);
   2377      carry = d >> (DigitBits - bitsShift);
   2378    }
   2379    if (grow) {
   2380      result->setDigit(i, carry);
   2381    } else {
   2382      MOZ_ASSERT(!carry);
   2383    }
   2384  }
   2385  return result;
   2386 }
   2387 
   2388 BigInt* BigInt::rshByMaximum(JSContext* cx, bool isNegative) {
   2389  return isNegative ? negativeOne(cx) : zero(cx);
   2390 }
   2391 
   2392 BigInt* BigInt::rshByAbsolute(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   2393  if (x->isZero() || y->isZero()) {
   2394    return x;
   2395  }
   2396 
   2397  if (y->digitLength() > 1 || y->digit(0) >= MaxBitLength) {
   2398    return rshByMaximum(cx, x->isNegative());
   2399  }
   2400  Digit shift = y->digit(0);
   2401  int length = x->digitLength();
   2402  int digitShift = static_cast<int>(shift / DigitBits);
   2403  int bitsShift = static_cast<int>(shift % DigitBits);
   2404  int resultLength = length - digitShift;
   2405  if (resultLength <= 0) {
   2406    return rshByMaximum(cx, x->isNegative());
   2407  }
   2408  // For negative numbers, round down if any bit was shifted out (so that e.g.
   2409  // -5n >> 1n == -3n and not -2n). Check now whether this will happen and
   2410  // whether it can cause overflow into a new digit. If we allocate the result
   2411  // large enough up front, it avoids having to do a second allocation later.
   2412  bool mustRoundDown = false;
   2413  if (x->isNegative()) {
   2414    const Digit mask = (static_cast<Digit>(1) << bitsShift) - 1;
   2415    if ((x->digit(digitShift) & mask)) {
   2416      mustRoundDown = true;
   2417    } else {
   2418      for (int i = 0; i < digitShift; i++) {
   2419        if (x->digit(i)) {
   2420          mustRoundDown = true;
   2421          break;
   2422        }
   2423      }
   2424    }
   2425  }
   2426  // If bits_shift is non-zero, it frees up bits, preventing overflow.
   2427  if (mustRoundDown && bitsShift == 0) {
   2428    // Overflow cannot happen if the most significant digit has unset bits.
   2429    Digit msd = x->digit(length - 1);
   2430    bool roundingCanOverflow = msd == std::numeric_limits<Digit>::max();
   2431    if (roundingCanOverflow) {
   2432      resultLength++;
   2433    }
   2434  }
   2435 
   2436  MOZ_ASSERT(resultLength <= length);
   2437  RootedBigInt result(cx,
   2438                      createUninitialized(cx, resultLength, x->isNegative()));
   2439  if (!result) {
   2440    return nullptr;
   2441  }
   2442  if (!bitsShift) {
   2443    // If roundingCanOverflow, manually initialize the overflow digit.
   2444    result->setDigit(resultLength - 1, 0);
   2445    for (int i = digitShift; i < length; i++) {
   2446      result->setDigit(i - digitShift, x->digit(i));
   2447    }
   2448  } else {
   2449    Digit carry = x->digit(digitShift) >> bitsShift;
   2450    int last = length - digitShift - 1;
   2451    for (int i = 0; i < last; i++) {
   2452      Digit d = x->digit(i + digitShift + 1);
   2453      result->setDigit(i, (d << (DigitBits - bitsShift)) | carry);
   2454      carry = d >> bitsShift;
   2455    }
   2456    result->setDigit(last, carry);
   2457  }
   2458 
   2459  if (mustRoundDown) {
   2460    MOZ_ASSERT(x->isNegative());
   2461    // Since the result is negative, rounding down means adding one to
   2462    // its absolute value. This cannot overflow.  TODO: modify the result in
   2463    // place.
   2464    return absoluteAddOne(cx, result, x->isNegative());
   2465  }
   2466  return destructivelyTrimHighZeroDigits(cx, result);
   2467 }
   2468 
   2469 // BigInt proposal section 1.1.9. BigInt::leftShift ( x, y )
   2470 BigInt* BigInt::lsh(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   2471  if (y->isNegative()) {
   2472    return rshByAbsolute(cx, x, y);
   2473  }
   2474  return lshByAbsolute(cx, x, y);
   2475 }
   2476 
   2477 // BigInt proposal section 1.1.10. BigInt::signedRightShift ( x, y )
   2478 BigInt* BigInt::rsh(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   2479  if (y->isNegative()) {
   2480    return lshByAbsolute(cx, x, y);
   2481  }
   2482  return rshByAbsolute(cx, x, y);
   2483 }
   2484 
   2485 // BigInt proposal section 1.1.17. BigInt::bitwiseAND ( x, y )
   2486 BigInt* BigInt::bitAnd(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   2487  if (x->isZero()) {
   2488    return x;
   2489  }
   2490 
   2491  if (y->isZero()) {
   2492    return y;
   2493  }
   2494 
   2495  if (!x->isNegative() && !y->isNegative()) {
   2496    return absoluteAnd(cx, x, y);
   2497  }
   2498 
   2499  if (x->isNegative() && y->isNegative()) {
   2500    // (-x) & (-y) == ~(x-1) & ~(y-1) == ~((x-1) | (y-1))
   2501    // == -(((x-1) | (y-1)) + 1)
   2502    RootedBigInt x1(cx, absoluteSubOne(cx, x));
   2503    if (!x1) {
   2504      return nullptr;
   2505    }
   2506    RootedBigInt y1(cx, absoluteSubOne(cx, y));
   2507    if (!y1) {
   2508      return nullptr;
   2509    }
   2510    RootedBigInt result(cx, absoluteOr(cx, x1, y1));
   2511    if (!result) {
   2512      return nullptr;
   2513    }
   2514    bool resultNegative = true;
   2515    return absoluteAddOne(cx, result, resultNegative);
   2516  }
   2517 
   2518  MOZ_ASSERT(x->isNegative() != y->isNegative());
   2519  HandleBigInt& pos = x->isNegative() ? y : x;
   2520  HandleBigInt& neg = x->isNegative() ? x : y;
   2521 
   2522  RootedBigInt neg1(cx, absoluteSubOne(cx, neg));
   2523  if (!neg1) {
   2524    return nullptr;
   2525  }
   2526 
   2527  // x & (-y) == x & ~(y-1) == x & ~(y-1)
   2528  return absoluteAndNot(cx, pos, neg1);
   2529 }
   2530 
   2531 // BigInt proposal section 1.1.18. BigInt::bitwiseXOR ( x, y )
   2532 BigInt* BigInt::bitXor(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   2533  if (x->isZero()) {
   2534    return y;
   2535  }
   2536 
   2537  if (y->isZero()) {
   2538    return x;
   2539  }
   2540 
   2541  if (!x->isNegative() && !y->isNegative()) {
   2542    return absoluteXor(cx, x, y);
   2543  }
   2544 
   2545  if (x->isNegative() && y->isNegative()) {
   2546    // (-x) ^ (-y) == ~(x-1) ^ ~(y-1) == (x-1) ^ (y-1)
   2547    RootedBigInt x1(cx, absoluteSubOne(cx, x));
   2548    if (!x1) {
   2549      return nullptr;
   2550    }
   2551    RootedBigInt y1(cx, absoluteSubOne(cx, y));
   2552    if (!y1) {
   2553      return nullptr;
   2554    }
   2555    return absoluteXor(cx, x1, y1);
   2556  }
   2557  MOZ_ASSERT(x->isNegative() != y->isNegative());
   2558 
   2559  HandleBigInt& pos = x->isNegative() ? y : x;
   2560  HandleBigInt& neg = x->isNegative() ? x : y;
   2561 
   2562  // x ^ (-y) == x ^ ~(y-1) == ~(x ^ (y-1)) == -((x ^ (y-1)) + 1)
   2563  RootedBigInt result(cx, absoluteSubOne(cx, neg));
   2564  if (!result) {
   2565    return nullptr;
   2566  }
   2567  result = absoluteXor(cx, result, pos);
   2568  if (!result) {
   2569    return nullptr;
   2570  }
   2571  bool resultNegative = true;
   2572  return absoluteAddOne(cx, result, resultNegative);
   2573 }
   2574 
   2575 // BigInt proposal section 1.1.19. BigInt::bitwiseOR ( x, y )
   2576 BigInt* BigInt::bitOr(JSContext* cx, HandleBigInt x, HandleBigInt y) {
   2577  if (x->isZero()) {
   2578    return y;
   2579  }
   2580 
   2581  if (y->isZero()) {
   2582    return x;
   2583  }
   2584 
   2585  bool resultNegative = x->isNegative() || y->isNegative();
   2586 
   2587  if (!resultNegative) {
   2588    return absoluteOr(cx, x, y);
   2589  }
   2590 
   2591  if (x->isNegative() && y->isNegative()) {
   2592    // (-x) | (-y) == ~(x-1) | ~(y-1) == ~((x-1) & (y-1))
   2593    // == -(((x-1) & (y-1)) + 1)
   2594    RootedBigInt result(cx, absoluteSubOne(cx, x));
   2595    if (!result) {
   2596      return nullptr;
   2597    }
   2598    RootedBigInt y1(cx, absoluteSubOne(cx, y));
   2599    if (!y1) {
   2600      return nullptr;
   2601    }
   2602    result = absoluteAnd(cx, result, y1);
   2603    if (!result) {
   2604      return nullptr;
   2605    }
   2606    return absoluteAddOne(cx, result, resultNegative);
   2607  }
   2608 
   2609  MOZ_ASSERT(x->isNegative() != y->isNegative());
   2610  HandleBigInt& pos = x->isNegative() ? y : x;
   2611  HandleBigInt& neg = x->isNegative() ? x : y;
   2612 
   2613  // x | (-y) == x | ~(y-1) == ~((y-1) &~ x) == -(((y-1) &~ x) + 1)
   2614  RootedBigInt result(cx, absoluteSubOne(cx, neg));
   2615  if (!result) {
   2616    return nullptr;
   2617  }
   2618  result = absoluteAndNot(cx, result, pos);
   2619  if (!result) {
   2620    return nullptr;
   2621  }
   2622  return absoluteAddOne(cx, result, resultNegative);
   2623 }
   2624 
   2625 // BigInt proposal section 1.1.2. BigInt::bitwiseNOT ( x )
   2626 BigInt* BigInt::bitNot(JSContext* cx, HandleBigInt x) {
   2627  if (x->isNegative()) {
   2628    // ~(-x) == ~(~(x-1)) == x-1
   2629    return absoluteSubOne(cx, x);
   2630  } else {
   2631    // ~x == -x-1 == -(x+1)
   2632    bool resultNegative = true;
   2633    return absoluteAddOne(cx, x, resultNegative);
   2634  }
   2635 }
   2636 
   2637 int64_t BigInt::toInt64(const BigInt* x) { return WrapToSigned(toUint64(x)); }
   2638 
   2639 uint64_t BigInt::toUint64(const BigInt* x) {
   2640  if (x->isZero()) {
   2641    return 0;
   2642  }
   2643 
   2644  uint64_t digit = x->uint64FromAbsNonZero();
   2645 
   2646  // Return the two's complement if x is negative.
   2647  if (x->isNegative()) {
   2648    return ~(digit - 1);
   2649  }
   2650 
   2651  return digit;
   2652 }
   2653 
   2654 bool BigInt::isInt32(const BigInt* x, int32_t* result) {
   2655  MOZ_MAKE_MEM_UNDEFINED(result, sizeof(*result));
   2656 
   2657  int64_t r;
   2658  if (!BigInt::isInt64(x, &r)) {
   2659    return false;
   2660  }
   2661 
   2662  if (std::numeric_limits<int32_t>::min() <= r &&
   2663      r <= std::numeric_limits<int32_t>::max()) {
   2664    *result = AssertedCast<int32_t>(r);
   2665    return true;
   2666  }
   2667  return false;
   2668 }
   2669 
   2670 bool BigInt::isInt64(const BigInt* x, int64_t* result) {
   2671  MOZ_MAKE_MEM_UNDEFINED(result, sizeof(*result));
   2672 
   2673  if (!x->absFitsInUint64()) {
   2674    return false;
   2675  }
   2676 
   2677  if (x->isZero()) {
   2678    *result = 0;
   2679    return true;
   2680  }
   2681 
   2682  uint64_t magnitude = x->uint64FromAbsNonZero();
   2683 
   2684  if (x->isNegative()) {
   2685    constexpr uint64_t Int64MinMagnitude = uint64_t(1) << 63;
   2686    if (magnitude <= Int64MinMagnitude) {
   2687      *result = magnitude == Int64MinMagnitude
   2688                    ? std::numeric_limits<int64_t>::min()
   2689                    : -AssertedCast<int64_t>(magnitude);
   2690      return true;
   2691    }
   2692  } else {
   2693    if (magnitude <=
   2694        static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
   2695      *result = AssertedCast<int64_t>(magnitude);
   2696      return true;
   2697    }
   2698  }
   2699 
   2700  return false;
   2701 }
   2702 
   2703 bool BigInt::isUint64(const BigInt* x, uint64_t* result) {
   2704  MOZ_MAKE_MEM_UNDEFINED(result, sizeof(*result));
   2705 
   2706  if (!x->absFitsInUint64() || x->isNegative()) {
   2707    return false;
   2708  }
   2709 
   2710  if (x->isZero()) {
   2711    *result = 0;
   2712    return true;
   2713  }
   2714 
   2715  *result = x->uint64FromAbsNonZero();
   2716  return true;
   2717 }
   2718 
   2719 bool BigInt::isIntPtr(const BigInt* x, intptr_t* result) {
   2720  MOZ_MAKE_MEM_UNDEFINED(result, sizeof(*result));
   2721 
   2722  static_assert(sizeof(intptr_t) == sizeof(BigInt::Digit));
   2723 
   2724  if (x->digitLength() > 1) {
   2725    return false;
   2726  }
   2727 
   2728  if (x->isZero()) {
   2729    *result = 0;
   2730    return true;
   2731  }
   2732 
   2733  uintptr_t magnitude = x->digit(0);
   2734 
   2735  if (x->isNegative()) {
   2736    constexpr uintptr_t IntPtrMinMagnitude = uintptr_t(1) << (DigitBits - 1);
   2737    if (magnitude <= IntPtrMinMagnitude) {
   2738      *result = magnitude == IntPtrMinMagnitude
   2739                    ? std::numeric_limits<intptr_t>::min()
   2740                    : -AssertedCast<intptr_t>(magnitude);
   2741      return true;
   2742    }
   2743  } else {
   2744    if (magnitude <=
   2745        static_cast<uintptr_t>(std::numeric_limits<intptr_t>::max())) {
   2746      *result = AssertedCast<intptr_t>(magnitude);
   2747      return true;
   2748    }
   2749  }
   2750 
   2751  return false;
   2752 }
   2753 
   2754 bool BigInt::isNumber(const BigInt* x, double* result) {
   2755  MOZ_MAKE_MEM_UNDEFINED(result, sizeof(*result));
   2756 
   2757  if (!x->absFitsInUint64()) {
   2758    return false;
   2759  }
   2760 
   2761  if (x->isZero()) {
   2762    *result = 0;
   2763    return true;
   2764  }
   2765 
   2766  uint64_t magnitude = x->uint64FromAbsNonZero();
   2767  if (magnitude < uint64_t(DOUBLE_INTEGRAL_PRECISION_LIMIT)) {
   2768    *result = x->isNegative() ? -double(magnitude) : double(magnitude);
   2769    return true;
   2770  }
   2771 
   2772  return false;
   2773 }
   2774 
   2775 // Compute `2**bits - (x & (2**bits - 1))`.  Used when treating BigInt values as
   2776 // arbitrary-precision two's complement signed integers.
   2777 BigInt* BigInt::truncateAndSubFromPowerOfTwo(JSContext* cx, HandleBigInt x,
   2778                                             uint64_t bits,
   2779                                             bool resultNegative) {
   2780  MOZ_ASSERT(bits != 0);
   2781  MOZ_ASSERT(!x->isZero());
   2782 
   2783  if (bits > MaxBitLength) {
   2784    ReportOversizedAllocation(cx, JSMSG_BIGINT_TOO_LARGE);
   2785    return nullptr;
   2786  }
   2787 
   2788  size_t resultLength = CeilDiv(bits, DigitBits);
   2789  BigInt* result = createUninitialized(cx, resultLength, resultNegative);
   2790  if (!result) {
   2791    return nullptr;
   2792  }
   2793 
   2794  // Process all digits except the MSD.
   2795  size_t xLength = x->digitLength();
   2796  Digit borrow = 0;
   2797  // Take digits from `x` until its length is exhausted.
   2798  for (size_t i = 0; i < std::min(resultLength - 1, xLength); i++) {
   2799    Digit newBorrow = 0;
   2800    Digit difference = digitSub(0, x->digit(i), &newBorrow);
   2801    difference = digitSub(difference, borrow, &newBorrow);
   2802    result->setDigit(i, difference);
   2803    borrow = newBorrow;
   2804  }
   2805  // Then simulate leading zeroes in `x` as needed.
   2806  for (size_t i = xLength; i < resultLength - 1; i++) {
   2807    Digit newBorrow = 0;
   2808    Digit difference = digitSub(0, borrow, &newBorrow);
   2809    result->setDigit(i, difference);
   2810    borrow = newBorrow;
   2811  }
   2812 
   2813  // The MSD might contain extra bits that we don't want.
   2814  Digit xMSD = resultLength <= xLength ? x->digit(resultLength - 1) : 0;
   2815  Digit resultMSD;
   2816  if (bits % DigitBits == 0) {
   2817    Digit newBorrow = 0;
   2818    resultMSD = digitSub(0, xMSD, &newBorrow);
   2819    resultMSD = digitSub(resultMSD, borrow, &newBorrow);
   2820  } else {
   2821    size_t drop = DigitBits - (bits % DigitBits);
   2822    xMSD = (xMSD << drop) >> drop;
   2823    Digit minuendMSD = Digit(1) << (DigitBits - drop);
   2824    Digit newBorrow = 0;
   2825    resultMSD = digitSub(minuendMSD, xMSD, &newBorrow);
   2826    resultMSD = digitSub(resultMSD, borrow, &newBorrow);
   2827    MOZ_ASSERT(newBorrow == 0, "result < 2^bits");
   2828    // If all subtracted bits were zero, we have to get rid of the
   2829    // materialized minuendMSD again.
   2830    resultMSD &= (minuendMSD - 1);
   2831  }
   2832  result->setDigit(resultLength - 1, resultMSD);
   2833 
   2834  return destructivelyTrimHighZeroDigits(cx, result);
   2835 }
   2836 
   2837 BigInt* BigInt::asUintN(JSContext* cx, HandleBigInt x, uint64_t bits) {
   2838  if (x->isZero()) {
   2839    return x;
   2840  }
   2841 
   2842  if (bits == 0) {
   2843    return zero(cx);
   2844  }
   2845 
   2846  // When truncating a negative number, simulate two's complement.
   2847  if (x->isNegative()) {
   2848    bool resultNegative = false;
   2849    return truncateAndSubFromPowerOfTwo(cx, x, bits, resultNegative);
   2850  }
   2851 
   2852  if (bits <= 64) {
   2853    uint64_t u64 = toUint64(x);
   2854    uint64_t mask = uint64_t(-1) >> (64 - bits);
   2855    uint64_t n = u64 & mask;
   2856    if (u64 == n && x->absFitsInUint64()) {
   2857      return x;
   2858    }
   2859    return createFromUint64(cx, n);
   2860  }
   2861 
   2862  if (bits >= MaxBitLength) {
   2863    return x;
   2864  }
   2865 
   2866  Digit msd = x->digit(x->digitLength() - 1);
   2867  size_t msdBits = DigitBits - DigitLeadingZeroes(msd);
   2868  size_t bitLength = msdBits + (x->digitLength() - 1) * DigitBits;
   2869 
   2870  if (bits >= bitLength) {
   2871    return x;
   2872  }
   2873 
   2874  size_t length = CeilDiv(bits, DigitBits);
   2875  MOZ_ASSERT(length >= 2, "single-digit cases should be handled above");
   2876  MOZ_ASSERT(length <= x->digitLength());
   2877 
   2878  // Eagerly trim high zero digits.
   2879  const size_t highDigitBits = ((bits - 1) % DigitBits) + 1;
   2880  const Digit highDigitMask = Digit(-1) >> (DigitBits - highDigitBits);
   2881  Digit mask = highDigitMask;
   2882  while (length > 0) {
   2883    if (x->digit(length - 1) & mask) {
   2884      break;
   2885    }
   2886 
   2887    mask = Digit(-1);
   2888    length--;
   2889  }
   2890 
   2891  const bool isNegative = false;
   2892  BigInt* res = createUninitialized(cx, length, isNegative);
   2893  if (res == nullptr) {
   2894    return nullptr;
   2895  }
   2896 
   2897  while (length-- > 0) {
   2898    res->setDigit(length, x->digit(length) & mask);
   2899    mask = Digit(-1);
   2900  }
   2901  MOZ_ASSERT_IF(length == 0, res->isZero());
   2902 
   2903  return res;
   2904 }
   2905 
   2906 BigInt* BigInt::asIntN(JSContext* cx, HandleBigInt x, uint64_t bits) {
   2907  if (x->isZero()) {
   2908    return x;
   2909  }
   2910 
   2911  if (bits == 0) {
   2912    return zero(cx);
   2913  }
   2914 
   2915  if (bits == 64) {
   2916    int64_t n = toInt64(x);
   2917    if (((n < 0) == x->isNegative()) && x->absFitsInUint64()) {
   2918      return x;
   2919    }
   2920    return createFromInt64(cx, n);
   2921  }
   2922 
   2923  if (bits > MaxBitLength) {
   2924    return x;
   2925  }
   2926 
   2927  Digit msd = x->digit(x->digitLength() - 1);
   2928  size_t msdBits = DigitBits - DigitLeadingZeroes(msd);
   2929  size_t bitLength = msdBits + (x->digitLength() - 1) * DigitBits;
   2930 
   2931  if (bits > bitLength) {
   2932    return x;
   2933  }
   2934 
   2935  Digit signBit = Digit(1) << ((bits - 1) % DigitBits);
   2936  if (bits == bitLength && msd < signBit) {
   2937    return x;
   2938  }
   2939 
   2940  // All the cases above were the trivial cases: truncating zero, or to zero
   2941  // bits, or to more bits than are in `x` (so we return `x` directly), or we
   2942  // already have the 64-bit fast path.  If we get here, follow the textbook
   2943  // algorithm from the specification.
   2944 
   2945  // BigInt.asIntN step 3:  Let `mod` be `x` modulo `2**bits`.
   2946  RootedBigInt mod(cx, asUintN(cx, x, bits));
   2947  if (!mod) {
   2948    return nullptr;
   2949  }
   2950 
   2951  // Step 4: If `mod >= 2**(bits - 1)`, return `mod - 2**bits`; otherwise,
   2952  // return `mod`.
   2953  if (mod->digitLength() == CeilDiv(bits, DigitBits)) {
   2954    MOZ_ASSERT(!mod->isZero(),
   2955               "nonzero bits implies nonzero digit length which implies "
   2956               "nonzero overall");
   2957 
   2958    if ((mod->digit(mod->digitLength() - 1) & signBit) != 0) {
   2959      bool resultNegative = true;
   2960      return truncateAndSubFromPowerOfTwo(cx, mod, bits, resultNegative);
   2961    }
   2962  }
   2963 
   2964  return mod;
   2965 }
   2966 
   2967 static bool ValidBigIntOperands(JSContext* cx, HandleValue lhs,
   2968                                HandleValue rhs) {
   2969  MOZ_ASSERT(lhs.isBigInt() || rhs.isBigInt());
   2970 
   2971  if (!lhs.isBigInt() || !rhs.isBigInt()) {
   2972    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
   2973                              JSMSG_BIGINT_TO_NUMBER);
   2974    return false;
   2975  }
   2976 
   2977  return true;
   2978 }
   2979 
   2980 bool BigInt::addValue(JSContext* cx, HandleValue lhs, HandleValue rhs,
   2981                      MutableHandleValue res) {
   2982  if (!ValidBigIntOperands(cx, lhs, rhs)) {
   2983    return false;
   2984  }
   2985 
   2986  RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   2987  RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   2988  BigInt* resBigInt = BigInt::add(cx, lhsBigInt, rhsBigInt);
   2989  if (!resBigInt) {
   2990    return false;
   2991  }
   2992  res.setBigInt(resBigInt);
   2993  return true;
   2994 }
   2995 
   2996 bool BigInt::subValue(JSContext* cx, HandleValue lhs, HandleValue rhs,
   2997                      MutableHandleValue res) {
   2998  if (!ValidBigIntOperands(cx, lhs, rhs)) {
   2999    return false;
   3000  }
   3001 
   3002  RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   3003  RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   3004  BigInt* resBigInt = BigInt::sub(cx, lhsBigInt, rhsBigInt);
   3005  if (!resBigInt) {
   3006    return false;
   3007  }
   3008  res.setBigInt(resBigInt);
   3009  return true;
   3010 }
   3011 
   3012 bool BigInt::mulValue(JSContext* cx, HandleValue lhs, HandleValue rhs,
   3013                      MutableHandleValue res) {
   3014  if (!ValidBigIntOperands(cx, lhs, rhs)) {
   3015    return false;
   3016  }
   3017 
   3018  RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   3019  RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   3020  BigInt* resBigInt = BigInt::mul(cx, lhsBigInt, rhsBigInt);
   3021  if (!resBigInt) {
   3022    return false;
   3023  }
   3024  res.setBigInt(resBigInt);
   3025  return true;
   3026 }
   3027 
   3028 bool BigInt::divValue(JSContext* cx, HandleValue lhs, HandleValue rhs,
   3029                      MutableHandleValue res) {
   3030  if (!ValidBigIntOperands(cx, lhs, rhs)) {
   3031    return false;
   3032  }
   3033 
   3034  RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   3035  RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   3036  BigInt* resBigInt = BigInt::div(cx, lhsBigInt, rhsBigInt);
   3037  if (!resBigInt) {
   3038    return false;
   3039  }
   3040  res.setBigInt(resBigInt);
   3041  return true;
   3042 }
   3043 
   3044 bool BigInt::modValue(JSContext* cx, HandleValue lhs, HandleValue rhs,
   3045                      MutableHandleValue res) {
   3046  if (!ValidBigIntOperands(cx, lhs, rhs)) {
   3047    return false;
   3048  }
   3049 
   3050  RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   3051  RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   3052  BigInt* resBigInt = BigInt::mod(cx, lhsBigInt, rhsBigInt);
   3053  if (!resBigInt) {
   3054    return false;
   3055  }
   3056  res.setBigInt(resBigInt);
   3057  return true;
   3058 }
   3059 
   3060 bool BigInt::powValue(JSContext* cx, HandleValue lhs, HandleValue rhs,
   3061                      MutableHandleValue res) {
   3062  if (!ValidBigIntOperands(cx, lhs, rhs)) {
   3063    return false;
   3064  }
   3065 
   3066  RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   3067  RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   3068  BigInt* resBigInt = BigInt::pow(cx, lhsBigInt, rhsBigInt);
   3069  if (!resBigInt) {
   3070    return false;
   3071  }
   3072  res.setBigInt(resBigInt);
   3073  return true;
   3074 }
   3075 
   3076 bool BigInt::negValue(JSContext* cx, HandleValue operand,
   3077                      MutableHandleValue res) {
   3078  MOZ_ASSERT(operand.isBigInt());
   3079 
   3080  RootedBigInt operandBigInt(cx, operand.toBigInt());
   3081  BigInt* resBigInt = BigInt::neg(cx, operandBigInt);
   3082  if (!resBigInt) {
   3083    return false;
   3084  }
   3085  res.setBigInt(resBigInt);
   3086  return true;
   3087 }
   3088 
   3089 bool BigInt::incValue(JSContext* cx, HandleValue operand,
   3090                      MutableHandleValue res) {
   3091  MOZ_ASSERT(operand.isBigInt());
   3092 
   3093  RootedBigInt operandBigInt(cx, operand.toBigInt());
   3094  BigInt* resBigInt = BigInt::inc(cx, operandBigInt);
   3095  if (!resBigInt) {
   3096    return false;
   3097  }
   3098  res.setBigInt(resBigInt);
   3099  return true;
   3100 }
   3101 
   3102 bool BigInt::decValue(JSContext* cx, HandleValue operand,
   3103                      MutableHandleValue res) {
   3104  MOZ_ASSERT(operand.isBigInt());
   3105 
   3106  RootedBigInt operandBigInt(cx, operand.toBigInt());
   3107  BigInt* resBigInt = BigInt::dec(cx, operandBigInt);
   3108  if (!resBigInt) {
   3109    return false;
   3110  }
   3111  res.setBigInt(resBigInt);
   3112  return true;
   3113 }
   3114 
   3115 bool BigInt::lshValue(JSContext* cx, HandleValue lhs, HandleValue rhs,
   3116                      MutableHandleValue res) {
   3117  if (!ValidBigIntOperands(cx, lhs, rhs)) {
   3118    return false;
   3119  }
   3120 
   3121  RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   3122  RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   3123  BigInt* resBigInt = BigInt::lsh(cx, lhsBigInt, rhsBigInt);
   3124  if (!resBigInt) {
   3125    return false;
   3126  }
   3127  res.setBigInt(resBigInt);
   3128  return true;
   3129 }
   3130 
   3131 bool BigInt::rshValue(JSContext* cx, HandleValue lhs, HandleValue rhs,
   3132                      MutableHandleValue res) {
   3133  if (!ValidBigIntOperands(cx, lhs, rhs)) {
   3134    return false;
   3135  }
   3136 
   3137  RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   3138  RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   3139  BigInt* resBigInt = BigInt::rsh(cx, lhsBigInt, rhsBigInt);
   3140  if (!resBigInt) {
   3141    return false;
   3142  }
   3143  res.setBigInt(resBigInt);
   3144  return true;
   3145 }
   3146 
   3147 bool BigInt::bitAndValue(JSContext* cx, HandleValue lhs, HandleValue rhs,
   3148                         MutableHandleValue res) {
   3149  if (!ValidBigIntOperands(cx, lhs, rhs)) {
   3150    return false;
   3151  }
   3152 
   3153  RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   3154  RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   3155  BigInt* resBigInt = BigInt::bitAnd(cx, lhsBigInt, rhsBigInt);
   3156  if (!resBigInt) {
   3157    return false;
   3158  }
   3159  res.setBigInt(resBigInt);
   3160  return true;
   3161 }
   3162 
   3163 bool BigInt::bitXorValue(JSContext* cx, HandleValue lhs, HandleValue rhs,
   3164                         MutableHandleValue res) {
   3165  if (!ValidBigIntOperands(cx, lhs, rhs)) {
   3166    return false;
   3167  }
   3168 
   3169  RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   3170  RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   3171  BigInt* resBigInt = BigInt::bitXor(cx, lhsBigInt, rhsBigInt);
   3172  if (!resBigInt) {
   3173    return false;
   3174  }
   3175  res.setBigInt(resBigInt);
   3176  return true;
   3177 }
   3178 
   3179 bool BigInt::bitOrValue(JSContext* cx, HandleValue lhs, HandleValue rhs,
   3180                        MutableHandleValue res) {
   3181  if (!ValidBigIntOperands(cx, lhs, rhs)) {
   3182    return false;
   3183  }
   3184 
   3185  RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   3186  RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   3187  BigInt* resBigInt = BigInt::bitOr(cx, lhsBigInt, rhsBigInt);
   3188  if (!resBigInt) {
   3189    return false;
   3190  }
   3191  res.setBigInt(resBigInt);
   3192  return true;
   3193 }
   3194 
   3195 bool BigInt::bitNotValue(JSContext* cx, HandleValue operand,
   3196                         MutableHandleValue res) {
   3197  MOZ_ASSERT(operand.isBigInt());
   3198 
   3199  RootedBigInt operandBigInt(cx, operand.toBigInt());
   3200  BigInt* resBigInt = BigInt::bitNot(cx, operandBigInt);
   3201  if (!resBigInt) {
   3202    return false;
   3203  }
   3204  res.setBigInt(resBigInt);
   3205  return true;
   3206 }
   3207 
   3208 // BigInt proposal section 7.3
   3209 BigInt* js::ToBigInt(JSContext* cx, HandleValue val) {
   3210  RootedValue v(cx, val);
   3211 
   3212  // Step 1.
   3213  if (!ToPrimitive(cx, JSTYPE_NUMBER, &v)) {
   3214    return nullptr;
   3215  }
   3216 
   3217  // Step 2.
   3218  if (v.isBigInt()) {
   3219    return v.toBigInt();
   3220  }
   3221 
   3222  if (v.isBoolean()) {
   3223    return v.toBoolean() ? BigInt::one(cx) : BigInt::zero(cx);
   3224  }
   3225 
   3226  if (v.isString()) {
   3227    RootedString str(cx, v.toString());
   3228    BigInt* bi;
   3229    JS_TRY_VAR_OR_RETURN_NULL(cx, bi, StringToBigInt(cx, str));
   3230    if (!bi) {
   3231      JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
   3232                                JSMSG_BIGINT_INVALID_SYNTAX);
   3233      return nullptr;
   3234    }
   3235    return bi;
   3236  }
   3237 
   3238  ReportValueError(cx, JSMSG_CANT_CONVERT_TO, JSDVG_IGNORE_STACK, v, nullptr,
   3239                   "BigInt");
   3240  return nullptr;
   3241 }
   3242 
   3243 JS::Result<int64_t> js::ToBigInt64(JSContext* cx, HandleValue v) {
   3244  BigInt* bi = js::ToBigInt(cx, v);
   3245  if (!bi) {
   3246    return cx->alreadyReportedError();
   3247  }
   3248  return BigInt::toInt64(bi);
   3249 }
   3250 
   3251 JS::Result<uint64_t> js::ToBigUint64(JSContext* cx, HandleValue v) {
   3252  BigInt* bi = js::ToBigInt(cx, v);
   3253  if (!bi) {
   3254    return cx->alreadyReportedError();
   3255  }
   3256  return BigInt::toUint64(bi);
   3257 }
   3258 
   3259 double BigInt::numberValue(const BigInt* x) {
   3260  if (x->isZero()) {
   3261    return 0.0;
   3262  }
   3263 
   3264  using Double = mozilla::FloatingPoint<double>;
   3265  constexpr uint8_t ExponentShift = Double::kExponentShift;
   3266  constexpr uint8_t SignificandWidth = Double::kSignificandWidth;
   3267  constexpr unsigned ExponentBias = Double::kExponentBias;
   3268  constexpr uint8_t SignShift = Double::kExponentWidth + SignificandWidth;
   3269 
   3270  MOZ_ASSERT(x->digitLength() > 0);
   3271 
   3272  // Fast path for the likely-common case of up to a uint64_t of magnitude not
   3273  // exceeding integral precision in IEEE-754.  (Note that we *depend* on this
   3274  // optimization being performed further down.)
   3275  if (x->absFitsInUint64()) {
   3276    uint64_t magnitude = x->uint64FromAbsNonZero();
   3277    const uint64_t MaxIntegralPrecisionDouble = uint64_t(1)
   3278                                                << (SignificandWidth + 1);
   3279    if (magnitude <= MaxIntegralPrecisionDouble) {
   3280      return x->isNegative() ? -double(magnitude) : +double(magnitude);
   3281    }
   3282  }
   3283 
   3284  size_t length = x->digitLength();
   3285  Digit msd = x->digit(length - 1);
   3286  uint8_t msdLeadingZeroes = DigitLeadingZeroes(msd);
   3287 
   3288  // `2**ExponentBias` is the largest power of two in a finite IEEE-754
   3289  // double.  If this bigint has a greater power of two, it'll round to
   3290  // infinity.
   3291  uint64_t exponent = length * DigitBits - msdLeadingZeroes - 1;
   3292  if (exponent > ExponentBias) {
   3293    return x->isNegative() ? mozilla::NegativeInfinity<double>()
   3294                           : mozilla::PositiveInfinity<double>();
   3295  }
   3296 
   3297  // Otherwise munge the most significant bits of the number into proper
   3298  // position in an IEEE-754 double and go to town.
   3299 
   3300  // Omit the most significant bit: the IEEE-754 format includes this bit
   3301  // implicitly for all double-precision integers.
   3302  const uint8_t msdIgnoredBits = msdLeadingZeroes + 1;
   3303  const uint8_t msdIncludedBits = DigitBits - msdIgnoredBits;
   3304 
   3305  // We compute the final mantissa of the result, shifted upward to the top of
   3306  // the `uint64_t` space -- plus an extra bit to detect potential rounding.
   3307  constexpr uint8_t BitsNeededForShiftedMantissa = SignificandWidth + 1;
   3308 
   3309  // Shift `msd`'s contributed bits upward to remove high-order zeroes and the
   3310  // highest set bit (which is implicit in IEEE-754 integral values so must be
   3311  // removed) and to add low-order zeroes.  (Lower-order garbage bits are
   3312  // discarded when `shiftedMantissa` is converted to a real mantissa.)
   3313  uint64_t shiftedMantissa =
   3314      msdIncludedBits == 0 ? 0 : uint64_t(msd) << (64 - msdIncludedBits);
   3315 
   3316  // If the extra bit is set, correctly rounding the result may require
   3317  // examining all lower-order bits.  Also compute 1) the index of the Digit
   3318  // storing the extra bit, and 2) whether bits beneath the extra bit in that
   3319  // Digit are nonzero so we can round if needed.
   3320  size_t digitContainingExtraBit;
   3321  Digit bitsBeneathExtraBitInDigitContainingExtraBit;
   3322 
   3323  // Add shifted bits to `shiftedMantissa` until we have a complete mantissa and
   3324  // an extra bit.
   3325  if (msdIncludedBits >= BitsNeededForShiftedMantissa) {
   3326    //       DigitBits=64 (necessarily for msdIncludedBits ≥ SignificandWidth+1;
   3327    //            |        C++ compiler range analysis ought eliminate this
   3328    //            |        check on 32-bit)
   3329    //   _________|__________
   3330    //  /                    |
   3331    //        msdIncludedBits
   3332    //      ________|________
   3333    //     /                 |
   3334    // [001···················|
   3335    //  \_/\_____________/\__|
   3336    //   |            |    |
   3337    // msdIgnoredBits |   bits below the extra bit (may be no bits)
   3338    //      BitsNeededForShiftedMantissa=SignificandWidth+1
   3339    digitContainingExtraBit = length - 1;
   3340 
   3341    const uint8_t countOfBitsInDigitBelowExtraBit =
   3342        DigitBits - BitsNeededForShiftedMantissa - msdIgnoredBits;
   3343    bitsBeneathExtraBitInDigitContainingExtraBit =
   3344        msd & ((Digit(1) << countOfBitsInDigitBelowExtraBit) - 1);
   3345  } else {
   3346    MOZ_ASSERT(length >= 2,
   3347               "single-Digit numbers with this few bits should have been "
   3348               "handled by the fast-path above");
   3349 
   3350    Digit second = x->digit(length - 2);
   3351    if (DigitBits == 64) {
   3352      shiftedMantissa |= second >> msdIncludedBits;
   3353 
   3354      digitContainingExtraBit = length - 2;
   3355 
   3356      //  msdIncludedBits + DigitBits
   3357      //      ________|_________
   3358      //     /                  |
   3359      //             DigitBits=64
   3360      // msdIncludedBits    |
   3361      //      __|___   _____|___
   3362      //     /      \ /         |
   3363      // [001········|···········|
   3364      //  \_/\_____________/\___|
   3365      //   |            |     |
   3366      // msdIgnoredBits | bits below the extra bit (always more than one)
   3367      //                |
   3368      //      BitsNeededForShiftedMantissa=SignificandWidth+1
   3369      const uint8_t countOfBitsInSecondDigitBelowExtraBit =
   3370          (msdIncludedBits + DigitBits) - BitsNeededForShiftedMantissa;
   3371 
   3372      bitsBeneathExtraBitInDigitContainingExtraBit =
   3373          second << (DigitBits - countOfBitsInSecondDigitBelowExtraBit);
   3374    } else {
   3375      shiftedMantissa |= uint64_t(second) << msdIgnoredBits;
   3376 
   3377      if (msdIncludedBits + DigitBits >= BitsNeededForShiftedMantissa) {
   3378        digitContainingExtraBit = length - 2;
   3379 
   3380        //  msdIncludedBits + DigitBits
   3381        //      ______|________
   3382        //     /               |
   3383        //             DigitBits=32
   3384        // msdIncludedBits |
   3385        //      _|_   _____|___
   3386        //     /   \ /         |
   3387        // [001·····|···········|
   3388        //     \___________/\__|
   3389        //          |        |
   3390        //          |      bits below the extra bit (may be no bits)
   3391        //      BitsNeededForShiftedMantissa=SignificandWidth+1
   3392        const uint8_t countOfBitsInSecondDigitBelowExtraBit =
   3393            (msdIncludedBits + DigitBits) - BitsNeededForShiftedMantissa;
   3394 
   3395        bitsBeneathExtraBitInDigitContainingExtraBit =
   3396            second & ((Digit(1) << countOfBitsInSecondDigitBelowExtraBit) - 1);
   3397      } else {
   3398        MOZ_ASSERT(length >= 3,
   3399                   "we must have at least three digits here, because "
   3400                   "`msdIncludedBits + 32 < BitsNeededForShiftedMantissa` "
   3401                   "guarantees `x < 2**53` -- and therefore the "
   3402                   "MaxIntegralPrecisionDouble optimization above will have "
   3403                   "handled two-digit cases");
   3404 
   3405        Digit third = x->digit(length - 3);
   3406        shiftedMantissa |= uint64_t(third) >> msdIncludedBits;
   3407 
   3408        digitContainingExtraBit = length - 3;
   3409 
   3410        //    msdIncludedBits + DigitBits + DigitBits
   3411        //      ____________|______________
   3412        //     /                           |
   3413        //             DigitBits=32
   3414        // msdIncludedBits |     DigitBits=32
   3415        //      _|_   _____|___   ____|____
   3416        //     /   \ /         \ /         |
   3417        // [001·····|···········|···········|
   3418        //     \____________________/\_____|
   3419        //               |               |
   3420        //               |      bits below the extra bit
   3421        //      BitsNeededForShiftedMantissa=SignificandWidth+1
   3422        static_assert(2 * DigitBits > BitsNeededForShiftedMantissa,
   3423                      "two 32-bit digits should more than fill a mantissa");
   3424        const uint8_t countOfBitsInThirdDigitBelowExtraBit =
   3425            msdIncludedBits + 2 * DigitBits - BitsNeededForShiftedMantissa;
   3426 
   3427        // Shift out the mantissa bits and the extra bit.
   3428        bitsBeneathExtraBitInDigitContainingExtraBit =
   3429            third << (DigitBits - countOfBitsInThirdDigitBelowExtraBit);
   3430      }
   3431    }
   3432  }
   3433 
   3434  constexpr uint64_t LeastSignificantBit = uint64_t(1)
   3435                                           << (64 - SignificandWidth);
   3436  constexpr uint64_t ExtraBit = LeastSignificantBit >> 1;
   3437 
   3438  // The extra bit must be set for rounding to change the mantissa.
   3439  if ((shiftedMantissa & ExtraBit) != 0) {
   3440    bool shouldRoundUp;
   3441    if (shiftedMantissa & LeastSignificantBit) {
   3442      // If the lowest mantissa bit is set, it doesn't matter what lower bits
   3443      // are: nearest-even rounds up regardless.
   3444      shouldRoundUp = true;
   3445    } else {
   3446      // If the lowest mantissa bit is unset, *all* lower bits are relevant.
   3447      // All-zero bits below the extra bit situates `x` halfway between two
   3448      // values, and the nearest *even* value lies downward.  But if any bit
   3449      // below the extra bit is set, `x` is closer to the rounded-up value.
   3450      shouldRoundUp = bitsBeneathExtraBitInDigitContainingExtraBit != 0;
   3451      if (!shouldRoundUp) {
   3452        while (digitContainingExtraBit-- > 0) {
   3453          if (x->digit(digitContainingExtraBit) != 0) {
   3454            shouldRoundUp = true;
   3455            break;
   3456          }
   3457        }
   3458      }
   3459    }
   3460 
   3461    if (shouldRoundUp) {
   3462      // Add one to the significand bits.  If they overflow, the exponent must
   3463      // also be increased.  If *that* overflows, return the correct infinity.
   3464      uint64_t before = shiftedMantissa;
   3465      shiftedMantissa += ExtraBit;
   3466      if (shiftedMantissa < before) {
   3467        exponent++;
   3468        if (exponent > ExponentBias) {
   3469          return x->isNegative() ? NegativeInfinity<double>()
   3470                                 : PositiveInfinity<double>();
   3471        }
   3472      }
   3473    }
   3474  }
   3475 
   3476  uint64_t significandBits = shiftedMantissa >> (64 - SignificandWidth);
   3477  uint64_t signBit = uint64_t(x->isNegative() ? 1 : 0) << SignShift;
   3478  uint64_t exponentBits = (exponent + ExponentBias) << ExponentShift;
   3479  return mozilla::BitwiseCast<double>(signBit | exponentBits | significandBits);
   3480 }
   3481 
   3482 int8_t BigInt::compare(const BigInt* x, const BigInt* y) {
   3483  // Sanity checks to catch negative zeroes escaping to the wild.
   3484  MOZ_ASSERT(!x->isNegative() || !x->isZero());
   3485  MOZ_ASSERT(!y->isNegative() || !y->isZero());
   3486 
   3487  bool xSign = x->isNegative();
   3488 
   3489  if (xSign != y->isNegative()) {
   3490    return xSign ? -1 : 1;
   3491  }
   3492 
   3493  if (xSign) {
   3494    std::swap(x, y);
   3495  }
   3496 
   3497  return absoluteCompare(x, y);
   3498 }
   3499 
   3500 bool BigInt::equal(const BigInt* lhs, const BigInt* rhs) {
   3501  if (lhs == rhs) {
   3502    return true;
   3503  }
   3504  if (lhs->digitLength() != rhs->digitLength()) {
   3505    return false;
   3506  }
   3507  if (lhs->isNegative() != rhs->isNegative()) {
   3508    return false;
   3509  }
   3510  for (size_t i = 0; i < lhs->digitLength(); i++) {
   3511    if (lhs->digit(i) != rhs->digit(i)) {
   3512      return false;
   3513    }
   3514  }
   3515  return true;
   3516 }
   3517 
   3518 int8_t BigInt::compare(const BigInt* x, double y) {
   3519  MOZ_ASSERT(!std::isnan(y));
   3520 
   3521  constexpr int LessThan = -1, Equal = 0, GreaterThan = 1;
   3522 
   3523  // ±Infinity exceeds a finite bigint value.
   3524  if (!std::isfinite(y)) {
   3525    return y > 0 ? LessThan : GreaterThan;
   3526  }
   3527 
   3528  // Handle `x === 0n` and `y == 0` special cases.
   3529  if (x->isZero()) {
   3530    if (y == 0) {
   3531      // -0 and +0 are treated identically.
   3532      return Equal;
   3533    }
   3534 
   3535    return y > 0 ? LessThan : GreaterThan;
   3536  }
   3537 
   3538  const bool xNegative = x->isNegative();
   3539  if (y == 0) {
   3540    return xNegative ? LessThan : GreaterThan;
   3541  }
   3542 
   3543  // Nonzero `x` and `y` with different signs are trivially compared.
   3544  const bool yNegative = y < 0;
   3545  if (xNegative != yNegative) {
   3546    return xNegative ? LessThan : GreaterThan;
   3547  }
   3548 
   3549  // `x` and `y` are same-signed.  Determine which has greater magnitude,
   3550  // then combine that with the signedness just computed to reach a result.
   3551  const int exponent = mozilla::ExponentComponent(y);
   3552  if (exponent < 0) {
   3553    // `y` is a nonzero fraction of magnitude less than 1.
   3554    return xNegative ? LessThan : GreaterThan;
   3555  }
   3556 
   3557  size_t xLength = x->digitLength();
   3558  MOZ_ASSERT(xLength > 0);
   3559 
   3560  Digit xMSD = x->digit(xLength - 1);
   3561  const int shift = DigitLeadingZeroes(xMSD);
   3562  int xBitLength = xLength * DigitBits - shift;
   3563 
   3564  // Differing bit-length makes for a simple comparison.
   3565  int yBitLength = exponent + 1;
   3566  if (xBitLength < yBitLength) {
   3567    return xNegative ? GreaterThan : LessThan;
   3568  }
   3569  if (xBitLength > yBitLength) {
   3570    return xNegative ? LessThan : GreaterThan;
   3571  }
   3572 
   3573  // Compare the high 64 bits of both numbers.  (Lower-order bits not present
   3574  // in either number are zeroed.)  Either that distinguishes `x` and `y`, or
   3575  // `x` and `y` differ only if a subsequent nonzero bit in `x` means `x` has
   3576  // larger magnitude.
   3577 
   3578  using Double = mozilla::FloatingPoint<double>;
   3579  constexpr uint8_t SignificandWidth = Double::kSignificandWidth;
   3580  constexpr uint64_t SignificandBits = Double::kSignificandBits;
   3581 
   3582  const uint64_t doubleBits = mozilla::BitwiseCast<uint64_t>(y);
   3583  const uint64_t significandBits = doubleBits & SignificandBits;
   3584 
   3585  // Readd the implicit-one bit when constructing `y`'s high 64 bits.
   3586  const uint64_t yHigh64Bits =
   3587      ((uint64_t(1) << SignificandWidth) | significandBits)
   3588      << (64 - SignificandWidth - 1);
   3589 
   3590  // Cons up `x`'s high 64 bits, backfilling zeroes for binary fractions of 1
   3591  // if `x` doesn't have 64 bits.
   3592  uint8_t xBitsFilled = DigitBits - shift;
   3593  uint64_t xHigh64Bits = uint64_t(xMSD) << (64 - xBitsFilled);
   3594 
   3595  // At this point we no longer need to look at the most significant digit.
   3596  xLength--;
   3597 
   3598  // The high 64 bits from `x` will probably not align to a digit boundary.
   3599  // `xHasNonZeroLeftoverBits` will be set to true if any remaining
   3600  // least-significant bit from the digit holding xHigh64Bits's
   3601  // least-significant bit is nonzero.
   3602  bool xHasNonZeroLeftoverBits = false;
   3603 
   3604  if (xBitsFilled < std::min(xBitLength, 64)) {
   3605    MOZ_ASSERT(xLength >= 1,
   3606               "If there are more bits to fill, there should be "
   3607               "more digits to fill them from");
   3608 
   3609    Digit second = x->digit(--xLength);
   3610    if (DigitBits == 32) {
   3611      xBitsFilled += 32;
   3612      xHigh64Bits |= uint64_t(second) << (64 - xBitsFilled);
   3613      if (xBitsFilled < 64 && xLength >= 1) {
   3614        Digit third = x->digit(--xLength);
   3615        const uint8_t neededBits = 64 - xBitsFilled;
   3616        xHigh64Bits |= uint64_t(third) >> (DigitBits - neededBits);
   3617        xHasNonZeroLeftoverBits = (third << neededBits) != 0;
   3618      }
   3619    } else {
   3620      const uint8_t neededBits = 64 - xBitsFilled;
   3621      xHigh64Bits |= uint64_t(second) >> (DigitBits - neededBits);
   3622      xHasNonZeroLeftoverBits = (second << neededBits) != 0;
   3623    }
   3624  }
   3625 
   3626  // If high bits are unequal, the larger one has greater magnitude.
   3627  if (yHigh64Bits > xHigh64Bits) {
   3628    return xNegative ? GreaterThan : LessThan;
   3629  }
   3630  if (xHigh64Bits > yHigh64Bits) {
   3631    return xNegative ? LessThan : GreaterThan;
   3632  }
   3633 
   3634  // Otherwise the top 64 bits of both are equal.  If the values differ, a
   3635  // lower-order bit in `x` is nonzero and `x` has greater magnitude than
   3636  // `y`; otherwise `x == y`.
   3637  if (xHasNonZeroLeftoverBits) {
   3638    return xNegative ? LessThan : GreaterThan;
   3639  }
   3640  while (xLength != 0) {
   3641    if (x->digit(--xLength) != 0) {
   3642      return xNegative ? LessThan : GreaterThan;
   3643    }
   3644  }
   3645 
   3646  return Equal;
   3647 }
   3648 
   3649 bool BigInt::equal(const BigInt* lhs, double rhs) {
   3650  if (std::isnan(rhs)) {
   3651    return false;
   3652  }
   3653  return compare(lhs, rhs) == 0;
   3654 }
   3655 
   3656 JS::Result<bool> BigInt::equal(JSContext* cx, Handle<BigInt*> lhs,
   3657                               HandleString rhs) {
   3658  BigInt* rhsBigInt = MOZ_TRY(StringToBigInt(cx, rhs));
   3659  if (!rhsBigInt) {
   3660    return false;
   3661  }
   3662  return equal(lhs, rhsBigInt);
   3663 }
   3664 
   3665 // BigInt proposal section 1.1.12. BigInt::lessThan ( x, y )
   3666 bool BigInt::lessThan(const BigInt* x, const BigInt* y) {
   3667  return compare(x, y) < 0;
   3668 }
   3669 
   3670 Maybe<bool> BigInt::lessThan(const BigInt* lhs, double rhs) {
   3671  if (std::isnan(rhs)) {
   3672    return Maybe<bool>(Nothing());
   3673  }
   3674  return Some(compare(lhs, rhs) < 0);
   3675 }
   3676 
   3677 Maybe<bool> BigInt::lessThan(double lhs, const BigInt* rhs) {
   3678  if (std::isnan(lhs)) {
   3679    return Maybe<bool>(Nothing());
   3680  }
   3681  return Some(-compare(rhs, lhs) < 0);
   3682 }
   3683 
   3684 bool BigInt::lessThan(JSContext* cx, HandleBigInt lhs, HandleString rhs,
   3685                      Maybe<bool>& res) {
   3686  BigInt* rhsBigInt;
   3687  JS_TRY_VAR_OR_RETURN_FALSE(cx, rhsBigInt, StringToBigInt(cx, rhs));
   3688  if (!rhsBigInt) {
   3689    res = Nothing();
   3690    return true;
   3691  }
   3692  res = Some(lessThan(lhs, rhsBigInt));
   3693  return true;
   3694 }
   3695 
   3696 bool BigInt::lessThan(JSContext* cx, HandleString lhs, HandleBigInt rhs,
   3697                      Maybe<bool>& res) {
   3698  BigInt* lhsBigInt;
   3699  JS_TRY_VAR_OR_RETURN_FALSE(cx, lhsBigInt, StringToBigInt(cx, lhs));
   3700  if (!lhsBigInt) {
   3701    res = Nothing();
   3702    return true;
   3703  }
   3704  res = Some(lessThan(lhsBigInt, rhs));
   3705  return true;
   3706 }
   3707 
   3708 bool BigInt::lessThan(JSContext* cx, HandleValue lhs, HandleValue rhs,
   3709                      Maybe<bool>& res) {
   3710  if (lhs.isBigInt()) {
   3711    if (rhs.isString()) {
   3712      RootedBigInt lhsBigInt(cx, lhs.toBigInt());
   3713      RootedString rhsString(cx, rhs.toString());
   3714      return lessThan(cx, lhsBigInt, rhsString, res);
   3715    }
   3716 
   3717    if (rhs.isNumber()) {
   3718      res = lessThan(lhs.toBigInt(), rhs.toNumber());
   3719      return true;
   3720    }
   3721 
   3722    MOZ_ASSERT(rhs.isBigInt());
   3723    res = Some(lessThan(lhs.toBigInt(), rhs.toBigInt()));
   3724    return true;
   3725  }
   3726 
   3727  MOZ_ASSERT(rhs.isBigInt());
   3728  if (lhs.isString()) {
   3729    RootedString lhsString(cx, lhs.toString());
   3730    RootedBigInt rhsBigInt(cx, rhs.toBigInt());
   3731    return lessThan(cx, lhsString, rhsBigInt, res);
   3732  }
   3733 
   3734  MOZ_ASSERT(lhs.isNumber());
   3735  res = lessThan(lhs.toNumber(), rhs.toBigInt());
   3736  return true;
   3737 }
   3738 
   3739 template <js::AllowGC allowGC>
   3740 JSLinearString* BigInt::toString(JSContext* cx, HandleBigInt x, uint8_t radix) {
   3741  MOZ_ASSERT(2 <= radix && radix <= 36);
   3742 
   3743  if (x->isZero()) {
   3744    return cx->staticStrings().getInt(0);
   3745  }
   3746 
   3747  if (x->digitLength() == 1) {
   3748    return toStringSingleDigit<allowGC>(cx, x->digit(0), x->isNegative(),
   3749                                        radix);
   3750  }
   3751 
   3752  if (mozilla::IsPowerOfTwo(radix)) {
   3753    return toStringBasePowerOfTwo<allowGC>(cx, x, radix);
   3754  }
   3755 
   3756  // Punt on doing generic toString without GC.
   3757  if (!allowGC) {
   3758    return nullptr;
   3759  }
   3760 
   3761  return toStringGeneric(cx, x, radix);
   3762 }
   3763 
   3764 template JSLinearString* BigInt::toString<js::CanGC>(JSContext* cx,
   3765                                                     HandleBigInt x,
   3766                                                     uint8_t radix);
   3767 template JSLinearString* BigInt::toString<js::NoGC>(JSContext* cx,
   3768                                                    HandleBigInt x,
   3769                                                    uint8_t radix);
   3770 
   3771 template <typename CharT>
   3772 static inline BigInt* ParseStringBigIntLiteral(JSContext* cx,
   3773                                               Range<const CharT> range,
   3774                                               bool* haveParseError) {
   3775  auto start = range.begin();
   3776  auto end = range.end();
   3777 
   3778  while (start < end && unicode::IsSpace(start[0])) {
   3779    start++;
   3780  }
   3781 
   3782  while (start < end && unicode::IsSpace(end[-1])) {
   3783    end--;
   3784  }
   3785 
   3786  if (start == end) {
   3787    return BigInt::zero(cx);
   3788  }
   3789 
   3790  // StringNumericLiteral ::: StrDecimalLiteral, but without Infinity, decimal
   3791  // points, or exponents.  Note that the raw '+' or '-' cases fall through
   3792  // because the string is too short, and eventually signal a parse error.
   3793  if (end - start > 1) {
   3794    if (start[0] == '+') {
   3795      bool isNegative = false;
   3796      start++;
   3797      return BigInt::parseLiteralDigits(cx, Range<const CharT>(start, end), 10,
   3798                                        isNegative, haveParseError);
   3799    }
   3800    if (start[0] == '-') {
   3801      bool isNegative = true;
   3802      start++;
   3803      return BigInt::parseLiteralDigits(cx, Range<const CharT>(start, end), 10,
   3804                                        isNegative, haveParseError);
   3805    }
   3806  }
   3807 
   3808  return BigInt::parseLiteral(cx, Range<const CharT>(start, end),
   3809                              haveParseError);
   3810 }
   3811 
   3812 // Called from BigInt constructor.
   3813 JS::Result<BigInt*> js::StringToBigInt(JSContext* cx, HandleString str) {
   3814  JSLinearString* linear = str->ensureLinear(cx);
   3815  if (!linear) {
   3816    return cx->alreadyReportedOOM();
   3817  }
   3818 
   3819  AutoStableStringChars chars(cx);
   3820  if (!chars.init(cx, str)) {
   3821    return cx->alreadyReportedOOM();
   3822  }
   3823 
   3824  BigInt* res;
   3825  bool parseError = false;
   3826  if (chars.isLatin1()) {
   3827    res = ParseStringBigIntLiteral(cx, chars.latin1Range(), &parseError);
   3828  } else {
   3829    res = ParseStringBigIntLiteral(cx, chars.twoByteRange(), &parseError);
   3830  }
   3831 
   3832  // A nullptr result can indicate either a parse error or generic error.
   3833  if (!res && !parseError) {
   3834    return cx->alreadyReportedError();
   3835  }
   3836 
   3837  return res;
   3838 }
   3839 
   3840 // Called from parser with already trimmed and validated token.
   3841 BigInt* js::ParseBigIntLiteral(JSContext* cx,
   3842                               const Range<const char16_t>& chars) {
   3843  // This function is only called from the frontend when parsing BigInts. Parsed
   3844  // BigInts are stored in the script's data vector and therefore need to be
   3845  // allocated in the tenured heap.
   3846  constexpr gc::Heap heap = gc::Heap::Tenured;
   3847 
   3848  bool parseError = false;
   3849  BigInt* res = BigInt::parseLiteral(cx, chars, &parseError, heap);
   3850  if (!res) {
   3851    return nullptr;
   3852  }
   3853  MOZ_ASSERT(res->isTenured());
   3854  MOZ_RELEASE_ASSERT(!parseError);
   3855  return res;
   3856 }
   3857 
   3858 mozilla::Maybe<int64_t> js::ParseBigInt64Literal(
   3859    mozilla::Range<const char16_t> chars) {
   3860  size_t length = chars.length();
   3861  MOZ_ASSERT(length > 0);
   3862 
   3863  int32_t radix = 10;
   3864  if (length > 2 && chars[0] == '0') {
   3865    if (chars[1] == 'b' || chars[1] == 'B') {
   3866      // StringNumericLiteral ::: BinaryIntegerLiteral
   3867      radix = 2;
   3868    } else if (chars[1] == 'x' || chars[1] == 'X') {
   3869      // StringNumericLiteral ::: HexIntegerLiteral
   3870      radix = 16;
   3871    } else if (chars[1] == 'o' || chars[1] == 'O') {
   3872      // StringNumericLiteral ::: OctalIntegerLiteral
   3873      radix = 8;
   3874    }
   3875  }
   3876 
   3877  auto start = chars.begin();
   3878  const auto end = chars.end();
   3879 
   3880  // Skip over prefix.
   3881  if (radix != 10) {
   3882    start += 2;
   3883  }
   3884 
   3885  // Skipping leading zeroes.
   3886  while (*start == '0') {
   3887    start++;
   3888    if (start == end) {
   3889      return mozilla::Some(0);
   3890    }
   3891  }
   3892 
   3893  mozilla::CheckedInt<int64_t> r = 0;
   3894  while (start < end) {
   3895    char16_t c = *start++;
   3896    MOZ_ASSERT(mozilla::IsAsciiAlphanumeric(c));
   3897 
   3898    int32_t digit = mozilla::AsciiAlphanumericToNumber(c);
   3899    MOZ_ASSERT(digit < radix);
   3900 
   3901    r *= radix;
   3902    r += digit;
   3903    if (!r.isValid()) {
   3904      return mozilla::Nothing();
   3905    }
   3906  }
   3907 
   3908  return mozilla::Some(r.value());
   3909 }
   3910 
   3911 template <js::AllowGC allowGC>
   3912 JSAtom* js::BigIntToAtom(JSContext* cx, HandleBigInt bi) {
   3913  JSString* str = BigInt::toString<allowGC>(cx, bi, 10);
   3914  if (!str) {
   3915    return nullptr;
   3916  }
   3917  JSAtom* atom = AtomizeString(cx, str);
   3918  if (!atom) {
   3919    if constexpr (!allowGC) {
   3920      // NOTE: AtomizeString can call ReportAllocationOverflow other than
   3921      //       ReportOutOfMemory, but ReportAllocationOverflow cannot happen
   3922      //       because the length is guarded by BigInt::toString.
   3923      cx->recoverFromOutOfMemory();
   3924    }
   3925    return nullptr;
   3926  }
   3927  return atom;
   3928 }
   3929 
   3930 template JSAtom* js::BigIntToAtom<js::CanGC>(JSContext* cx, HandleBigInt bi);
   3931 template JSAtom* js::BigIntToAtom<js::NoGC>(JSContext* cx, HandleBigInt bi);
   3932 
   3933 #if defined(DEBUG) || defined(JS_JITSPEW)
   3934 void BigInt::dump() const {
   3935  js::Fprinter out(stderr);
   3936  dump(out);
   3937 }
   3938 
   3939 void BigInt::dump(js::GenericPrinter& out) const {
   3940  js::JSONPrinter json(out);
   3941  dump(json);
   3942  out.put("\n");
   3943 }
   3944 
   3945 void BigInt::dump(js::JSONPrinter& json) const {
   3946  json.beginObject();
   3947  dumpFields(json);
   3948  json.endObject();
   3949 }
   3950 
   3951 void BigInt::dumpFields(js::JSONPrinter& json) const {
   3952  json.formatProperty("address", "(JS::BigInt*)0x%p", this);
   3953 
   3954  json.property("digitLength", digitLength());
   3955 
   3956  js::GenericPrinter& out = json.beginStringProperty("value");
   3957  dumpLiteral(out);
   3958  json.endStringProperty();
   3959 }
   3960 
   3961 void BigInt::dumpStringContent(js::GenericPrinter& out) const {
   3962  dumpLiteral(out);
   3963 
   3964  out.printf(" @ (JS::BigInt*)0x%p", this);
   3965 }
   3966 
   3967 void BigInt::dumpLiteral(js::GenericPrinter& out) const {
   3968  if (isNegative()) {
   3969    out.putChar('-');
   3970  }
   3971 
   3972  if (digitLength() == 0) {
   3973    out.put("0");
   3974  } else if (digitLength() == 1) {
   3975    uint64_t d = digit(0);
   3976    out.printf("%" PRIu64, d);
   3977  } else {
   3978    out.put("0x");
   3979    for (size_t i = 0; i < digitLength(); i++) {
   3980      uint64_t d = digit(digitLength() - i - 1);
   3981      if (sizeof(Digit) == 4) {
   3982        out.printf("%.8" PRIX32, uint32_t(d));
   3983      } else {
   3984        out.printf("%.16" PRIX64, d);
   3985      }
   3986    }
   3987  }
   3988 
   3989  out.putChar('n');
   3990 }
   3991 #endif
   3992 
   3993 JS::ubi::Node::Size JS::ubi::Concrete<BigInt>::size(
   3994    mozilla::MallocSizeOf mallocSizeOf) const {
   3995  BigInt& bi = get();
   3996  size_t size = sizeof(JS::BigInt);
   3997  if (IsInsideNursery(&bi)) {
   3998    size += Nursery::nurseryCellHeaderSize();
   3999    size += bi.sizeOfExcludingThisInNursery(mallocSizeOf);
   4000  } else {
   4001    size += bi.sizeOfExcludingThis(mallocSizeOf);
   4002  }
   4003  return size;
   4004 }
   4005 
   4006 // Public API
   4007 
   4008 BigInt* JS::NumberToBigInt(JSContext* cx, double num) {
   4009  return js::NumberToBigInt(cx, num);
   4010 }
   4011 
   4012 template <typename CharT>
   4013 static inline BigInt* StringToBigIntHelper(JSContext* cx,
   4014                                           const Range<const CharT>& chars) {
   4015  bool parseError = false;
   4016  BigInt* bi = ParseStringBigIntLiteral(cx, chars, &parseError);
   4017  if (!bi) {
   4018    if (parseError) {
   4019      JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
   4020                                JSMSG_BIGINT_INVALID_SYNTAX);
   4021    }
   4022    return nullptr;
   4023  }
   4024  MOZ_RELEASE_ASSERT(!parseError);
   4025  return bi;
   4026 }
   4027 
   4028 BigInt* JS::StringToBigInt(JSContext* cx,
   4029                           const Range<const Latin1Char>& chars) {
   4030  return StringToBigIntHelper(cx, chars);
   4031 }
   4032 
   4033 BigInt* JS::StringToBigInt(JSContext* cx, const Range<const char16_t>& chars) {
   4034  return StringToBigIntHelper(cx, chars);
   4035 }
   4036 
   4037 BigInt* JS::SimpleStringToBigInt(JSContext* cx, mozilla::Span<const char> chars,
   4038                                 uint8_t radix) {
   4039  if (chars.empty()) {
   4040    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
   4041                              JSMSG_BIGINT_INVALID_SYNTAX);
   4042    return nullptr;
   4043  }
   4044  if (radix < 2 || radix > 36) {
   4045    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_RADIX);
   4046    return nullptr;
   4047  }
   4048 
   4049  mozilla::Span<const Latin1Char> latin1{
   4050      reinterpret_cast<const Latin1Char*>(chars.data()), chars.size()};
   4051 
   4052  bool isNegative = false;
   4053  if (chars.size() > 1 && (chars[0] == '-' || chars[0] == '+')) {
   4054    isNegative = chars[0] == '-';
   4055    latin1 = latin1.From(1);
   4056  }
   4057 
   4058  bool haveParseError = false;
   4059  BigInt* bi = BigInt::parseLiteralDigits(cx, mozilla::Range{latin1}, radix,
   4060                                          isNegative, &haveParseError);
   4061  if (!bi) {
   4062    if (haveParseError) {
   4063      JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
   4064                                JSMSG_BIGINT_INVALID_SYNTAX);
   4065    }
   4066    return nullptr;
   4067  }
   4068  MOZ_RELEASE_ASSERT(!haveParseError);
   4069  return bi;
   4070 }
   4071 
   4072 BigInt* JS::ToBigInt(JSContext* cx, HandleValue val) {
   4073  return js::ToBigInt(cx, val);
   4074 }
   4075 
   4076 int64_t JS::ToBigInt64(const JS::BigInt* bi) { return BigInt::toInt64(bi); }
   4077 
   4078 uint64_t JS::ToBigUint64(const JS::BigInt* bi) { return BigInt::toUint64(bi); }
   4079 
   4080 double JS::BigIntToNumber(const JS::BigInt* bi) {
   4081  return BigInt::numberValue(bi);
   4082 }
   4083 
   4084 bool JS::BigIntIsNegative(const BigInt* bi) {
   4085  return !bi->isZero() && bi->isNegative();
   4086 }
   4087 
   4088 bool JS::BigIntFitsNumber(const BigInt* bi, double* out) {
   4089  return bi->isNumber(bi, out);
   4090 }
   4091 
   4092 JSString* JS::BigIntToString(JSContext* cx, Handle<BigInt*> bi, uint8_t radix) {
   4093  if (radix < 2 || radix > 36) {
   4094    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_RADIX);
   4095    return nullptr;
   4096  }
   4097  return BigInt::toString<CanGC>(cx, bi, radix);
   4098 }
   4099 
   4100 // Semi-public template details
   4101 
   4102 BigInt* JS::detail::BigIntFromInt64(JSContext* cx, int64_t num) {
   4103  return BigInt::createFromInt64(cx, num);
   4104 }
   4105 
   4106 BigInt* JS::detail::BigIntFromUint64(JSContext* cx, uint64_t num) {
   4107  return BigInt::createFromUint64(cx, num);
   4108 }
   4109 
   4110 BigInt* JS::detail::BigIntFromBool(JSContext* cx, bool b) {
   4111  return b ? BigInt::one(cx) : BigInt::zero(cx);
   4112 }
   4113 
   4114 bool JS::detail::BigIntIsInt64(const BigInt* bi, int64_t* result) {
   4115  return BigInt::isInt64(bi, result);
   4116 }
   4117 
   4118 bool JS::detail::BigIntIsUint64(const BigInt* bi, uint64_t* result) {
   4119  return BigInt::isUint64(bi, result);
   4120 }