Changeset 262012 in webkit


Ignore:
Timestamp:
May 21, 2020 10:21:14 AM (4 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Fix 32bit JSBigInt with INT32_MAX < x <= UINT32_MAX
https://bugs.webkit.org/show_bug.cgi?id=212193

Reviewed by Mark Lam.

In 32bit architecture, we are creating one-length JSBigInt for INT32_MIN <= x <= INT32_MAX, and two-length JSBigInt otherwise.
This is wrong since one-length JSBigInt should cover from -UINT32_MAX <= x <= UINT32_MAX.

This patch fixes the bug and cleans up createFrom(VM&, int64_t). And it also adds JSBigInt::createFrom(VM&, uint64_t) in preparation for [1]
Currently, this path is not used while it was used previously because BigIntConstructor starts using JSBigInt::createFrom(VM&, double). But this
will be used in [1], and simply the existing implementation is wrong.

[1]: https://bugs.webkit.org/show_bug.cgi?id=190800

  • runtime/JSBigInt.cpp:

(JSC::JSBigInt::createFromImpl):
(JSC::JSBigInt::createFrom):

  • runtime/JSBigInt.h:
Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r261993 r262012  
     12020-05-21  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Fix 32bit JSBigInt with INT32_MAX < x <= UINT32_MAX
     4        https://bugs.webkit.org/show_bug.cgi?id=212193
     5
     6        Reviewed by Mark Lam.
     7
     8        In 32bit architecture, we are creating one-length JSBigInt for INT32_MIN <= x <= INT32_MAX, and two-length JSBigInt otherwise.
     9        This is wrong since one-length JSBigInt should cover from -UINT32_MAX <= x <= UINT32_MAX.
     10
     11        This patch fixes the bug and cleans up createFrom(VM&, int64_t). And it also adds JSBigInt::createFrom(VM&, uint64_t) in preparation for [1]
     12        Currently, this path is not used while it was used previously because BigIntConstructor starts using JSBigInt::createFrom(VM&, double). But this
     13        will be used in [1], and simply the existing implementation is wrong.
     14
     15        [1]: https://bugs.webkit.org/show_bug.cgi?id=190800
     16
     17        * runtime/JSBigInt.cpp:
     18        (JSC::JSBigInt::createFromImpl):
     19        (JSC::JSBigInt::createFrom):
     20        * runtime/JSBigInt.h:
     21
    1222020-05-21  Paulo Matos  <pmatos@igalia.com>
    223
  • trunk/Source/JavaScriptCore/runtime/JSBigInt.cpp

    r261895 r262012  
    136136}
    137137
    138 JSBigInt* JSBigInt::createFrom(VM& vm, int64_t value)
     138inline JSBigInt* JSBigInt::createFromImpl(VM& vm, uint64_t value, bool sign)
    139139{
    140140    if (!value)
     
    143143    // This path is not just an optimization: because we do not call rightTrim at the end of this function,
    144144    // it would be a bug to create a BigInt with length=2 in this case.
    145     if (sizeof(Digit) == 8 || (value <= INT_MAX && value >= INT_MIN)) {
     145    if (sizeof(Digit) == 8 || value <= UINT32_MAX) {
    146146        JSBigInt* bigInt = createWithLengthUnchecked(vm, 1);
    147         if (value < 0) {
    148             bigInt->setDigit(0, static_cast<Digit>(static_cast<uint64_t>(-(value + 1)) + 1));
    149             bigInt->setSign(true);
    150         } else
    151             bigInt->setDigit(0, static_cast<Digit>(value));
    152        
     147        bigInt->setDigit(0, static_cast<Digit>(value));
     148        bigInt->setSign(sign);
    153149        return bigInt;
    154150    }
    155    
     151
     152    ASSERT(sizeof(Digit) == 4);
    156153    JSBigInt* bigInt = createWithLengthUnchecked(vm, 2);
    157     uint64_t tempValue;
    158     bool sign = false;
    159     if (value < 0) {
    160         tempValue = static_cast<uint64_t>(-(value + 1)) + 1;
    161         sign = true;
    162     } else
    163         tempValue = value;
    164    
    165     Digit lowBits  = static_cast<Digit>(tempValue & 0xffffffff);
    166     Digit highBits = static_cast<Digit>((tempValue >> 32) & 0xffffffff);
    167    
     154    Digit lowBits  = static_cast<Digit>(value & 0xffffffff);
     155    Digit highBits = static_cast<Digit>((value >> 32) & 0xffffffff);
     156
     157    ASSERT(highBits);
     158
    168159    bigInt->setDigit(0, lowBits);
    169160    bigInt->setDigit(1, highBits);
    170161    bigInt->setSign(sign);
    171    
     162
    172163    return bigInt;
     164}
     165
     166JSBigInt* JSBigInt::createFrom(VM& vm, uint64_t value)
     167{
     168    return createFromImpl(vm, value, false);
     169}
     170
     171JSBigInt* JSBigInt::createFrom(VM& vm, int64_t value)
     172{
     173    uint64_t unsignedValue;
     174    bool sign = false;
     175    if (value < 0) {
     176        unsignedValue = static_cast<uint64_t>(-(value + 1)) + 1;
     177        sign = true;
     178    } else
     179        unsignedValue = value;
     180    return createFromImpl(vm, unsignedValue, sign);
    173181}
    174182
  • trunk/Source/JavaScriptCore/runtime/JSBigInt.h

    r261199 r262012  
    7373    static JSBigInt* createFrom(VM&, uint32_t value);
    7474    static JSBigInt* createFrom(VM&, int64_t value);
     75    static JSBigInt* createFrom(VM&, uint64_t value);
    7576    static JSBigInt* createFrom(VM&, bool value);
    7677    static JSBigInt* createFrom(VM&, double value);
     
    427428private:
    428429    JSBigInt(VM&, Structure*, Digit*, unsigned length);
     430
     431    static JSBigInt* createFromImpl(VM&, uint64_t value, bool sign);
    429432
    430433    static constexpr unsigned bitsPerByte = 8;
Note: See TracChangeset for help on using the changeset viewer.