Unreviewed, rolling out r238132.
authorryanhaddad@apple.com <ryanhaddad@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Nov 2018 01:47:29 +0000 (01:47 +0000)
committerryanhaddad@apple.com <ryanhaddad@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Nov 2018 01:47:29 +0000 (01:47 +0000)
The test added with this change is timing out on Debug JSC
bots.

Reverted changeset:

"[BigInt] JSBigInt::createWithLength should throw when length
is greater than JSBigInt::maxLength"
https://bugs.webkit.org/show_bug.cgi?id=190836
https://trac.webkit.org/changeset/238132

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238156 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChangeLog
JSTests/stress/big-int-out-of-memory-tests.js [deleted file]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/JSBigInt.cpp
Source/JavaScriptCore/runtime/JSBigInt.h
Source/JavaScriptCore/runtime/Operations.cpp
Source/JavaScriptCore/runtime/Operations.h

index 15890b2..b80b87d 100644 (file)
@@ -1,3 +1,17 @@
+2018-11-13  Ryan Haddad  <ryanhaddad@apple.com>
+
+        Unreviewed, rolling out r238132.
+
+        The test added with this change is timing out on Debug JSC
+        bots.
+
+        Reverted changeset:
+
+        "[BigInt] JSBigInt::createWithLength should throw when length
+        is greater than JSBigInt::maxLength"
+        https://bugs.webkit.org/show_bug.cgi?id=190836
+        https://trac.webkit.org/changeset/238132
+
 2018-11-13  Mark Lam  <mark.lam@apple.com>
 
         Add OOM detection to StringPrototype's substituteBackreferences().
diff --git a/JSTests/stress/big-int-out-of-memory-tests.js b/JSTests/stress/big-int-out-of-memory-tests.js
deleted file mode 100644 (file)
index ac39387..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-//@ runDefault("--useBigInt=true", "--useDFGJIT=false")
-
-function assert(a, message) {
-    if (!a)
-        throw new Error(message);
-}
-
-function lshift(y) {
-    let out = 1n;
-    for (let i = 0; i < y; i++) {
-        out *= 2n;
-    }
-
-    return out;
-}
-
-let a = lshift(16384 * 63);
-for (let i = 0; i < 256; i++) {
-    a *= 18446744073709551615n;
-}
-
-try {
-    let b = a + 1n;
-    assert(false, "Should throw OutOfMemoryError, but executed without exception");
-} catch(e) {
-    assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
-}
-
-try {
-    let b = a - (-1n);
-    assert(false, "Should throw OutOfMemoryError, but executed without exception");
-} catch(e) {
-    assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
-}
-
-try {
-    let b = a * (-1n);
-    assert(false, "Should throw OutOfMemoryError, but executed without exception");
-} catch(e) {
-    assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
-}
-
-try {
-    let b = a / a;
-    assert(false, "Should throw OutOfMemoryError, but executed without exception");
-} catch(e) {
-    assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
-}
-
-try {
-    let b = -a & -1n;
-    assert(false, "Should throw OutOfMemoryError, but executed without exception");
-} catch(e) {
-    assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
-}
-
-try {
-    let b = a ^ -1n;
-    assert(false, "Should throw OutOfMemoryError, but executed without exception");
-} catch(e) {
-    assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
-}
-
index 20698fd..ffbb099 100644 (file)
@@ -1,3 +1,17 @@
+2018-11-13  Ryan Haddad  <ryanhaddad@apple.com>
+
+        Unreviewed, rolling out r238132.
+
+        The test added with this change is timing out on Debug JSC
+        bots.
+
+        Reverted changeset:
+
+        "[BigInt] JSBigInt::createWithLength should throw when length
+        is greater than JSBigInt::maxLength"
+        https://bugs.webkit.org/show_bug.cgi?id=190836
+        https://trac.webkit.org/changeset/238132
+
 2018-11-12  Mark Lam  <mark.lam@apple.com>
 
         Add OOM detection to StringPrototype's substituteBackreferences().
