Changeset 260810 in webkit


Ignore:
Timestamp:
Apr 27, 2020 11:41:54 PM (4 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Throw OutOfMemoryError instead of RangeError if BigInt is too big
https://bugs.webkit.org/show_bug.cgi?id=211111

Reviewed by Saam Barati.

JSTests:

  • stress/big-int-constructor-oom.js:

(catch):

  • stress/big-int-left-shift-range-error.js:

(assertThrowRangeError):

  • stress/big-int-out-of-memory-tests.js:

(catch):

  • stress/bigint-exponential-oom.js: Added.

(shouldThrow):

  • stress/bigint-int32-min-shift.js:

(shouldThrow):

Source/JavaScriptCore:

Currently, we are throwing a RangeError if we detect that JSBigInt becomes too large. But this is not consistent with our JSString's policy.
We should throw OutOfMemoryError in this case. This also makes DFG simple since DFG allows throwing OutOfMemoryError in any places which node
is even removed.

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • runtime/ExceptionHelpers.cpp:

(JSC::throwOutOfMemoryError):

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

(JSC::JSBigInt::tryCreateWithLength):
(JSC::JSBigInt::exponentiateHeap):
(JSC::JSBigInt::leftShiftByAbsolute):
(JSC::JSBigInt::allocateFor):

Location:
trunk
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r260806 r260810  
     12020-04-27  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Throw OutOfMemoryError instead of RangeError if BigInt is too big
     4        https://bugs.webkit.org/show_bug.cgi?id=211111
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/big-int-constructor-oom.js:
     9        (catch):
     10        * stress/big-int-left-shift-range-error.js:
     11        (assertThrowRangeError):
     12        * stress/big-int-out-of-memory-tests.js:
     13        (catch):
     14        * stress/bigint-exponential-oom.js: Added.
     15        (shouldThrow):
     16        * stress/bigint-int32-min-shift.js:
     17        (shouldThrow):
     18
    1192020-04-27  Keith Miller  <keith_miller@apple.com>
    220
  • trunk/JSTests/stress/big-int-constructor-oom.js

    r226377 r260810  
    1717    assert(false);
    1818} catch(e) {
    19     assert(e.message == "Out of memory")
     19    assert(e.message == "Out of memory: BigInt generated from this operation is too big")
    2020}
    2121
  • trunk/JSTests/stress/big-int-left-shift-range-error.js

    r238790 r260810  
    1111        assert(false, message + ": Should throw RangeError, but executed without exception");
    1212    } catch (e) {
    13         assert(e instanceof RangeError, message + ": expected RangeError, got: " + e);
     13        assert(e instanceof Error, message + ": expected Error , got: " + e);
    1414    }
    1515}
  • trunk/JSTests/stress/big-int-out-of-memory-tests.js

    r238790 r260810  
    1313    assert(false, "Should throw OutOfMemoryError, but executed without exception");
    1414} catch(e) {
    15     assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
     15    assert(e.message == "Out of memory: BigInt generated from this operation is too big", "Expected OutOfMemoryError, but got: " + e);
    1616}
    1717
     
    2020    assert(false, "Should throw OutOfMemoryError, but executed without exception");
    2121} catch(e) {
    22     assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
     22    assert(e.message == "Out of memory: BigInt generated from this operation is too big", "Expected OutOfMemoryError, but got: " + e);
    2323}
    2424
     
    2727    assert(false, "Should throw OutOfMemoryError, but executed without exception");
    2828} catch(e) {
    29     assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
     29    assert(e.message == "Out of memory: BigInt generated from this operation is too big", "Expected OutOfMemoryError, but got: " + e);
    3030}
    3131
     
    3434    assert(false, "Should throw OutOfMemoryError, but executed without exception");
    3535} catch(e) {
    36     assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
     36    assert(e.message == "Out of memory: BigInt generated from this operation is too big", "Expected OutOfMemoryError, but got: " + e);
    3737}
    3838
     
    4141    assert(false, "Should throw OutOfMemoryError, but executed without exception");
    4242} catch(e) {
    43     assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
     43    assert(e.message == "Out of memory: BigInt generated from this operation is too big", "Expected OutOfMemoryError, but got: " + e);
    4444}
    4545
     
    4848    assert(false, "Should throw OutOfMemoryError, but executed without exception");
    4949} catch(e) {
    50     assert(e.message == "Out of memory", "Expected OutOfMemoryError, but got: " + e);
     50    assert(e.message == "Out of memory: BigInt generated from this operation is too big", "Expected OutOfMemoryError, but got: " + e);
    5151}
    5252
  • trunk/JSTests/stress/bigint-int32-min-shift.js

    r260720 r260810  
    3838shouldThrow(() => {
    3939    1n >> int32min;
    40 }, `RangeError: BigInt generated from this operation is too big`);
     40}, `Error: Out of memory: BigInt generated from this operation is too big`);
    4141shouldThrow(() => {
    4242    -1n >> int32min;
    43 }, `RangeError: BigInt generated from this operation is too big`);
     43}, `Error: Out of memory: BigInt generated from this operation is too big`);
    4444shouldThrow(() => {
    4545    0x7fffffffn >> int32min;
    46 }, `RangeError: BigInt generated from this operation is too big`);
     46}, `Error: Out of memory: BigInt generated from this operation is too big`);
    4747shouldThrow(() => {
    4848    (-0x7fffffffn - 1n) >> int32min;
    49 }, `RangeError: BigInt generated from this operation is too big`);
     49}, `Error: Out of memory: BigInt generated from this operation is too big`);
  • trunk/Source/JavaScriptCore/ChangeLog

    r260809 r260810  
     12020-04-27  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Throw OutOfMemoryError instead of RangeError if BigInt is too big
     4        https://bugs.webkit.org/show_bug.cgi?id=211111
     5
     6        Reviewed by Saam Barati.
     7
     8        Currently, we are throwing a RangeError if we detect that JSBigInt becomes too large. But this is not consistent with our JSString's policy.
     9        We should throw OutOfMemoryError in this case. This also makes DFG simple since DFG allows throwing OutOfMemoryError in any places which node
     10        is even removed.
     11
     12        * dfg/DFGFixupPhase.cpp:
     13        (JSC::DFG::FixupPhase::fixupNode):
     14        * runtime/ExceptionHelpers.cpp:
     15        (JSC::throwOutOfMemoryError):
     16        * runtime/ExceptionHelpers.h:
     17        * runtime/JSBigInt.cpp:
     18        (JSC::JSBigInt::tryCreateWithLength):
     19        (JSC::JSBigInt::exponentiateHeap):
     20        (JSC::JSBigInt::leftShiftByAbsolute):
     21        (JSC::JSBigInt::allocateFor):
     22
    1232020-04-27  Saam Barati  <sbarati@apple.com>
    224
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r260730 r260810  
    326326                fixEdge<HeapBigIntUse>(node->child2());
    327327#endif
    328                 // Shift can throw RangeError.
    329                 switch (node->op()) {
    330                 case ValueBitXor:
    331                 case ValueBitOr:
    332                 case ValueBitAnd:
    333                     node->clearFlags(NodeMustGenerate);
    334                     break;
    335                 default:
    336                     break;
    337                 }
     328                node->clearFlags(NodeMustGenerate);
    338329                break;
    339330            }
  • trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp

    r260722 r260810  
    334334}
    335335
     336Exception* throwOutOfMemoryError(JSGlobalObject* globalObject, ThrowScope& scope, const String& message)
     337{
     338    return throwException(globalObject, scope, createOutOfMemoryError(globalObject, message));
     339}
     340
    336341Exception* throwStackOverflowError(JSGlobalObject* globalObject, ThrowScope& scope)
    337342{
  • trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.h

    r258059 r260810  
    5757
    5858JS_EXPORT_PRIVATE Exception* throwOutOfMemoryError(JSGlobalObject*, ThrowScope&);
     59JS_EXPORT_PRIVATE Exception* throwOutOfMemoryError(JSGlobalObject*, ThrowScope&, const String&);
    5960JS_EXPORT_PRIVATE Exception* throwStackOverflowError(JSGlobalObject*, ThrowScope&);
    6061JS_EXPORT_PRIVATE Exception* throwTerminatedExecutionException(JSGlobalObject*, ThrowScope&);
  • trunk/Source/JavaScriptCore/runtime/JSBigInt.cpp

    r260809 r260810  
    9696
    9797    if (UNLIKELY(length > maxLength)) {
    98         throwOutOfMemoryError(globalObject, scope);
     98        throwOutOfMemoryError(globalObject, scope, "BigInt generated from this operation is too big"_s);
    9999        return nullptr;
    100100    }
     
    365365    static_assert(maxLengthBits < std::numeric_limits<Digit>::max(), "maxLengthBits needs to be less than digit::max()");
    366366    if (exponent.length() > 1) {
    367         throwRangeError(globalObject, scope, "BigInt generated from this operation is too big"_s);
     367        throwOutOfMemoryError(globalObject, scope, "BigInt generated from this operation is too big"_s);
    368368        return nullptr;
    369369    }
     
    373373        return base;
    374374    if (expValue >= maxLengthBits) {
    375         throwRangeError(globalObject, scope, "BigInt generated from this operation is too big"_s);
     375        throwOutOfMemoryError(globalObject, scope, "BigInt generated from this operation is too big"_s);
    376376        return nullptr;
    377377    }
     
    17921792    auto optionalShift = toShiftAmount(y);
    17931793    if (!optionalShift) {
    1794         throwRangeError(globalObject, scope, "BigInt generated from this operation is too big"_s);
     1794        throwOutOfMemoryError(globalObject, scope, "BigInt generated from this operation is too big"_s);
    17951795        return nullptr;
    17961796    }
     
    18031803    int resultLength = length + digitShift + grow;
    18041804    if (static_cast<unsigned>(resultLength) > maxLength) {
    1805         throwRangeError(globalObject, scope, "BigInt generated from this operation is too big"_s);
     1805        throwOutOfMemoryError(globalObject, scope, "BigInt generated from this operation is too big"_s);
    18061806        return nullptr;
    18071807    }
     
    21592159    if (globalObject) {
    21602160        auto scope = DECLARE_THROW_SCOPE(vm);
    2161         throwOutOfMemoryError(globalObject, scope);
     2161        throwOutOfMemoryError(globalObject, scope, "BigInt generated from this operation is too big"_s);
    21622162    }
    21632163    return nullptr;
Note: See TracChangeset for help on using the changeset viewer.