Ignore:
Timestamp:
May 30, 2020, 12:46:53 AM (5 years ago)
Author:
[email protected]
Message:

[JSC] JSBigInt allocation should be graceful for OOM
https://bugs.webkit.org/show_bug.cgi?id=212512

Reviewed by Mark Lam.

JSTests:

  • stress/bigint-can-throw-oom.js: Copied from JSTests/stress/get-function-realm-not-doing-recursion.js.

(canThrow):
(foo):
(get foo):

  • stress/get-function-realm-not-doing-recursion.js:

(canThrow):

Source/JavaScriptCore:

This patch allows JSBigInt's storage allocation to fail gracefully if OOM condition happens.
We thread JSGlobalObject* instead of VM& and throw OOM error if storage allocation failed.
We also rename JSGlobalObject* globalObject parameter to JSGlobalObject* nullOrGlobalObjectForOOM
if it can be nullptr.

  • jit/JITOperations.cpp:
  • jsc.cpp:

(functionCreateHeapBigInt):

  • parser/ParserArena.cpp:

(JSC::IdentifierArena::makeBigIntDecimalIdentifier):

  • runtime/BigIntConstructor.cpp:

(JSC::toBigInt):
(JSC::callBigIntConstructor):

  • runtime/BigIntPrototype.cpp:

(JSC::toThisBigIntValue):
(JSC::bigIntProtoFuncToString):
(JSC::bigIntProtoFuncToLocaleString):
(JSC::bigIntProtoFuncValueOf):

  • runtime/CachedTypes.cpp:

(JSC::CachedBigInt::decode const):

  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

  • runtime/IntlNumberFormatPrototype.cpp:

(JSC::IntlNumberFormatFuncFormat):

  • runtime/JSBigInt.cpp:

(JSC::JSBigInt::createZero):
(JSC::JSBigInt::tryCreateZero):
(JSC::JSBigInt::createWithLength):
(JSC::JSBigInt::tryCreateWithLength):
(JSC::JSBigInt::createFrom):
(JSC::JSBigInt::tryCreateFrom):
(JSC::JSBigInt::createFromImpl):
(JSC::JSBigInt::parseInt):
(JSC::HeapBigIntImpl::toHeapBigInt):
(JSC::Int32BigIntImpl::toHeapBigInt):
(JSC::zeroImpl):
(JSC::JSBigInt::exponentiateImpl):
(JSC::JSBigInt::multiplyImpl):
(JSC::JSBigInt::divideImpl):
(JSC::JSBigInt::copy):
(JSC::JSBigInt::unaryMinusImpl):
(JSC::JSBigInt::unaryMinus):
(JSC::JSBigInt::remainderImpl):
(JSC::JSBigInt::incImpl):
(JSC::JSBigInt::decImpl):
(JSC::JSBigInt::addImpl):
(JSC::JSBigInt::subImpl):
(JSC::JSBigInt::bitwiseAndImpl):
(JSC::JSBigInt::bitwiseOrImpl):
(JSC::JSBigInt::bitwiseXorImpl):
(JSC::JSBigInt::absoluteAdd):
(JSC::JSBigInt::absoluteSub):
(JSC::JSBigInt::absoluteDivWithDigitDivisor):
(JSC::JSBigInt::absoluteDivWithBigIntDivisor):
(JSC::JSBigInt::absoluteLeftShiftAlwaysCopy):
(JSC::JSBigInt::absoluteBitwiseOp):
(JSC::JSBigInt::absoluteAnd):
(JSC::JSBigInt::absoluteOr):
(JSC::JSBigInt::absoluteAndNot):
(JSC::JSBigInt::absoluteXor):
(JSC::JSBigInt::absoluteAddOne):
(JSC::JSBigInt::absoluteSubOne):
(JSC::JSBigInt::leftShiftByAbsolute):
(JSC::JSBigInt::rightShiftByAbsolute):
(JSC::JSBigInt::rightShiftByMaximum):
(JSC::JSBigInt::toStringBasePowerOfTwo):
(JSC::JSBigInt::toStringGeneric):
(JSC::JSBigInt::rightTrim):
(JSC::JSBigInt::tryRightTrim):
(JSC::JSBigInt::allocateFor):
(JSC::JSBigInt::asIntNImpl):
(JSC::JSBigInt::asUintNImpl):
(JSC::JSBigInt::truncateToNBits):
(JSC::JSBigInt::truncateAndSubFromPowerOfTwo):
(JSC::JSBigInt::createWithLengthUnchecked): Deleted.

  • runtime/JSBigInt.h:
  • runtime/JSCJSValue.cpp:

(JSC::JSValue::toThisSlowCase const):

  • runtime/VM.cpp:

(JSC::VM::VM):

Source/WebCore:

  • bindings/js/SerializedScriptValue.cpp:

(WebCore::CloneDeserializer::readBigInt):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSBigInt.cpp

    r262054 r262342  
    8383}
    8484
    85 JSBigInt* JSBigInt::createZero(VM& vm)
    86 {
    87     JSBigInt* zeroBigInt = createWithLengthUnchecked(vm, 0);
    88     return zeroBigInt;
    89 }
    90 
    91 JSBigInt* JSBigInt::tryCreateWithLength(JSGlobalObject* globalObject, unsigned length)
    92 {
    93     VM& vm = globalObject->vm();
     85inline JSBigInt* JSBigInt::createZero(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm)
     86{
     87    return createWithLength(nullOrGlobalObjectForOOM, vm, 0);
     88}
     89
     90JSBigInt* JSBigInt::createZero(JSGlobalObject* globalObject)
     91{
     92    return createZero(globalObject, globalObject->vm());
     93}
     94
     95JSBigInt* JSBigInt::tryCreateZero(VM& vm)
     96{
     97    return createZero(nullptr, vm);
     98}
     99
     100inline JSBigInt* JSBigInt::createWithLength(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, unsigned length)
     101{
    94102    auto scope = DECLARE_THROW_SCOPE(vm);
    95 
    96103    if (UNLIKELY(length > maxLength)) {
    97         throwOutOfMemoryError(globalObject, scope, "BigInt generated from this operation is too big"_s);
     104        if (nullOrGlobalObjectForOOM)
     105            throwOutOfMemoryError(nullOrGlobalObjectForOOM, scope, "BigInt generated from this operation is too big"_s);
    98106        return nullptr;
    99107    }
    100108
    101     scope.release();
    102 
    103     return createWithLengthUnchecked(vm, length);
    104 }
    105 
    106 JSBigInt* JSBigInt::createWithLengthUnchecked(VM& vm, unsigned length)
    107 {
    108109    ASSERT(length <= maxLength);
    109     void* data = Gigacage::malloc(Gigacage::Primitive, length * sizeof(Digit));
     110    void* data = Gigacage::tryMalloc(Gigacage::Primitive, length * sizeof(Digit));
     111    if (UNLIKELY(!data)) {
     112        if (nullOrGlobalObjectForOOM)
     113            throwOutOfMemoryError(nullOrGlobalObjectForOOM, scope);
     114        return nullptr;
     115    }
    110116    JSBigInt* bigInt = new (NotNull, allocateCell<JSBigInt>(vm.heap)) JSBigInt(vm, vm.bigIntStructure.get(), reinterpret_cast<Digit*>(data), length);
    111117    bigInt->finishCreation(vm);
     
    113119}
    114120
    115 JSBigInt* JSBigInt::createFrom(VM& vm, int32_t value)
     121JSBigInt* JSBigInt::tryCreateWithLength(VM& vm, unsigned length)
     122{
     123    return createWithLength(nullptr, vm, length);
     124}
     125
     126JSBigInt* JSBigInt::createWithLength(JSGlobalObject* globalObject, unsigned length)
     127{
     128    return createWithLength(globalObject, globalObject->vm(), length);
     129}
     130
     131inline JSBigInt* JSBigInt::createFrom(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, int32_t value)
    116132{
    117133    if (!value)
    118         return createZero(vm);
    119    
    120     JSBigInt* bigInt = createWithLengthUnchecked(vm, 1);
     134        return createZero(nullOrGlobalObjectForOOM, vm);
     135
     136    JSBigInt* bigInt = createWithLength(nullOrGlobalObjectForOOM, vm, 1);
     137    if (UNLIKELY(!bigInt))
     138        return nullptr;
     139
    121140    if (value < 0) {
    122141        bigInt->setDigit(0, static_cast<Digit>(-1 * static_cast<int64_t>(value)));
     
    128147}
    129148
    130 JSBigInt* JSBigInt::createFrom(VM& vm, uint32_t value)
    131 {
     149JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, int32_t value)
     150{
     151    return createFrom(globalObject, globalObject->vm(), value);
     152}
     153
     154JSBigInt* JSBigInt::tryCreateFrom(VM& vm, int32_t value)
     155{
     156    return createFrom(nullptr, vm, value);
     157}
     158
     159JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, uint32_t value)
     160{
     161    VM& vm = globalObject->vm();
     162    auto scope = DECLARE_THROW_SCOPE(vm);
     163
    132164    if (!value)
    133         return createZero(vm);
     165        RELEASE_AND_RETURN(scope, createZero(globalObject));
    134166   
    135     JSBigInt* bigInt = createWithLengthUnchecked(vm, 1);
     167    JSBigInt* bigInt = createWithLength(globalObject, 1);
     168    RETURN_IF_EXCEPTION(scope, nullptr);
    136169    bigInt->setDigit(0, static_cast<Digit>(value));
    137170    return bigInt;
    138171}
    139172
    140 inline JSBigInt* JSBigInt::createFromImpl(VM& vm, uint64_t value, bool sign)
    141 {
     173inline JSBigInt* JSBigInt::createFromImpl(JSGlobalObject* globalObject, uint64_t value, bool sign)
     174{
     175    VM& vm = globalObject->vm();
     176    auto scope = DECLARE_THROW_SCOPE(vm);
     177
    142178    if (!value)
    143         return createZero(vm);
     179        RELEASE_AND_RETURN(scope, createZero(globalObject));
    144180
    145181    // This path is not just an optimization: because we do not call rightTrim at the end of this function,
    146182    // it would be a bug to create a BigInt with length=2 in this case.
    147183    if (sizeof(Digit) == 8 || value <= UINT32_MAX) {
    148         JSBigInt* bigInt = createWithLengthUnchecked(vm, 1);
     184        JSBigInt* bigInt = createWithLength(globalObject, 1);
     185        RETURN_IF_EXCEPTION(scope, nullptr);
    149186        bigInt->setDigit(0, static_cast<Digit>(value));
    150187        bigInt->setSign(sign);
     
    153190
    154191    ASSERT(sizeof(Digit) == 4);
    155     JSBigInt* bigInt = createWithLengthUnchecked(vm, 2);
     192    JSBigInt* bigInt = createWithLength(globalObject, 2);
     193    RETURN_IF_EXCEPTION(scope, nullptr);
    156194    Digit lowBits  = static_cast<Digit>(value & 0xffffffff);
    157195    Digit highBits = static_cast<Digit>((value >> 32) & 0xffffffff);
     
    166204}
    167205
    168 JSBigInt* JSBigInt::createFrom(VM& vm, uint64_t value)
    169 {
    170     return createFromImpl(vm, value, false);
    171 }
    172 
    173 JSBigInt* JSBigInt::createFrom(VM& vm, int64_t value)
     206JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, uint64_t value)
     207{
     208    return createFromImpl(globalObject, value, false);
     209}
     210
     211JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, int64_t value)
    174212{
    175213    uint64_t unsignedValue;
     
    180218    } else
    181219        unsignedValue = value;
    182     return createFromImpl(vm, unsignedValue, sign);
    183 }
    184 
    185 JSBigInt* JSBigInt::createFrom(VM& vm, bool value)
    186 {
     220    return createFromImpl(globalObject, unsignedValue, sign);
     221}
     222
     223JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, bool value)
     224{
     225    VM& vm = globalObject->vm();
     226    auto scope = DECLARE_THROW_SCOPE(vm);
     227
    187228    if (!value)
    188         return createZero(vm);
    189    
    190     JSBigInt* bigInt = createWithLengthUnchecked(vm, 1);
     229        RELEASE_AND_RETURN(scope, createZero(globalObject));
     230
     231    JSBigInt* bigInt = createWithLength(globalObject, 1);
     232    RETURN_IF_EXCEPTION(scope, nullptr);
    191233    bigInt->setDigit(0, static_cast<Digit>(value));
    192234    return bigInt;
    193235}
    194236
    195 JSBigInt* JSBigInt::createFrom(VM& vm, double value)
    196 {
     237JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, double value)
     238{
     239    VM& vm = globalObject->vm();
     240    auto scope = DECLARE_THROW_SCOPE(vm);
     241
    197242    ASSERT(isInteger(value));
    198243    if (!value)
    199         return createZero(vm);
     244        RELEASE_AND_RETURN(scope, createZero(globalObject));
    200245
    201246    bool sign = value < 0; // -0 was already handled above.
     
    206251    int32_t exponent = rawExponent - 0x3ff;
    207252    int32_t digits = exponent / digitBits + 1;
    208     JSBigInt* result = createWithLengthUnchecked(vm, digits);
     253    JSBigInt* result = createWithLength(globalObject, digits);
     254    RETURN_IF_EXCEPTION(scope, nullptr);
    209255    ASSERT(result);
    210256    result->initialize(InitializationType::WithZero);
     
    260306        result->setDigit(digitIndex, digit);
    261307    }
    262     return result->rightTrim(vm);
     308    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
    263309}
    264310
     
    275321}
    276322
    277 JSValue JSBigInt::parseInt(JSGlobalObject* globalObject, VM& vm, StringView s, uint8_t radix, ErrorParseMode parserMode, ParseIntSign sign)
     323JSValue JSBigInt::parseInt(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, StringView s, uint8_t radix, ErrorParseMode parserMode, ParseIntSign sign)
    278324{
    279325    if (s.is8Bit())
    280         return parseInt(globalObject, vm, s.characters8(), s.length(), 0, radix, parserMode, sign, ParseIntMode::DisallowEmptyString);
    281     return parseInt(globalObject, vm, s.characters16(), s.length(), 0, radix, parserMode, sign, ParseIntMode::DisallowEmptyString);
     326        return parseInt(nullOrGlobalObjectForOOM, vm, s.characters8(), s.length(), 0, radix, parserMode, sign, ParseIntMode::DisallowEmptyString);
     327    return parseInt(nullOrGlobalObjectForOOM, vm, s.characters16(), s.length(), 0, radix, parserMode, sign, ParseIntMode::DisallowEmptyString);
    282328}
    283329
     
    319365    ALWAYS_INLINE unsigned length() { return m_bigInt->length(); }
    320366    ALWAYS_INLINE JSBigInt::Digit digit(unsigned i) { return m_bigInt->digit(i); }
    321     ALWAYS_INLINE JSBigInt* toHeapBigInt(VM&) { return m_bigInt; }
     367    ALWAYS_INLINE JSBigInt* toHeapBigInt(JSGlobalObject*, VM&) { return m_bigInt; }
     368    ALWAYS_INLINE JSBigInt* toHeapBigInt(JSGlobalObject*) { return m_bigInt; }
    322369
    323370private:
     
    344391    }
    345392
    346     ALWAYS_INLINE JSBigInt* toHeapBigInt(VM& vm) { return JSBigInt::createFrom(vm, m_value); }
     393    ALWAYS_INLINE JSBigInt* toHeapBigInt(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm)
     394    {
     395        return JSBigInt::createFrom(nullOrGlobalObjectForOOM, vm, m_value);
     396    }
     397
     398    ALWAYS_INLINE JSBigInt* toHeapBigInt(JSGlobalObject* globalObject)
     399    {
     400        return JSBigInt::createFrom(globalObject, m_value);
     401    }
    347402
    348403private:
     
    403458}
    404459
    405 static ALWAYS_INLINE JSBigInt::ImplResult zeroImpl(VM& vm)
     460static ALWAYS_INLINE JSBigInt::ImplResult zeroImpl(JSGlobalObject* globalObject)
    406461{
    407462#if USE(BIGINT32)
    408     UNUSED_PARAM(vm);
     463    UNUSED_PARAM(globalObject);
    409464    return jsBigInt32(0);
    410465#else
    411     return JSBigInt::createZero(vm);
     466    return JSBigInt::createZero(globalObject);
    412467#endif
    413468}
     
    432487    // 2. If base is 0n and exponent is 0n, return 1n.
    433488    if (exponent.isZero())
    434         return JSBigInt::createFrom(vm, 1);
     489        RELEASE_AND_RETURN(scope, JSBigInt::createFrom(globalObject, 1));
    435490   
    436491    // 3. Return a BigInt representing the mathematical value of base raised
     
    442497        // (-1) ** even_number == 1.
    443498        if (base.sign() && !(exponent.digit(0) & 1))
    444             return JSBigInt::unaryMinusImpl(vm, base);
     499            RELEASE_AND_RETURN(scope, JSBigInt::unaryMinusImpl(globalObject, base));
    445500
    446501        // (-1) ** odd_number == -1; 1 ** anything == 1.
     
    469524        // Fast path for 2^n.
    470525        int neededDigits = 1 + (n / digitBits);
    471         JSBigInt* result = JSBigInt::tryCreateWithLength(globalObject, neededDigits);
     526        JSBigInt* result = JSBigInt::createWithLength(globalObject, neededDigits);
    472527        RETURN_IF_EXCEPTION(scope, nullptr);
    473528
     
    484539
    485540    JSBigInt* result = nullptr;
    486     JSBigInt* runningSquare = base.toHeapBigInt(vm);
     541    JSBigInt* runningSquare = base.toHeapBigInt(globalObject);
     542    RETURN_IF_EXCEPTION(scope, nullptr);
    487543
    488544    // This implicitly sets the result's sign correctly.
    489     if (n & 1)
    490         result = base.toHeapBigInt(vm);
     545    if (n & 1) {
     546        result = base.toHeapBigInt(globalObject);
     547        RETURN_IF_EXCEPTION(scope, nullptr);
     548    }
    491549
    492550    n >>= 1;
     
    549607
    550608    unsigned resultLength = x.length() + y.length();
    551     JSBigInt* result = JSBigInt::tryCreateWithLength(globalObject, resultLength);
     609    JSBigInt* result = JSBigInt::createWithLength(globalObject, resultLength);
    552610    RETURN_IF_EXCEPTION(scope, nullptr);
    553611    result->initialize(InitializationType::WithZero);
     
    557615
    558616    result->setSign(x.sign() != y.sign());
    559     return result->rightTrim(vm);
     617    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
    560618}
    561619
     
    591649    //    integral value.
    592650    if (absoluteCompare(x, y) == ComparisonResult::LessThan)
    593         return zeroImpl(vm);
     651        RELEASE_AND_RETURN(scope, zeroImpl(globalObject));
    594652
    595653    JSBigInt* quotient = nullptr;
     
    597655    if (y.length() == 1) {
    598656        Digit divisor = y.digit(0);
    599         if (divisor == 1)
    600             return resultSign == x.sign() ? JSBigInt::ImplResult { x } : JSBigInt::unaryMinusImpl(vm, x);
     657        if (divisor == 1) {
     658            if (resultSign == x.sign())
     659                return JSBigInt::ImplResult { x };
     660            RELEASE_AND_RETURN(scope, JSBigInt::unaryMinusImpl(globalObject, x));
     661        }
    601662
    602663        Digit remainder;
    603         absoluteDivWithDigitDivisor(vm, x, divisor, &quotient, remainder);
     664        absoluteDivWithDigitDivisor(globalObject, vm, x, divisor, &quotient, remainder);
     665        RETURN_IF_EXCEPTION(scope, nullptr);
    604666    } else {
    605         absoluteDivWithBigIntDivisor(globalObject, x, y.toHeapBigInt(vm), &quotient, nullptr);
     667        JSBigInt* yBigInt = y.toHeapBigInt(globalObject);
    606668        RETURN_IF_EXCEPTION(scope, nullptr);
     669        absoluteDivWithBigIntDivisor(globalObject, x, yBigInt, &quotient, nullptr);
     670        RETURN_IF_EXCEPTION(scope, nullptr);
    607671    }
    608672
    609673    quotient->setSign(resultSign);
    610     return quotient->rightTrim(vm);
     674    RELEASE_AND_RETURN(scope, quotient->rightTrim(globalObject));
    611675}
    612676
     
    627691
    628692template <typename BigIntImpl>
    629 JSBigInt* JSBigInt::copy(VM& vm, BigIntImpl x)
    630 {
     693JSBigInt* JSBigInt::copy(JSGlobalObject* globalObject, BigIntImpl x)
     694{
     695    VM& vm = globalObject->vm();
     696    auto scope = DECLARE_THROW_SCOPE(vm);
     697
    631698    ASSERT(!x.isZero());
    632699
    633     JSBigInt* result = JSBigInt::createWithLengthUnchecked(vm, x.length());
     700    JSBigInt* result = createWithLength(globalObject, x.length());
     701    RETURN_IF_EXCEPTION(scope, nullptr);
     702
    634703    for (unsigned i = 0; i < result->length(); ++i)
    635704        result->setDigit(i, x.digit(i));
     
    639708
    640709template <typename BigIntImpl>
    641 JSBigInt::ImplResult JSBigInt::unaryMinusImpl(VM& vm, BigIntImpl x)
    642 {
     710JSBigInt::ImplResult JSBigInt::unaryMinusImpl(JSGlobalObject* globalObject, BigIntImpl x)
     711{
     712    VM& vm = globalObject->vm();
     713    auto scope = DECLARE_THROW_SCOPE(vm);
     714
    643715    if (x.isZero())
    644         return zeroImpl(vm);
    645 
    646     JSBigInt* result = copy(vm, x);
     716        RELEASE_AND_RETURN(scope, zeroImpl(globalObject));
     717
     718    JSBigInt* result = copy(globalObject, x);
     719    RETURN_IF_EXCEPTION(scope, nullptr);
     720
    647721    result->setSign(!x.sign());
    648722    return result;
    649723}
    650724
    651 JSValue JSBigInt::unaryMinus(VM& vm, JSBigInt* x)
    652 {
    653     return tryConvertToBigInt32(unaryMinusImpl(vm, HeapBigIntImpl { x }));
     725JSValue JSBigInt::unaryMinus(JSGlobalObject* globalObject, JSBigInt* x)
     726{
     727    return tryConvertToBigInt32(unaryMinusImpl(globalObject, HeapBigIntImpl { x }));
    654728}
    655729
     
    675749        Digit divisor = y.digit(0);
    676750        if (divisor == 1)
    677             return zeroImpl(vm);
     751            RELEASE_AND_RETURN(scope, zeroImpl(globalObject));
    678752
    679753        Digit remainderDigit;
    680         absoluteDivWithDigitDivisor(vm, x, divisor, nullptr, remainderDigit);
     754        absoluteDivWithDigitDivisor(globalObject, vm, x, divisor, nullptr, remainderDigit);
     755        RETURN_IF_EXCEPTION(scope, nullptr);
     756
    681757        if (!remainderDigit)
    682             return zeroImpl(vm);
    683 
    684         remainder = createWithLengthUnchecked(vm, 1);
     758            RELEASE_AND_RETURN(scope, zeroImpl(globalObject));
     759
     760        remainder = createWithLength(globalObject, 1);
     761        RETURN_IF_EXCEPTION(scope, nullptr);
    685762        remainder->setDigit(0, remainderDigit);
    686763    } else {
    687         absoluteDivWithBigIntDivisor(globalObject, x, y.toHeapBigInt(vm), nullptr, &remainder);
     764        JSBigInt* yBigInt = y.toHeapBigInt(globalObject);
    688765        RETURN_IF_EXCEPTION(scope, nullptr);
     766        absoluteDivWithBigIntDivisor(globalObject, x, yBigInt, nullptr, &remainder);
     767        RETURN_IF_EXCEPTION(scope, nullptr);
    689768    }
    690769
    691770    remainder->setSign(x.sign());
    692     return remainder->rightTrim(vm);
     771    RELEASE_AND_RETURN(scope, remainder->rightTrim(globalObject));
    693772}
    694773JSValue JSBigInt::remainder(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
     
    710789JSBigInt::ImplResult JSBigInt::incImpl(JSGlobalObject* globalObject, BigIntImpl x)
    711790{
     791    VM& vm = globalObject->vm();
     792    auto scope = DECLARE_THROW_SCOPE(vm);
     793
    712794    if (!x.sign())
    713         return absoluteAddOne(globalObject, x, SignOption::Unsigned);
     795        RELEASE_AND_RETURN(scope, absoluteAddOne(globalObject, x, SignOption::Unsigned));
    714796    JSBigInt* result = absoluteSubOne(globalObject, x, x.length());
     797    RETURN_IF_EXCEPTION(scope, nullptr);
    715798    if (result->isZero())
    716799        return result;
     
    731814        return jsBigInt32(-1);
    732815#else
    733         return createFrom(globalObject->vm(), -1);
     816        return createFrom(globalObject, -1);
    734817#endif
    735818    }
     
    747830JSBigInt::ImplResult JSBigInt::addImpl(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y)
    748831{
    749     VM& vm = globalObject->vm();
    750832    bool xSign = x.sign();
    751833
     
    759841    ComparisonResult comparisonResult = absoluteCompare(x, y);
    760842    if (comparisonResult == ComparisonResult::GreaterThan || comparisonResult == ComparisonResult::Equal)
    761         return absoluteSub(vm, x, y, xSign);
    762 
    763     return absoluteSub(vm, y, x, !xSign);
     843        return absoluteSub(globalObject, x, y, xSign);
     844
     845    return absoluteSub(globalObject, y, x, !xSign);
    764846}
    765847JSValue JSBigInt::add(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y)
     
    781863JSBigInt::ImplResult JSBigInt::subImpl(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y)
    782864{
    783     VM& vm = globalObject->vm();
    784865    bool xSign = x.sign();
    785866    if (xSign != y.sign()) {
     
    792873    ComparisonResult comparisonResult = absoluteCompare(x, y);
    793874    if (comparisonResult == ComparisonResult::GreaterThan || comparisonResult == ComparisonResult::Equal)
    794         return absoluteSub(vm, x, y, xSign);
    795 
    796     return absoluteSub(vm, y, x, !xSign);
     875        return absoluteSub(globalObject, x, y, xSign);
     876
     877    return absoluteSub(globalObject, y, x, !xSign);
    797878}
    798879
     
    818899    auto scope = DECLARE_THROW_SCOPE(vm);
    819900
    820     if (!x.sign() && !y.sign()) {
    821         scope.release();
    822         return absoluteAnd(vm, x, y);
    823     }
     901    if (!x.sign() && !y.sign())
     902        RELEASE_AND_RETURN(scope, absoluteAnd(globalObject, x, y));
    824903   
    825904    if (x.sign() && y.sign()) {
     
    832911        JSBigInt* y1 = absoluteSubOne(globalObject, y, y.length());
    833912        RETURN_IF_EXCEPTION(scope, nullptr);
    834         result = absoluteOr(vm, HeapBigIntImpl { result }, HeapBigIntImpl { y1 });
    835         scope.release();
    836         return absoluteAddOne(globalObject, HeapBigIntImpl { result }, SignOption::Signed);
     913        result = absoluteOr(globalObject, HeapBigIntImpl { result }, HeapBigIntImpl { y1 });
     914        RETURN_IF_EXCEPTION(scope, nullptr);
     915        RELEASE_AND_RETURN(scope, absoluteAddOne(globalObject, HeapBigIntImpl { result }, SignOption::Signed));
    837916    }
    838917
     
    844923        JSBigInt* y1 = absoluteSubOne(globalObject, y, y.length());
    845924        RETURN_IF_EXCEPTION(scope, nullptr);
    846         return absoluteAndNot(vm, x, HeapBigIntImpl { y1 });
     925        RELEASE_AND_RETURN(scope, absoluteAndNot(globalObject, x, HeapBigIntImpl { y1 }));
    847926    };
    848927    if (x.sign())
     
    874953    unsigned resultLength = std::max(x.length(), y.length());
    875954
    876     if (!x.sign() && !y.sign()) {
    877         scope.release();
    878         return absoluteOr(vm, x, y);
    879     }
     955    if (!x.sign() && !y.sign())
     956        RELEASE_AND_RETURN(scope, absoluteOr(globalObject, x, y));
    880957   
    881958    if (x.sign() && y.sign()) {
     
    886963        JSBigInt* y1 = absoluteSubOne(globalObject, y, y.length());
    887964        RETURN_IF_EXCEPTION(scope, nullptr);
    888         result = absoluteAnd(vm, HeapBigIntImpl { result }, HeapBigIntImpl { y1 });
     965        result = absoluteAnd(globalObject, HeapBigIntImpl { result }, HeapBigIntImpl { y1 });
    889966        RETURN_IF_EXCEPTION(scope, nullptr);
    890 
    891         scope.release();
    892         return absoluteAddOne(globalObject, HeapBigIntImpl { result }, SignOption::Signed);
     967        RELEASE_AND_RETURN(scope, absoluteAddOne(globalObject, HeapBigIntImpl { result }, SignOption::Signed));
    893968    }
    894969   
     
    902977        JSBigInt* result = absoluteSubOne(globalObject, y, resultLength);
    903978        RETURN_IF_EXCEPTION(scope, nullptr);
    904         result = absoluteAndNot(vm, HeapBigIntImpl { result }, x);
    905 
    906         scope.release();
    907         return absoluteAddOne(globalObject, HeapBigIntImpl { result }, SignOption::Signed);
     979        result = absoluteAndNot(globalObject, HeapBigIntImpl { result }, x);
     980        RETURN_IF_EXCEPTION(scope, nullptr);
     981        RELEASE_AND_RETURN(scope, absoluteAddOne(globalObject, HeapBigIntImpl { result }, SignOption::Signed));
    908982    };
    909983
     
    9341008    auto scope = DECLARE_THROW_SCOPE(vm);
    9351009
    936     if (!x.sign() && !y.sign()) {
    937         scope.release();
    938         return absoluteXor(vm, x, y);
    939     }
     1010    if (!x.sign() && !y.sign())
     1011        RELEASE_AND_RETURN(scope, absoluteXor(globalObject, x, y));
    9401012   
    9411013    if (x.sign() && y.sign()) {
     
    9471019        JSBigInt* y1 = absoluteSubOne(globalObject, y, y.length());
    9481020        RETURN_IF_EXCEPTION(scope, nullptr);
    949 
    950         scope.release();
    951         return absoluteXor(vm, HeapBigIntImpl { result }, HeapBigIntImpl { y1 });
     1021        RELEASE_AND_RETURN(scope, absoluteXor(globalObject, HeapBigIntImpl { result }, HeapBigIntImpl { y1 }));
    9521022    }
    9531023    ASSERT(x.sign() != y.sign());
     
    9611031        RETURN_IF_EXCEPTION(scope, nullptr);
    9621032
    963         result = absoluteXor(vm, HeapBigIntImpl { result }, x);
    964         scope.release();
    965         return absoluteAddOne(globalObject, HeapBigIntImpl { result }, SignOption::Signed);
     1033        result = absoluteXor(globalObject, HeapBigIntImpl { result }, x);
     1034        RETURN_IF_EXCEPTION(scope, nullptr);
     1035        RELEASE_AND_RETURN(scope, absoluteAddOne(globalObject, HeapBigIntImpl { result }, SignOption::Signed));
    9661036    };
    9671037   
     
    13751445{
    13761446    VM& vm = globalObject->vm();
     1447    auto scope = DECLARE_THROW_SCOPE(vm);
    13771448
    13781449    if (x.length() < y.length())
    1379         return absoluteAdd(globalObject, y, x, resultSign);
     1450        RELEASE_AND_RETURN(scope, absoluteAdd(globalObject, y, x, resultSign));
    13801451
    13811452    if (x.isZero()) {
     
    13841455    }
    13851456
    1386     if (y.isZero())
    1387         return resultSign == x.sign() ? x : unaryMinusImpl(vm, x);
    1388 
    1389     JSBigInt* result = JSBigInt::tryCreateWithLength(globalObject, x.length() + 1);
    1390     if (!result)
    1391         return nullptr;
     1457    if (y.isZero()) {
     1458        if (resultSign == x.sign())
     1459            return x;
     1460        RELEASE_AND_RETURN(scope, unaryMinusImpl(globalObject, x));
     1461    }
     1462
     1463    JSBigInt* result = createWithLength(globalObject, x.length() + 1);
     1464    RETURN_IF_EXCEPTION(scope, nullptr);
     1465    ASSERT(result);
    13921466    Digit carry = 0;
    13931467    unsigned i = 0;
     
    14101484    result->setSign(resultSign);
    14111485
    1412     return result->rightTrim(vm);
     1486    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
    14131487}
    14141488
    14151489template <typename BigIntImpl1, typename BigIntImpl2>
    1416 JSBigInt::ImplResult JSBigInt::absoluteSub(VM& vm, BigIntImpl1 x, BigIntImpl2 y, bool resultSign)
    1417 {
     1490JSBigInt::ImplResult JSBigInt::absoluteSub(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y, bool resultSign)
     1491{
     1492    VM& vm = globalObject->vm();
     1493    auto scope = DECLARE_THROW_SCOPE(vm);
     1494
    14181495    ComparisonResult comparisonResult = absoluteCompare(x, y);
    14191496    ASSERT(x.length() >= y.length());
     
    14251502    }
    14261503
    1427     if (y.isZero())
    1428         return resultSign == x.sign() ? ImplResult { x } : JSBigInt::unaryMinusImpl(vm, x);
     1504    if (y.isZero()) {
     1505        if (resultSign == x.sign())
     1506            return ImplResult { x };
     1507        RELEASE_AND_RETURN(scope, JSBigInt::unaryMinusImpl(globalObject, x));
     1508    }
    14291509
    14301510    if (comparisonResult == ComparisonResult::Equal)
    1431         return zeroImpl(vm);
    1432 
    1433     JSBigInt* result = JSBigInt::createWithLengthUnchecked(vm, x.length());
     1511        RELEASE_AND_RETURN(scope, zeroImpl(globalObject));
     1512
     1513    JSBigInt* result = createWithLength(globalObject, x.length());
     1514    RETURN_IF_EXCEPTION(scope, nullptr);
    14341515
    14351516    Digit borrow = 0;
     
    14521533    ASSERT(!borrow);
    14531534    result->setSign(resultSign);
    1454     return result->rightTrim(vm);
     1535    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
    14551536}
    14561537
     
    14631544// also be nullptr if the caller is only interested in the remainder.
    14641545template <typename BigIntImpl>
    1465 void JSBigInt::absoluteDivWithDigitDivisor(VM& vm, BigIntImpl x, Digit divisor, JSBigInt** quotient, Digit& remainder)
     1546bool JSBigInt::absoluteDivWithDigitDivisor(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, BigIntImpl x, Digit divisor, JSBigInt** quotient, Digit& remainder)
    14661547{
    14671548    ASSERT(divisor);
     
    14701551    remainder = 0;
    14711552    if (divisor == 1) {
    1472         if (quotient)
    1473             *quotient = x.toHeapBigInt(vm);
    1474         return;
     1553        if (quotient) {
     1554            JSBigInt* result = x.toHeapBigInt(nullOrGlobalObjectForOOM, vm);
     1555            if (UNLIKELY(!result))
     1556                return false;
     1557            *quotient = result;
     1558        }
     1559        return true;
    14751560    }
    14761561
    14771562    unsigned length = x.length();
    14781563    if (quotient) {
    1479         if (*quotient == nullptr)
    1480             *quotient = JSBigInt::createWithLengthUnchecked(vm, length);
     1564        if (*quotient == nullptr) {
     1565            JSBigInt* result = createWithLength(nullOrGlobalObjectForOOM, vm, length);
     1566            if (UNLIKELY(!result))
     1567                return false;
     1568            *quotient = result;
     1569        }
    14811570
    14821571        for (int i = length - 1; i >= 0; i--) {
     
    14881577            digitDiv(remainder, x.digit(i), divisor, remainder);
    14891578    }
     1579    return true;
    14901580}
    14911581
     
    15131603    // The quotient to be computed.
    15141604    JSBigInt* q = nullptr;
    1515     if (quotient != nullptr)
    1516         q = createWithLengthUnchecked(globalObject->vm(), m + 1);
     1605    if (quotient != nullptr) {
     1606        q = createWithLength(globalObject, m + 1);
     1607        RETURN_IF_EXCEPTION(scope, void());
     1608    }
    15171609   
    15181610    // In each iteration, {qhatv} holds {divisor} * {current quotient digit}.
    15191611    // "v" is the book's name for {divisor}, "qhat" the current quotient digit.
    1520     JSBigInt* qhatv = tryCreateWithLength(globalObject, n + 1);
     1612    JSBigInt* qhatv = createWithLength(globalObject, n + 1);
    15211613    RETURN_IF_EXCEPTION(scope, void());
    15221614   
     
    16681760JSBigInt* JSBigInt::absoluteLeftShiftAlwaysCopy(JSGlobalObject* globalObject, BigIntImpl x, unsigned shift, LeftShiftMode mode)
    16691761{
     1762    VM& vm = globalObject->vm();
     1763    auto scope = DECLARE_THROW_SCOPE(vm);
     1764
    16701765    ASSERT(shift < digitBits);
    16711766    ASSERT(!x.isZero());
     
    16731768    unsigned n = x.length();
    16741769    unsigned resultLength = mode == LeftShiftMode::AlwaysAddOneDigit ? n + 1 : n;
    1675     JSBigInt* result = tryCreateWithLength(globalObject, resultLength);
    1676     if (!result)
    1677         return nullptr;
     1770    JSBigInt* result = createWithLength(globalObject, resultLength);
     1771    RETURN_IF_EXCEPTION(scope, { });
    16781772
    16791773    if (!shift) {
     
    17171811// result: [  0 ][ x3 ][ r2 ][ r1 ][ r0 ]
    17181812template <typename BigIntImpl1, typename BigIntImpl2, typename BitwiseOp>
    1719 inline JSBigInt* JSBigInt::absoluteBitwiseOp(VM& vm, BigIntImpl1 x, BigIntImpl2 y, ExtraDigitsHandling extraDigits, BitwiseOp&& op)
    1720 {
     1813inline JSBigInt* JSBigInt::absoluteBitwiseOp(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y, ExtraDigitsHandling extraDigits, BitwiseOp&& op)
     1814{
     1815    VM& vm = globalObject->vm();
     1816    auto scope = DECLARE_THROW_SCOPE(vm);
     1817
    17211818    unsigned xLength = x.length();
    17221819    unsigned yLength = y.length();
     
    17311828    ASSERT(maxLength == std::max(xLength, yLength));
    17321829    unsigned resultLength = extraDigits == ExtraDigitsHandling::Copy ? maxLength : numPairs;
    1733     JSBigInt* result = createWithLengthUnchecked(vm, resultLength);
     1830    JSBigInt* result = createWithLength(globalObject, resultLength);
     1831    RETURN_IF_EXCEPTION(scope, nullptr);
    17341832    unsigned i = 0;
    17351833    for (; i < numPairs; i++)
     
    17491847        result->setDigit(i, 0);
    17501848
    1751     return result->rightTrim(vm);
     1849    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
    17521850}
    17531851
    17541852template <typename BigIntImpl1, typename BigIntImpl2>
    1755 JSBigInt* JSBigInt::absoluteAnd(VM& vm, BigIntImpl1 x, BigIntImpl2 y)
     1853JSBigInt* JSBigInt::absoluteAnd(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y)
    17561854{
    17571855    auto digitOperation = [](Digit a, Digit b) {
    17581856        return a & b;
    17591857    };
    1760     return absoluteBitwiseOp(vm, x, y, ExtraDigitsHandling::Skip, digitOperation);
     1858    return absoluteBitwiseOp(globalObject, x, y, ExtraDigitsHandling::Skip, digitOperation);
    17611859}
    17621860
    17631861template <typename BigIntImpl1, typename BigIntImpl2>
    1764 JSBigInt* JSBigInt::absoluteOr(VM& vm, BigIntImpl1 x, BigIntImpl2 y)
     1862JSBigInt* JSBigInt::absoluteOr(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y)
    17651863{
    17661864    auto digitOperation = [](Digit a, Digit b) {
    17671865        return a | b;
    17681866    };
    1769     return absoluteBitwiseOp(vm, x, y, ExtraDigitsHandling::Copy, digitOperation);
     1867    return absoluteBitwiseOp(globalObject, x, y, ExtraDigitsHandling::Copy, digitOperation);
    17701868}
    17711869
    17721870template <typename BigIntImpl1, typename BigIntImpl2>
    1773 JSBigInt* JSBigInt::absoluteAndNot(VM& vm, BigIntImpl1 x, BigIntImpl2 y)
     1871JSBigInt* JSBigInt::absoluteAndNot(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y)
    17741872{
    17751873    // x & ~y
     1874
     1875    VM& vm = globalObject->vm();
     1876    auto scope = DECLARE_THROW_SCOPE(vm);
    17761877
    17771878    unsigned xLength = x.length();
     
    17791880    unsigned resultLength = xLength;
    17801881
    1781     JSBigInt* result = createWithLengthUnchecked(vm, resultLength);
     1882    JSBigInt* result = createWithLength(globalObject, resultLength);
     1883    RETURN_IF_EXCEPTION(scope, nullptr);
    17821884    unsigned i = 0;
    17831885    for (; i < std::min(xLength, yLength); i++)
     
    17861888        result->setDigit(i, x.digit(i));
    17871889
    1788     return result->rightTrim(vm);
     1890    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
    17891891}
    17901892
    17911893template <typename BigIntImpl1, typename BigIntImpl2>
    1792 JSBigInt* JSBigInt::absoluteXor(VM& vm, BigIntImpl1 x, BigIntImpl2 y)
     1894JSBigInt* JSBigInt::absoluteXor(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y)
    17931895{
    17941896    auto digitOperation = [](Digit a, Digit b) {
    17951897        return a ^ b;
    17961898    };
    1797     return absoluteBitwiseOp(vm, x, y, ExtraDigitsHandling::Copy, digitOperation);
     1899    return absoluteBitwiseOp(globalObject, x, y, ExtraDigitsHandling::Copy, digitOperation);
    17981900}
    17991901   
     
    18011903JSBigInt* JSBigInt::absoluteAddOne(JSGlobalObject* globalObject, BigIntImpl x, SignOption signOption)
    18021904{
     1905    VM& vm = globalObject->vm();
     1906    auto scope = DECLARE_THROW_SCOPE(vm);
     1907
    18031908    unsigned inputLength = x.length();
    18041909    // The addition will overflow into a new digit if all existing digits are
     
    18131918
    18141919    unsigned resultLength = inputLength + willOverflow;
    1815     JSBigInt* result = tryCreateWithLength(globalObject, resultLength);
    1816     if (!result)
    1817         return nullptr;
     1920    JSBigInt* result = createWithLength(globalObject, resultLength);
     1921    RETURN_IF_EXCEPTION(scope, nullptr);
    18181922
    18191923    Digit carry = 1;
     
    18291933
    18301934    result->setSign(signOption == SignOption::Signed);
    1831     return result->rightTrim(globalObject->vm());
     1935    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
    18321936}
    18331937
     
    18401944    auto scope = DECLARE_THROW_SCOPE(vm);
    18411945
    1842     JSBigInt* result = tryCreateWithLength(globalObject, resultLength);
     1946    JSBigInt* result = createWithLength(globalObject, resultLength);
    18431947    RETURN_IF_EXCEPTION(scope, nullptr);
    18441948
     
    18541958        result->setDigit(i, borrow);
    18551959
    1856     return result->rightTrim(vm);
     1960    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
    18571961}
    18581962
     
    18801984    }
    18811985
    1882     JSBigInt* result = tryCreateWithLength(globalObject, resultLength);
     1986    JSBigInt* result = createWithLength(globalObject, resultLength);
    18831987    RETURN_IF_EXCEPTION(scope, nullptr);
    18841988    if (!bitsShift) {
     
    19072011
    19082012    result->setSign(x.sign());
    1909     return result->rightTrim(vm);
     2013    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
    19102014}
    19112015
     
    19142018{
    19152019    VM& vm = globalObject->vm();
     2020    auto scope = DECLARE_THROW_SCOPE(vm);
     2021
    19162022    unsigned length = x.length();
    19172023    bool sign = x.sign();
    19182024    auto optionalShift = toShiftAmount(y);
    19192025    if (!optionalShift)
    1920         return rightShiftByMaximum(vm, sign);
     2026        RELEASE_AND_RETURN(scope, rightShiftByMaximum(globalObject, sign));
    19212027
    19222028    Digit shift = *optionalShift;
     
    19252031    int resultLength = length - digitalShift;
    19262032    if (resultLength <= 0)
    1927         return rightShiftByMaximum(vm, sign);
     2033        RELEASE_AND_RETURN(scope, rightShiftByMaximum(globalObject, sign));
    19282034
    19292035    // For negative numbers, round down if any bit was shifted out (so that e.g.
     
    19562062
    19572063    ASSERT(static_cast<unsigned>(resultLength) <= length);
    1958     JSBigInt* result = createWithLengthUnchecked(vm, static_cast<unsigned>(resultLength));
     2064    JSBigInt* result = createWithLength(globalObject, static_cast<unsigned>(resultLength));
     2065    RETURN_IF_EXCEPTION(scope, nullptr);
     2066
    19592067    if (!bitsShift) {
    19602068        for (unsigned i = digitalShift; i < length; i++)
     
    19762084            // Since the result is negative, rounding down means adding one to
    19772085            // its absolute value. This cannot overflow.
    1978             result = result->rightTrim(vm);
    1979             return absoluteAddOne(globalObject, HeapBigIntImpl { result }, SignOption::Signed);
     2086            result = result->rightTrim(globalObject);
     2087            RETURN_IF_EXCEPTION(scope, nullptr);
     2088            RELEASE_AND_RETURN(scope, absoluteAddOne(globalObject, HeapBigIntImpl { result }, SignOption::Signed));
    19802089        }
    19812090    }
    19822091
    1983     return result->rightTrim(vm);
    1984 }
    1985 
    1986 JSBigInt::ImplResult JSBigInt::rightShiftByMaximum(VM& vm, bool sign)
     2092    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
     2093}
     2094
     2095JSBigInt::ImplResult JSBigInt::rightShiftByMaximum(JSGlobalObject* globalObject, bool sign)
    19872096{
    19882097    if (sign)
    1989         return createFrom(vm, -1);
    1990 
    1991     return createZero(vm);
     2098        return createFrom(globalObject, -1);
     2099
     2100    return createZero(globalObject);
    19922101}
    19932102
     
    20352144}
    20362145
    2037 String JSBigInt::toStringBasePowerOfTwo(VM& vm, JSGlobalObject* globalObject, JSBigInt* x, unsigned radix)
     2146String JSBigInt::toStringBasePowerOfTwo(VM& vm, JSGlobalObject* nullOrGlobalObjectForOOM, JSBigInt* x, unsigned radix)
    20382147{
    20392148    ASSERT(hasOneBitSet(radix));
     
    20552164
    20562165    if (charsRequired > JSString::MaxLength) {
    2057         if (globalObject) {
     2166        if (nullOrGlobalObjectForOOM) {
    20582167            auto scope = DECLARE_THROW_SCOPE(vm);
    2059             throwOutOfMemoryError(globalObject, scope);           
     2168            throwOutOfMemoryError(nullOrGlobalObjectForOOM, scope);
    20602169        }
    20612170        return String();
     
    20972206}
    20982207
    2099 String JSBigInt::toStringGeneric(VM& vm, JSGlobalObject* globalObject, JSBigInt* x, unsigned radix)
     2208String JSBigInt::toStringGeneric(VM& vm, JSGlobalObject* nullOrGlobalObjectForOOM, JSBigInt* x, unsigned radix)
    21002209{
    21012210    // FIXME: [JSC] Revisit usage of Vector into JSBigInt::toString
     
    21132222
    21142223    if (maximumCharactersRequired > JSString::MaxLength) {
    2115         if (globalObject) {
     2224        if (nullOrGlobalObjectForOOM) {
    21162225            auto scope = DECLARE_THROW_SCOPE(vm);
    2117             throwOutOfMemoryError(globalObject, scope);           
     2226            throwOutOfMemoryError(nullOrGlobalObjectForOOM, scope);
    21182227        }
    21192228        return String();
     
    21412250        do {
    21422251            Digit chunk;
    2143             absoluteDivWithDigitDivisor(vm, HeapBigIntImpl { *dividend }, chunkDivisor, &rest, chunk);
     2252            bool success = absoluteDivWithDigitDivisor(nullOrGlobalObjectForOOM, vm, HeapBigIntImpl { *dividend }, chunkDivisor, &rest, chunk);
     2253            if (!success)
     2254                return String();
    21442255            dividend = &rest;
    21452256            for (unsigned i = 0; i < chunkChars; i++) {
     
    21822293}
    21832294
    2184 JSBigInt* JSBigInt::rightTrim(VM& vm)
     2295JSBigInt* JSBigInt::rightTrim(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm)
    21852296{
    21862297    if (isZero()) {
     
    21942305
    21952306    if (nonZeroIndex < 0)
    2196         return createZero(vm);
     2307        return createZero(nullOrGlobalObjectForOOM, vm);
    21972308
    21982309    if (nonZeroIndex == static_cast<int>(m_length - 1))
     
    22002311
    22012312    unsigned newLength = nonZeroIndex + 1;
    2202     JSBigInt* trimmedBigInt = createWithLengthUnchecked(vm, newLength);
    2203     std::copy(dataStorage(), dataStorage() + newLength, trimmedBigInt->dataStorage());
     2313    JSBigInt* trimmedBigInt = createWithLength(nullOrGlobalObjectForOOM, vm, newLength);
     2314    if (UNLIKELY(!trimmedBigInt))
     2315        return nullptr;
     2316    std::copy(dataStorage(), dataStorage() + newLength, trimmedBigInt->dataStorage());
    22042317
    22052318    trimmedBigInt->setSign(this->sign());
     
    22082321}
    22092322
    2210 JSBigInt* JSBigInt::allocateFor(JSGlobalObject* globalObject, VM& vm, unsigned radix, unsigned charcount)
    2211 {
     2323JSBigInt* JSBigInt::rightTrim(JSGlobalObject* globalObject)
     2324{
     2325    return rightTrim(globalObject, globalObject->vm());
     2326}
     2327
     2328JSBigInt* JSBigInt::tryRightTrim(VM& vm)
     2329{
     2330    return rightTrim(nullptr, vm);
     2331}
     2332
     2333JSBigInt* JSBigInt::allocateFor(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, unsigned radix, unsigned charcount)
     2334{
     2335    auto scope = DECLARE_THROW_SCOPE(vm);
     2336
    22122337    ASSERT(2 <= radix && radix <= 36);
    22132338
     
    22232348            // Divide by kDigitsBits, rounding up.
    22242349            unsigned length = (bitsMin + digitBits - 1) / digitBits;
    2225             if (length <= maxLength) {
    2226                 JSBigInt* result = JSBigInt::createWithLengthUnchecked(vm, length);
    2227                 return result;
    2228             }
     2350            if (length <= maxLength)
     2351                RELEASE_AND_RETURN(scope, createWithLength(nullOrGlobalObjectForOOM, vm, length));
    22292352        }
    22302353    }
    22312354
    2232     if (globalObject) {
    2233         auto scope = DECLARE_THROW_SCOPE(vm);
    2234         throwOutOfMemoryError(globalObject, scope, "BigInt generated from this operation is too big"_s);
    2235     }
     2355    if (nullOrGlobalObjectForOOM)
     2356        throwOutOfMemoryError(nullOrGlobalObjectForOOM, scope, "BigInt generated from this operation is too big"_s);
     2357
    22362358    return nullptr;
    22372359}
     
    22912413
    22922414template <typename CharType>
    2293 JSValue JSBigInt::parseInt(JSGlobalObject* globalObject, VM& vm, CharType* data, unsigned length, unsigned startIndex, unsigned radix, ErrorParseMode errorParseMode, ParseIntSign sign, ParseIntMode parseMode)
     2415JSValue JSBigInt::parseInt(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, CharType* data, unsigned length, unsigned startIndex, unsigned radix, ErrorParseMode errorParseMode, ParseIntSign sign, ParseIntMode parseMode)
    22942416{
    22952417    ASSERT(length >= 0);
    22962418    unsigned p = startIndex;
    22972419
    2298     auto scope = DECLARE_THROW_SCOPE(vm);
    2299 
    23002420    if (parseMode != ParseIntMode::AllowEmptyString && startIndex == length) {
    2301         ASSERT(globalObject);
    2302         if (errorParseMode == ErrorParseMode::ThrowExceptions)
    2303             throwVMError(globalObject, scope, createSyntaxError(globalObject, "Failed to parse String to BigInt"));
     2421        ASSERT(nullOrGlobalObjectForOOM);
     2422        if (errorParseMode == ErrorParseMode::ThrowExceptions) {
     2423            auto scope = DECLARE_THROW_SCOPE(vm);
     2424            throwVMError(nullOrGlobalObjectForOOM, scope, createSyntaxError(nullOrGlobalObjectForOOM, "Failed to parse String to BigInt"));
     2425        }
    23042426        return JSValue();
    23052427    }
     
    23202442        return jsBigInt32(0);
    23212443#else
    2322         return createZero(vm);
     2444        return createZero(nullOrGlobalObjectForOOM, vm);
    23232445#endif
    23242446    }
     
    24152537            else {
    24162538                if (errorParseMode == ErrorParseMode::ThrowExceptions) {
    2417                     ASSERT(globalObject);
    2418                     throwVMError(globalObject, scope, createSyntaxError(globalObject, "Failed to parse String to BigInt"));
     2539                    auto scope = DECLARE_THROW_SCOPE(vm);
     2540                    ASSERT(nullOrGlobalObjectForOOM);
     2541                    throwVMError(nullOrGlobalObjectForOOM, scope, createSyntaxError(nullOrGlobalObjectForOOM, "Failed to parse String to BigInt"));
    24192542                }
    24202543                return JSValue();
     
    24342557                    return jsBigInt32(static_cast<int32_t>(maybeResult));
    24352558#else
    2436                     return JSBigInt::createFrom(vm, static_cast<int32_t>(maybeResult));
     2559                    return JSBigInt::createFrom(nullOrGlobalObjectForOOM, vm, static_cast<int32_t>(maybeResult));
    24372560#endif
    24382561                }
    24392562            }
    2440             heapResult = allocateFor(globalObject, vm, radix, initialLength);
    2441             RETURN_IF_EXCEPTION(scope, JSValue());
    2442             // result can still be null if we don't have access to global object, as allocateFor cannot throw an exception in that case.
     2563            heapResult = allocateFor(nullOrGlobalObjectForOOM, vm, radix, initialLength);
    24432564            if (!heapResult)
    24442565                return JSValue();
     
    24522573
    24532574    heapResult->setSign(sign == ParseIntSign::Signed);
    2454     return heapResult->rightTrim(vm);
     2575    return heapResult->rightTrim(nullOrGlobalObjectForOOM, vm);
    24552576}
    24562577
     
    27392860{
    27402861    VM& vm = globalObject->vm();
     2862    auto scope = DECLARE_THROW_SCOPE(vm);
    27412863
    27422864    if (bigInt.isZero())
    27432865        return bigInt;
    27442866    if (n == 0)
    2745         return zeroImpl(vm);
     2867        RELEASE_AND_RETURN(scope, zeroImpl(globalObject));
    27462868
    27472869    uint64_t neededLength = (n + digitBits - 1) / digitBits;
     
    27672889    int32_t N = static_cast<int32_t>(n);
    27682890    if (!hasBit)
    2769         return truncateToNBits(vm, N, bigInt);
     2891        RELEASE_AND_RETURN(scope, truncateToNBits(globalObject, N, bigInt));
    27702892    if (!bigInt.sign())
    2771         return truncateAndSubFromPowerOfTwo(vm, N, bigInt, true);
     2893        RELEASE_AND_RETURN(scope, truncateAndSubFromPowerOfTwo(globalObject, N, bigInt, true));
    27722894
    27732895    // Negative numbers must subtract from 2^n, except for the special case
     
    27762898        for (int32_t i = static_cast<int32_t>(neededLength) - 2; i >= 0; i--) {
    27772899            if (bigInt.digit(i) != 0)
    2778                 return truncateAndSubFromPowerOfTwo(vm, N, bigInt, false);
     2900                RELEASE_AND_RETURN(scope, truncateAndSubFromPowerOfTwo(globalObject, N, bigInt, false));
    27792901        }
    27802902        // Truncation is no-op if bigInt == -2^(n-1).
    27812903        if (length == neededLength && topDigit == compareDigit)
    27822904            return bigInt;
    2783         return truncateToNBits(vm, N, bigInt);
    2784     }
    2785     return truncateAndSubFromPowerOfTwo(vm, N, bigInt, false);
     2905        RELEASE_AND_RETURN(scope, truncateToNBits(globalObject, N, bigInt));
     2906    }
     2907    RELEASE_AND_RETURN(scope, truncateAndSubFromPowerOfTwo(globalObject, N, bigInt, false));
    27862908}
    27872909
     
    27952917        return bigInt;
    27962918    if (n == 0)
    2797         return zeroImpl(vm);
     2919        RELEASE_AND_RETURN(scope, zeroImpl(globalObject));
    27982920
    27992921    // If bigInt is negative, simulate two's complement representation.
     
    28032925            return nullptr;
    28042926        }
    2805         return truncateAndSubFromPowerOfTwo(vm, static_cast<int32_t>(n), bigInt, false);
     2927        RELEASE_AND_RETURN(scope, truncateAndSubFromPowerOfTwo(globalObject, static_cast<int32_t>(n), bigInt, false));
    28062928    }
    28072929
     
    28252947    // Otherwise, truncate.
    28262948    ASSERT(n <= INT32_MAX);
    2827     return truncateToNBits(vm, static_cast<int32_t>(n), bigInt);
     2949    RELEASE_AND_RETURN(scope, truncateToNBits(globalObject, static_cast<int32_t>(n), bigInt));
    28282950}
    28292951
    28302952template <typename BigIntImpl>
    2831 JSBigInt::ImplResult JSBigInt::truncateToNBits(VM& vm, int32_t n, BigIntImpl bigInt)
    2832 {
     2953JSBigInt::ImplResult JSBigInt::truncateToNBits(JSGlobalObject* globalObject, int32_t n, BigIntImpl bigInt)
     2954{
     2955    VM& vm = globalObject->vm();
     2956    auto scope = DECLARE_THROW_SCOPE(vm);
     2957
    28332958    ASSERT(n != 0);
    28342959    ASSERT(bigInt.length() > n / digitBits);
     
    28362961    int32_t neededDigits = (n + (digitBits - 1)) / digitBits;
    28372962    ASSERT(neededDigits <= static_cast<int32_t>(bigInt.length()));
    2838     JSBigInt* result = createWithLengthUnchecked(vm, neededDigits);
     2963    JSBigInt* result = createWithLength(globalObject, neededDigits);
     2964    RETURN_IF_EXCEPTION(scope, nullptr);
    28392965    ASSERT(result);
    28402966
     
    28522978    result->setDigit(last, msd);
    28532979    result->setSign(bigInt.sign());
    2854     return result->rightTrim(vm);
     2980    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
    28552981}
    28562982
    28572983// Subtracts the least significant n bits of abs(bigInt) from 2^n.
    28582984template <typename BigIntImpl>
    2859 JSBigInt::ImplResult JSBigInt::truncateAndSubFromPowerOfTwo(VM& vm, int32_t n, BigIntImpl bigInt, bool resultSign)
    2860 {
     2985JSBigInt::ImplResult JSBigInt::truncateAndSubFromPowerOfTwo(JSGlobalObject* globalObject, int32_t n, BigIntImpl bigInt, bool resultSign)
     2986{
     2987    VM& vm = globalObject->vm();
     2988    auto scope = DECLARE_THROW_SCOPE(vm);
     2989
    28612990    ASSERT(n != 0);
    28622991    ASSERT(n <= static_cast<int32_t>(maxLengthBits));
     
    28642993    int32_t neededDigits = (n + (digitBits - 1)) / digitBits;
    28652994    ASSERT(neededDigits <= static_cast<int32_t>(maxLength)); // Follows from n <= maxLengthBits.
    2866     JSBigInt* result = createWithLengthUnchecked(vm, neededDigits);
     2995    JSBigInt* result = createWithLength(globalObject, neededDigits);
     2996    RETURN_IF_EXCEPTION(scope, nullptr);
    28672997    ASSERT(result);
    28682998
     
    29113041    result->setDigit(last, resultMSD);
    29123042    result->setSign(resultSign);
    2913     return result->rightTrim(vm);
     3043    RELEASE_AND_RETURN(scope, result->rightTrim(globalObject));
    29143044}
    29153045
Note: See TracChangeset for help on using the changeset viewer.