index 5417fb0..df3fd1e 100644 (file)
@@ -349,7 +349,7 @@ EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState* exec, EncodedJSValu
 
     if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
         if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-            JSBigInt* result = JSBigInt::bitwiseAnd(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
+            JSBigInt* result = JSBigInt::bitwiseAnd(*vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
             RETURN_IF_EXCEPTION(scope, encodedJSValue());
             return JSValue::encode(result);
         }
@@ -376,7 +376,7 @@ EncodedJSValue JIT_OPERATION operationValueBitOr(ExecState* exec, EncodedJSValue
 
     if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
         if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-            JSBigInt* result = JSBigInt::bitwiseOr(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
+            JSBigInt* result = JSBigInt::bitwiseOr(*vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
             RETURN_IF_EXCEPTION(scope, encodedJSValue());
             return JSValue::encode(result);
         }
@@ -1294,7 +1294,7 @@ JSCell* JIT_OPERATION operationSubBigInt(ExecState* exec, JSCell* op1, JSCell* o
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     
-    return JSBigInt::sub(exec, leftOperand, rightOperand);
+    return JSBigInt::sub(*vm, leftOperand, rightOperand);
 }
 
 JSCell* JIT_OPERATION operationBitAndBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
@@ -1305,7 +1305,7 @@ JSCell* JIT_OPERATION operationBitAndBigInt(ExecState* exec, JSCell* op1, JSCell
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
 
-    return JSBigInt::bitwiseAnd(exec, leftOperand, rightOperand);
+    return JSBigInt::bitwiseAnd(*vm, leftOperand, rightOperand);
 }
 
 JSCell* JIT_OPERATION operationAddBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
@@ -1316,7 +1316,7 @@ JSCell* JIT_OPERATION operationAddBigInt(ExecState* exec, JSCell* op1, JSCell* o
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     
-    return JSBigInt::add(exec, leftOperand, rightOperand);
+    return JSBigInt::add(*vm, leftOperand, rightOperand);
 }
 
 JSCell* JIT_OPERATION operationBitOrBigInt(ExecState* exec, JSCell* op1, JSCell* op2)
@@ -1327,7 +1327,7 @@ JSCell* JIT_OPERATION operationBitOrBigInt(ExecState* exec, JSCell* op1, JSCell*
     JSBigInt* leftOperand = jsCast<JSBigInt*>(op1);
     JSBigInt* rightOperand = jsCast<JSBigInt*>(op2);
     
-    return JSBigInt::bitwiseOr(exec, leftOperand, rightOperand);
+    return JSBigInt::bitwiseOr(*vm, leftOperand, rightOperand);
 }
 
 size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, JSCell* op1, JSCell* op2)
index 511c42f..1e8fe00 100644 (file)
@@ -2766,8 +2766,10 @@ EncodedJSValue JIT_OPERATION operationArithNegateOptimize(ExecState* exec, Encod
     JSValue primValue = operand.toPrimitive(exec);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
     
-    if (primValue.isBigInt())
-        return JSValue::encode(JSBigInt::unaryMinus(vm, asBigInt(primValue)));
+    if (primValue.isBigInt()) {
+        JSBigInt* result = JSBigInt::unaryMinus(vm, asBigInt(primValue));
+        return JSValue::encode(result);
+    }
 
     double number = primValue.toNumber(exec);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
index ee5ada2..5163c33 100644 (file)
@@ -563,8 +563,7 @@ SLOW_PATH_DECL(slow_path_sub)
 
     if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
         if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-            JSBigInt* result = JSBigInt::sub(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
-            CHECK_EXCEPTION();
+            JSBigInt* result = JSBigInt::sub(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
             RETURN_WITH_PROFILING(result, {
                 updateArithProfileForBinaryArithOp(exec, pc, result, left, right);
             });
@@ -700,7 +699,7 @@ SLOW_PATH_DECL(slow_path_bitand)
     CHECK_EXCEPTION();
     if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
         if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-            JSBigInt* result = JSBigInt::bitwiseAnd(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
+            JSBigInt* result = JSBigInt::bitwiseAnd(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
             CHECK_EXCEPTION();
             RETURN_PROFILED(result);
         }
@@ -721,7 +720,7 @@ SLOW_PATH_DECL(slow_path_bitor)
     CHECK_EXCEPTION();
     if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
         if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-            JSBigInt* result = JSBigInt::bitwiseOr(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
+            JSBigInt* result = JSBigInt::bitwiseOr(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
             CHECK_EXCEPTION();
             RETURN_PROFILED(result);
         }
@@ -742,7 +741,7 @@ SLOW_PATH_DECL(slow_path_bitxor)
     CHECK_EXCEPTION();
     if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
         if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-            JSBigInt* result = JSBigInt::bitwiseXor(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
+            JSBigInt* result = JSBigInt::bitwiseXor(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
             CHECK_EXCEPTION();
             RETURN(result);
         }
index 0c6f40d..4ab5a52 100644 (file)
@@ -81,7 +81,7 @@ Structure* JSBigInt::createStructure(VM& vm, JSGlobalObject* globalObject, JSVal
 
 JSBigInt* JSBigInt::createZero(VM& vm)
 {
-    JSBigInt* zeroBigInt = createWithLengthUnchecked(vm, 0);
+    JSBigInt* zeroBigInt = createWithLength(vm, 0);
     return zeroBigInt;
 }
 
@@ -91,22 +91,7 @@ inline size_t JSBigInt::allocationSize(unsigned length)
     return sizeWithPadding + length * sizeof(Digit);
 }
 
-JSBigInt* JSBigInt::tryCreateWithLength(ExecState* exec, unsigned length)
-{
-    VM& vm = exec->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (UNLIKELY(length > maxLength)) {
-        throwOutOfMemoryError(exec, scope);
-        return nullptr;
-    }
-
-    scope.release();
-
-    return createWithLengthUnchecked(vm, length);
-}
-
-JSBigInt* JSBigInt::createWithLengthUnchecked(VM& vm, unsigned length)
+JSBigInt* JSBigInt::createWithLength(VM& vm, unsigned length)
 {
     JSBigInt* bigInt = new (NotNull, allocateCell<JSBigInt>(vm.heap, allocationSize(length))) JSBigInt(vm, vm.bigIntStructure.get(), length);
     bigInt->finishCreation(vm);
@@ -118,7 +103,8 @@ JSBigInt* JSBigInt::createFrom(VM& vm, int32_t value)
     if (!value)
         return createZero(vm);
     
-    JSBigInt* bigInt = createWithLengthUnchecked(vm, 1);
+    JSBigInt* bigInt = createWithLength(vm, 1);
+    
     if (value < 0) {
         bigInt->setDigit(0, static_cast<Digit>(-1 * static_cast<int64_t>(value)));
         bigInt->setSign(true);
@@ -133,7 +119,7 @@ JSBigInt* JSBigInt::createFrom(VM& vm, uint32_t value)
     if (!value)
         return createZero(vm);
     
-    JSBigInt* bigInt = createWithLengthUnchecked(vm, 1);
+    JSBigInt* bigInt = createWithLength(vm, 1);
     bigInt->setDigit(0, static_cast<Digit>(value));
     return bigInt;
 }
@@ -144,7 +130,8 @@ JSBigInt* JSBigInt::createFrom(VM& vm, int64_t value)
         return createZero(vm);
     
     if (sizeof(Digit) == 8) {
-        JSBigInt* bigInt = createWithLengthUnchecked(vm, 1);
+        JSBigInt* bigInt = createWithLength(vm, 1);
+        
         if (value < 0) {
             bigInt->setDigit(0, static_cast<Digit>(static_cast<uint64_t>(-(value + 1)) + 1));
             bigInt->setSign(true);
@@ -154,7 +141,8 @@ JSBigInt* JSBigInt::createFrom(VM& vm, int64_t value)
         return bigInt;
     }
     
-    JSBigInt* bigInt = createWithLengthUnchecked(vm, 2);
+    JSBigInt* bigInt = createWithLength(vm, 2);
+    
     uint64_t tempValue;
     bool sign = false;
     if (value < 0) {
@@ -178,7 +166,7 @@ JSBigInt* JSBigInt::createFrom(VM& vm, bool value)
     if (!value)
         return createZero(vm);
     
-    JSBigInt* bigInt = createWithLengthUnchecked(vm, 1);
+    JSBigInt* bigInt = createWithLength(vm, 1);
     bigInt->setDigit(0, static_cast<Digit>(value));
     return bigInt;
 }
@@ -246,7 +234,6 @@ void JSBigInt::inplaceMultiplyAdd(Digit factor, Digit summand)
 JSBigInt* JSBigInt::multiply(ExecState* exec, JSBigInt* x, JSBigInt* y)
 {
     VM& vm = exec->vm();
-    auto scope = DECLARE_CATCH_SCOPE(vm);
 
     if (x->isZero())
         return x;
@@ -254,8 +241,7 @@ JSBigInt* JSBigInt::multiply(ExecState* exec, JSBigInt* x, JSBigInt* y)
         return y;
 
     unsigned resultLength = x->length() + y->length();
-    JSBigInt* result = JSBigInt::tryCreateWithLength(exec, resultLength);
-    RETURN_IF_EXCEPTION(scope, nullptr);
+    JSBigInt* result = JSBigInt::createWithLength(vm, resultLength);
     result->initialize(InitializationType::WithZero);
 
     for (unsigned i = 0; i < x->length(); i++)
@@ -291,10 +277,8 @@ JSBigInt* JSBigInt::divide(ExecState* exec, JSBigInt* x, JSBigInt* y)
 
         Digit remainder;
         absoluteDivWithDigitDivisor(vm, x, divisor, &quotient, remainder);
-    } else {
-        absoluteDivWithBigIntDivisor(exec, x, y, &quotient, nullptr);
-        RETURN_IF_EXCEPTION(scope, nullptr);
-    }
+    } else
+        absoluteDivWithBigIntDivisor(vm, x, y, &quotient, nullptr);
 
     quotient->setSign(resultSign);
     return quotient->rightTrim(vm);
@@ -304,7 +288,7 @@ JSBigInt* JSBigInt::copy(VM& vm, JSBigInt* x)
 {
     ASSERT(!x->isZero());
 
-    JSBigInt* result = JSBigInt::createWithLengthUnchecked(vm, x->length());
+    JSBigInt* result = JSBigInt::createWithLength(vm, x->length());
     std::copy(x->dataStorage(), x->dataStorage() + x->length(), result->dataStorage());
     result->setSign(x->sign());
     return result;
@@ -347,26 +331,23 @@ JSBigInt* JSBigInt::remainder(ExecState* exec, JSBigInt* x, JSBigInt* y)
         if (!remainderDigit)
             return createZero(vm);
 
-        remainder = createWithLengthUnchecked(vm, 1);
+        remainder = createWithLength(vm, 1);
         remainder->setDigit(0, remainderDigit);
-    } else {
-        absoluteDivWithBigIntDivisor(exec, x, y, nullptr, &remainder);
-        RETURN_IF_EXCEPTION(scope, nullptr);
-    }
+    } else
+        absoluteDivWithBigIntDivisor(vm, x, y, nullptr, &remainder);
 
     remainder->setSign(x->sign());
     return remainder->rightTrim(vm);
 }
 
-JSBigInt* JSBigInt::add(ExecState* exec, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::add(VM& vm, JSBigInt* x, JSBigInt* y)
 {
-    VM& vm = exec->vm();
     bool xSign = x->sign();
 
     // x + y == x + y
     // -x + -y == -(x + y)
     if (xSign == y->sign())
-        return absoluteAdd(exec, x, y, xSign);
+        return absoluteAdd(vm, x, y, xSign);
 
     // x + -y == x - y == -(y - x)
     // -x + y == y - x == -(x - y)
@@ -377,14 +358,13 @@ JSBigInt* JSBigInt::add(ExecState* exec, JSBigInt* x, JSBigInt* y)
     return absoluteSub(vm, y, x, !xSign);
 }
 
-JSBigInt* JSBigInt::sub(ExecState* exec, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::sub(VM& vm, JSBigInt* x, JSBigInt* y)
 {
-    VM& vm = exec->vm();
     bool xSign = x->sign();
     if (xSign != y->sign()) {
         // x - (-y) == x + y
         // (-x) - y == -(x + y)
-        return absoluteAdd(exec, x, y, xSign);
+        return absoluteAdd(vm, x, y, xSign);
     }
     // x - y == -(y - x)
     // (-x) - (-y) == y - x == -(x - y)
@@ -395,11 +375,8 @@ JSBigInt* JSBigInt::sub(ExecState* exec, JSBigInt* x, JSBigInt* y)
     return absoluteSub(vm, y, x, !xSign);
 }
 
-JSBigInt* JSBigInt::bitwiseAnd(ExecState* exec, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::bitwiseAnd(VM& vm, JSBigInt* x, JSBigInt* y)
 {
-    VM& vm = exec->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
     if (!x->sign() && !y->sign())
         return absoluteAnd(vm, x, y);
     
@@ -407,14 +384,11 @@ JSBigInt* JSBigInt::bitwiseAnd(ExecState* exec, JSBigInt* x, JSBigInt* y)
         int resultLength = std::max(x->length(), y->length()) + 1;
         // (-x) & (-y) == ~(x-1) & ~(y-1) == ~((x-1) | (y-1))
         // == -(((x-1) | (y-1)) + 1)
-        JSBigInt* result = absoluteSubOne(exec, x, resultLength);
-        RETURN_IF_EXCEPTION(scope, nullptr);
-
-        JSBigInt* y1 = absoluteSubOne(exec, y, y->length());
-        ASSERT(y1);
+        JSBigInt* result = absoluteSubOne(vm, x, resultLength);
+        JSBigInt* y1 = absoluteSubOne(vm, y, y->length());
         result = absoluteOr(vm, result, y1);
-        scope.release();
-        return absoluteAddOne(exec, result, SignOption::Signed);
+
+        return absoluteAddOne(vm, result, SignOption::Signed);
     }
 
     ASSERT(x->sign() != y->sign());
@@ -423,15 +397,11 @@ JSBigInt* JSBigInt::bitwiseAnd(ExecState* exec, JSBigInt* x, JSBigInt* y)
         std::swap(x, y);
     
     // x & (-y) == x & ~(y-1) == x & ~(y-1)
-    JSBigInt* y1 = absoluteSubOne(exec, y, y->length());
-    ASSERT(y1);
-    return absoluteAndNot(vm, x, y1);
+    return absoluteAndNot(vm, x, absoluteSubOne(vm, y, y->length()));
 }
 
-JSBigInt* JSBigInt::bitwiseOr(ExecState* exec, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::bitwiseOr(VM& vm, JSBigInt* x, JSBigInt* y)
 {
-    VM& vm = exec->vm();
-
     unsigned resultLength = std::max(x->length(), y->length());
 
     if (!x->sign() && !y->sign())
@@ -440,12 +410,10 @@ JSBigInt* JSBigInt::bitwiseOr(ExecState* exec, JSBigInt* x, JSBigInt* y)
     if (x->sign() && y->sign()) {
         // (-x) | (-y) == ~(x-1) | ~(y-1) == ~((x-1) & (y-1))
         // == -(((x-1) & (y-1)) + 1)
-        JSBigInt* result = absoluteSubOne(exec, x, resultLength);
-        ASSERT(result);
-        JSBigInt* y1 = absoluteSubOne(exec, y, y->length());
-        ASSERT(y1);
+        JSBigInt* result = absoluteSubOne(vm, x, resultLength);
+        JSBigInt* y1 = absoluteSubOne(vm, y, y->length());
         result = absoluteAnd(vm, result, y1);
-        return absoluteAddOne(exec, result, SignOption::Signed);
+        return absoluteAddOne(vm, result, SignOption::Signed);
     }
     
     ASSERT(x->sign() != y->sign());
@@ -455,17 +423,13 @@ JSBigInt* JSBigInt::bitwiseOr(ExecState* exec, JSBigInt* x, JSBigInt* y)
         std::swap(x, y);
     
     // x | (-y) == x | ~(y-1) == ~((y-1) &~ x) == -(((y-1) &~ x) + 1)
-    JSBigInt* result = absoluteSubOne(exec, y, resultLength);
-    ASSERT(result);
+    JSBigInt* result = absoluteSubOne(vm, y, resultLength);
     result = absoluteAndNot(vm, result, x);
-    return absoluteAddOne(exec, result, SignOption::Signed);
+    return absoluteAddOne(vm, result, SignOption::Signed);
 }
 
-JSBigInt* JSBigInt::bitwiseXor(ExecState* exec, JSBigInt* x, JSBigInt* y)
+JSBigInt* JSBigInt::bitwiseXor(VM& vm, JSBigInt* x, JSBigInt* y)
 {
-    VM& vm = exec->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
     if (!x->sign() && !y->sign())
         return absoluteXor(vm, x, y);
     
@@ -473,10 +437,8 @@ JSBigInt* JSBigInt::bitwiseXor(ExecState* exec, JSBigInt* x, JSBigInt* y)
         int resultLength = std::max(x->length(), y->length());
         
         // (-x) ^ (-y) == ~(x-1) ^ ~(y-1) == (x-1) ^ (y-1)
-        JSBigInt* result = absoluteSubOne(exec, x, resultLength);
-        ASSERT(result);
-        JSBigInt* y1 = absoluteSubOne(exec, y, y->length());
-        ASSERT(y1);
+        JSBigInt* result = absoluteSubOne(vm, x, resultLength);
+        JSBigInt* y1 = absoluteSubOne(vm, y, y->length());
         return absoluteXor(vm, result, y1);
     }
     ASSERT(x->sign() != y->sign());
@@ -487,12 +449,9 @@ JSBigInt* JSBigInt::bitwiseXor(ExecState* exec, JSBigInt* x, JSBigInt* y)
         std::swap(x, y);
     
     // x ^ (-y) == x ^ ~(y-1) == ~(x ^ (y-1)) == -((x ^ (y-1)) + 1)
-    JSBigInt* result = absoluteSubOne(exec, y, resultLength);
-    RETURN_IF_EXCEPTION(scope, nullptr);
-
+    JSBigInt* result = absoluteSubOne(vm, y, resultLength);
     result = absoluteXor(vm, result, x);
-    scope.release();
-    return absoluteAddOne(exec, result, SignOption::Signed);
+    return absoluteAddOne(vm, result, SignOption::Signed);
 }
 
 #if USE(JSVALUE32_64)
@@ -792,12 +751,10 @@ inline JSBigInt::ComparisonResult JSBigInt::absoluteCompare(JSBigInt* x, JSBigIn
     return x->digit(i) > y->digit(i) ? ComparisonResult::GreaterThan : ComparisonResult::LessThan;
 }
 
-JSBigInt* JSBigInt::absoluteAdd(ExecState* exec, JSBigInt* x, JSBigInt* y, bool resultSign)
+JSBigInt* JSBigInt::absoluteAdd(VM& vm, JSBigInt* x, JSBigInt* y, bool resultSign)
 {
-    VM& vm = exec->vm();
-
     if (x->length() < y->length())
-        return absoluteAdd(exec, y, x, resultSign);
+        return absoluteAdd(vm, y, x, resultSign);
 
     if (x->isZero()) {
         ASSERT(y->isZero());
@@ -807,9 +764,8 @@ JSBigInt* JSBigInt::absoluteAdd(ExecState* exec, JSBigInt* x, JSBigInt* y, bool
     if (y->isZero())
         return resultSign == x->sign() ? x : unaryMinus(vm, x);
 
-    JSBigInt* result = JSBigInt::tryCreateWithLength(exec, x->length() + 1);
-    if (!result)
-        return nullptr;
+    JSBigInt* result = JSBigInt::createWithLength(vm, x->length() + 1);
+    ASSERT(result);
     Digit carry = 0;
     unsigned i = 0;
     for (; i < y->length(); i++) {
@@ -850,8 +806,7 @@ JSBigInt* JSBigInt::absoluteSub(VM& vm, JSBigInt* x, JSBigInt* y, bool resultSig
     if (comparisonResult == ComparisonResult::Equal)
         return JSBigInt::createZero(vm);
 
-    JSBigInt* result = JSBigInt::createWithLengthUnchecked(vm, x->length());
-
+    JSBigInt* result = JSBigInt::createWithLength(vm, x->length());
     Digit borrow = 0;
     unsigned i = 0;
     for (; i < y->length(); i++) {
@@ -896,7 +851,7 @@ void JSBigInt::absoluteDivWithDigitDivisor(VM& vm, JSBigInt* x, Digit divisor, J
     unsigned length = x->length();
     if (quotient != nullptr) {
         if (*quotient == nullptr)
-            *quotient = JSBigInt::createWithLengthUnchecked(vm, length);
+            *quotient = JSBigInt::createWithLength(vm, length);
 
         for (int i = length - 1; i >= 0; i--) {
             Digit q = digitDiv(remainder, x->digit(i), divisor, remainder);
@@ -914,12 +869,10 @@ void JSBigInt::absoluteDivWithDigitDivisor(VM& vm, JSBigInt* x, Digit divisor, J
 // Both {quotient} and {remainder} are optional, for callers that are only
 // interested in one of them.
 // See Knuth, Volume 2, section 4.3.1, Algorithm D.
-void JSBigInt::absoluteDivWithBigIntDivisor(ExecState* exec, JSBigInt* dividend, JSBigInt* divisor, JSBigInt** quotient, JSBigInt** remainder)
+void JSBigInt::absoluteDivWithBigIntDivisor(VM& vm, JSBigInt* dividend, JSBigInt* divisor, JSBigInt** quotient, JSBigInt** remainder)
 {
     ASSERT(divisor->length() >= 2);
     ASSERT(dividend->length() >= divisor->length());
-    VM& vm = exec->vm();
-    auto scope = DECLARE_CATCH_SCOPE(vm);
 
     // The unusual variable names inside this function are consistent with
     // Knuth's book, as well as with Go's implementation of this algorithm.
@@ -931,12 +884,11 @@ void JSBigInt::absoluteDivWithBigIntDivisor(ExecState* exec, JSBigInt* dividend,
     // The quotient to be computed.
     JSBigInt* q = nullptr;
     if (quotient != nullptr)
-        q = createWithLengthUnchecked(exec->vm(), m + 1);
+        q = createWithLength(vm, m + 1);
     
     // In each iteration, {qhatv} holds {divisor} * {current quotient digit}.
     // "v" is the book's name for {divisor}, "qhat" the current quotient digit.
-    JSBigInt* qhatv = tryCreateWithLength(exec, n + 1);
-    RETURN_IF_EXCEPTION(scope, void());
+    JSBigInt* qhatv = createWithLength(vm, n + 1);
     
     // D1.
     // Left-shift inputs so that the divisor's MSB is set. This is necessary
@@ -946,15 +898,12 @@ void JSBigInt::absoluteDivWithBigIntDivisor(ExecState* exec, JSBigInt* dividend,
     Digit lastDigit = divisor->digit(n - 1);
     unsigned shift = sizeof(lastDigit) == 8 ? clz64(lastDigit) : clz32(lastDigit);
 
-    if (shift > 0) {
-        divisor = absoluteLeftShiftAlwaysCopy(exec, divisor, shift, LeftShiftMode::SameSizeResult);
-        RETURN_IF_EXCEPTION(scope, void());
-    }
+    if (shift > 0)
+        divisor = absoluteLeftShiftAlwaysCopy(vm, divisor, shift, LeftShiftMode::SameSizeResult);
 
     // Holds the (continuously updated) remaining part of the dividend, which
     // eventually becomes the remainder.
-    JSBigInt* u = absoluteLeftShiftAlwaysCopy(exec, dividend, shift, LeftShiftMode::AlwaysAddOneDigit);
-    RETURN_IF_EXCEPTION(scope, void());
+    JSBigInt* u = absoluteLeftShiftAlwaysCopy(vm, dividend, shift, LeftShiftMode::AlwaysAddOneDigit);
 
     // D2.
     // Iterate over the dividend's digit (like the "grad school" algorithm).
@@ -1082,16 +1031,14 @@ void JSBigInt::inplaceRightShift(unsigned shift)
 }
 
 // Always copies the input, even when {shift} == 0.
-JSBigInt* JSBigInt::absoluteLeftShiftAlwaysCopy(ExecState* exec, JSBigInt* x, unsigned shift, LeftShiftMode mode)
+JSBigInt* JSBigInt::absoluteLeftShiftAlwaysCopy(VM& vm, JSBigInt* x, unsigned shift, LeftShiftMode mode)
 {
     ASSERT(shift < digitBits);
     ASSERT(!x->isZero());
 
     unsigned n = x->length();
     unsigned resultLength = mode == LeftShiftMode::AlwaysAddOneDigit ? n + 1 : n;
-    JSBigInt* result = tryCreateWithLength(exec, resultLength);
-    if (!result)
-        return nullptr;
+    JSBigInt* result = createWithLength(vm, resultLength);
 
     if (!shift) {
         for (unsigned i = 0; i < n; i++)
@@ -1148,7 +1095,8 @@ inline JSBigInt* JSBigInt::absoluteBitwiseOp(VM& vm, JSBigInt* x, JSBigInt* y, E
 
     ASSERT(numPairs == std::min(xLength, yLength));
     unsigned resultLength = extraDigits == ExtraDigitsHandling::Copy ? xLength : numPairs;
-    JSBigInt* result = createWithLengthUnchecked(vm, resultLength);
+    JSBigInt* result = createWithLength(vm, resultLength);
+
     unsigned i = 0;
     for (; i < numPairs; i++)
         result->setDigit(i, op(x->digit(i), y->digit(i)));
@@ -1196,7 +1144,7 @@ JSBigInt* JSBigInt::absoluteXor(VM& vm, JSBigInt* x, JSBigInt* y)
     return absoluteBitwiseOp(vm, x, y, ExtraDigitsHandling::Copy, SymmetricOp::Symmetric, digitOperation);
 }
     
-JSBigInt* JSBigInt::absoluteAddOne(ExecState* exec, JSBigInt* x, SignOption signOption)
+JSBigInt* JSBigInt::absoluteAddOne(VM& vm, JSBigInt* x, SignOption signOption)
 {
     unsigned inputLength = x->length();
     // The addition will overflow into a new digit if all existing digits are
@@ -1210,9 +1158,7 @@ JSBigInt* JSBigInt::absoluteAddOne(ExecState* exec, JSBigInt* x, SignOption sign
     }
 
     unsigned resultLength = inputLength + willOverflow;
-    JSBigInt* result = tryCreateWithLength(exec, resultLength);
-    if (!result)
-        return nullptr;
+    JSBigInt* result = createWithLength(vm, resultLength);
 
     Digit carry = 1;
     for (unsigned i = 0; i < inputLength; i++) {
@@ -1226,18 +1172,16 @@ JSBigInt* JSBigInt::absoluteAddOne(ExecState* exec, JSBigInt* x, SignOption sign
         ASSERT(!carry);
 
     result->setSign(signOption == SignOption::Signed);
-    return result->rightTrim(exec->vm());
+    return result->rightTrim(vm);
 }
 
-JSBigInt* JSBigInt::absoluteSubOne(ExecState* exec, JSBigInt* x, unsigned resultLength)
+// Like the above, but you can specify that the allocated result should have
+// length {resultLength}, which must be at least as large as {x->length()}.
+JSBigInt* JSBigInt::absoluteSubOne(VM& vm, JSBigInt* x, unsigned resultLength)
 {
     ASSERT(!x->isZero());
     ASSERT(resultLength >= x->length());
-    VM& vm = exec->vm();
-    auto scope = DECLARE_CATCH_SCOPE(vm);
-
-    JSBigInt* result = tryCreateWithLength(exec, resultLength);
-    RETURN_IF_EXCEPTION(scope, nullptr);
+    JSBigInt* result = createWithLength(vm, resultLength);
 
     unsigned length = x->length();
     Digit borrow = 1;
@@ -1410,6 +1354,8 @@ String JSBigInt::toStringGeneric(ExecState* exec, JSBigInt* x, unsigned radix)
         do {
             Digit chunk;
             absoluteDivWithDigitDivisor(vm, *dividend, chunkDivisor, &rest, chunk);
+            ASSERT(rest);
+
             dividend = &rest;
             for (unsigned i = 0; i < chunkChars; i++) {
                 resultString.append(radixDigits[chunk % radix]);
@@ -1468,7 +1414,8 @@ JSBigInt* JSBigInt::rightTrim(VM& vm)
         return this;
 
     unsigned newLength = nonZeroIndex + 1;
-    JSBigInt* trimmedBigInt = createWithLengthUnchecked(vm, newLength);
+    JSBigInt* trimmedBigInt = createWithLength(vm, newLength);
+    RELEASE_ASSERT(trimmedBigInt);
     std::copy(dataStorage(), dataStorage() + newLength, trimmedBigInt->dataStorage()); 
 
     trimmedBigInt->setSign(this->sign());
@@ -1492,7 +1439,7 @@ JSBigInt* JSBigInt::allocateFor(ExecState* exec, VM& vm, unsigned radix, unsigne
             // Divide by kDigitsBits, rounding up.
             unsigned length = (bitsMin + digitBits - 1) / digitBits;
             if (length <= maxLength) {
-                JSBigInt* result = JSBigInt::createWithLengthUnchecked(vm, length);
+                JSBigInt* result = JSBigInt::createWithLength(vm, length);
                 return result;
             }
         }
index ab8ff5a..a62e138 100644 (file)
@@ -51,8 +51,7 @@ public:
 
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
     static JSBigInt* createZero(VM&);
-    static JSBigInt* tryCreateWithLength(ExecState*, unsigned length);
-    static JSBigInt* createWithLengthUnchecked(VM&, unsigned length);
+    static JSBigInt* createWithLength(VM&, unsigned length);
 
     static JSBigInt* createFrom(VM&, int32_t value);
     static JSBigInt* createFrom(VM&, uint32_t value);
@@ -109,15 +108,15 @@ public:
     
     ComparisonResult static compareToDouble(JSBigInt* x, double y);
 
-    static JSBigInt* add(ExecState*, JSBigInt* x, JSBigInt* y);
-    static JSBigInt* sub(ExecState*, JSBigInt* x, JSBigInt* y);
+    static JSBigInt* add(VM&, JSBigInt* x, JSBigInt* y);
+    static JSBigInt* sub(VM&, JSBigInt* x, JSBigInt* y);
     static JSBigInt* divide(ExecState*, JSBigInt* x, JSBigInt* y);
     static JSBigInt* remainder(ExecState*, JSBigInt* x, JSBigInt* y);
     static JSBigInt* unaryMinus(VM&, JSBigInt* x);
 
-    static JSBigInt* bitwiseAnd(ExecState*, JSBigInt* x, JSBigInt* y);
-    static JSBigInt* bitwiseOr(ExecState*, JSBigInt* x, JSBigInt* y);
-    static JSBigInt* bitwiseXor(ExecState*, JSBigInt* x, JSBigInt* y);
+    static JSBigInt* bitwiseAnd(VM&, JSBigInt* x, JSBigInt* y);
+    static JSBigInt* bitwiseOr(VM&, JSBigInt* x, JSBigInt* y);
+    static JSBigInt* bitwiseXor(VM&, JSBigInt* x, JSBigInt* y);
 
 private:
 
@@ -140,14 +139,14 @@ private:
     static void absoluteDivWithDigitDivisor(VM&, JSBigInt* x, Digit divisor, JSBigInt** quotient, Digit& remainder);
     static void internalMultiplyAdd(JSBigInt* source, Digit factor, Digit summand, unsigned, JSBigInt* result);
     static void multiplyAccumulate(JSBigInt* multiplicand, Digit multiplier, JSBigInt* accumulator, unsigned accumulatorIndex);
-    static void absoluteDivWithBigIntDivisor(ExecState*, JSBigInt* dividend, JSBigInt* divisor, JSBigInt** quotient, JSBigInt** remainder);
+    static void absoluteDivWithBigIntDivisor(VM&, JSBigInt* dividend, JSBigInt* divisor, JSBigInt** quotient, JSBigInt** remainder);
     
     enum class LeftShiftMode {
         SameSizeResult,
         AlwaysAddOneDigit
     };
     
-    static JSBigInt* absoluteLeftShiftAlwaysCopy(ExecState*, JSBigInt* x, unsigned shift, LeftShiftMode);
+    static JSBigInt* absoluteLeftShiftAlwaysCopy(VM&, JSBigInt* x, unsigned shift, LeftShiftMode);
     static bool productGreaterThan(Digit factor1, Digit factor2, Digit high, Digit low);
 
     Digit absoluteInplaceAdd(JSBigInt* summand, unsigned startIndex);
@@ -177,8 +176,8 @@ private:
         Unsigned
     };
 
-    static JSBigInt* absoluteAddOne(ExecState*, JSBigInt* x, SignOption);
-    static JSBigInt* absoluteSubOne(ExecState*, JSBigInt* x, unsigned resultLength);
+    static JSBigInt* absoluteAddOne(VM&, JSBigInt* x, SignOption);
+    static JSBigInt* absoluteSubOne(VM&, JSBigInt* x, unsigned resultLength);
 
     // Digit arithmetic helpers.
     static Digit digitAdd(Digit a, Digit b, Digit& carry);
@@ -204,7 +203,7 @@ private:
     JSBigInt* rightTrim(VM&);
 
     void inplaceMultiplyAdd(Digit multiplier, Digit part);
-    static JSBigInt* absoluteAdd(ExecState*, JSBigInt* x, JSBigInt* y, bool resultSign);
+    static JSBigInt* absoluteAdd(VM&, JSBigInt* x, JSBigInt* y, bool resultSign);
     static JSBigInt* absoluteSub(VM&, JSBigInt* x, JSBigInt* y, bool resultSign);
     
     static size_t allocationSize(unsigned length);
index 836f953..a088ad1 100644 (file)
@@ -69,10 +69,8 @@ NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2)
     RETURN_IF_EXCEPTION(scope, { });
 
     if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-        if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-            scope.release();
-            return JSBigInt::add(callFrame, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
-        }
+        if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric))
+            return JSBigInt::add(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
 
         return throwTypeError(callFrame, scope, "Invalid mix of BigInt and other type in addition."_s);
     }
index 0ea9829..61d533c 100644 (file)
@@ -348,10 +348,8 @@ ALWAYS_INLINE JSValue jsSub(ExecState* exec, JSValue v1, JSValue v2)
     RETURN_IF_EXCEPTION(scope, { });
 
     if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-        if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-            scope.release();
-            return JSBigInt::sub(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
-        }
+        if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric))
+            return JSBigInt::sub(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
 
         return throwTypeError(exec, scope, "Invalid mix of BigInt and other type in subtraction."_s);
     }
@@ -370,10 +368,8 @@ ALWAYS_INLINE JSValue jsMul(ExecState* state, JSValue v1, JSValue v2)
     RETURN_IF_EXCEPTION(scope, { });
 
     if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-        if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) {
-            scope.release();
+        if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric))
             return JSBigInt::multiply(state, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));
-        }
 
         throwTypeError(state, scope, "Invalid mix of BigInt and other type in multiplication."_s);
         return { };