Changeset 262342 in webkit for trunk/Source/JavaScriptCore/runtime/JSBigInt.cpp
- Timestamp:
- May 30, 2020, 12:46:53 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/JSBigInt.cpp
r262054 r262342 83 83 } 84 84 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(); 85 inline JSBigInt* JSBigInt::createZero(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm) 86 { 87 return createWithLength(nullOrGlobalObjectForOOM, vm, 0); 88 } 89 90 JSBigInt* JSBigInt::createZero(JSGlobalObject* globalObject) 91 { 92 return createZero(globalObject, globalObject->vm()); 93 } 94 95 JSBigInt* JSBigInt::tryCreateZero(VM& vm) 96 { 97 return createZero(nullptr, vm); 98 } 99 100 inline JSBigInt* JSBigInt::createWithLength(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, unsigned length) 101 { 94 102 auto scope = DECLARE_THROW_SCOPE(vm); 95 96 103 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); 98 106 return nullptr; 99 107 } 100 108 101 scope.release();102 103 return createWithLengthUnchecked(vm, length);104 }105 106 JSBigInt* JSBigInt::createWithLengthUnchecked(VM& vm, unsigned length)107 {108 109 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 } 110 116 JSBigInt* bigInt = new (NotNull, allocateCell<JSBigInt>(vm.heap)) JSBigInt(vm, vm.bigIntStructure.get(), reinterpret_cast<Digit*>(data), length); 111 117 bigInt->finishCreation(vm); … … 113 119 } 114 120 115 JSBigInt* JSBigInt::createFrom(VM& vm, int32_t value) 121 JSBigInt* JSBigInt::tryCreateWithLength(VM& vm, unsigned length) 122 { 123 return createWithLength(nullptr, vm, length); 124 } 125 126 JSBigInt* JSBigInt::createWithLength(JSGlobalObject* globalObject, unsigned length) 127 { 128 return createWithLength(globalObject, globalObject->vm(), length); 129 } 130 131 inline JSBigInt* JSBigInt::createFrom(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, int32_t value) 116 132 { 117 133 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 121 140 if (value < 0) { 122 141 bigInt->setDigit(0, static_cast<Digit>(-1 * static_cast<int64_t>(value))); … … 128 147 } 129 148 130 JSBigInt* JSBigInt::createFrom(VM& vm, uint32_t value) 131 { 149 JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, int32_t value) 150 { 151 return createFrom(globalObject, globalObject->vm(), value); 152 } 153 154 JSBigInt* JSBigInt::tryCreateFrom(VM& vm, int32_t value) 155 { 156 return createFrom(nullptr, vm, value); 157 } 158 159 JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, uint32_t value) 160 { 161 VM& vm = globalObject->vm(); 162 auto scope = DECLARE_THROW_SCOPE(vm); 163 132 164 if (!value) 133 return createZero(vm);165 RELEASE_AND_RETURN(scope, createZero(globalObject)); 134 166 135 JSBigInt* bigInt = createWithLengthUnchecked(vm, 1); 167 JSBigInt* bigInt = createWithLength(globalObject, 1); 168 RETURN_IF_EXCEPTION(scope, nullptr); 136 169 bigInt->setDigit(0, static_cast<Digit>(value)); 137 170 return bigInt; 138 171 } 139 172 140 inline JSBigInt* JSBigInt::createFromImpl(VM& vm, uint64_t value, bool sign) 141 { 173 inline JSBigInt* JSBigInt::createFromImpl(JSGlobalObject* globalObject, uint64_t value, bool sign) 174 { 175 VM& vm = globalObject->vm(); 176 auto scope = DECLARE_THROW_SCOPE(vm); 177 142 178 if (!value) 143 return createZero(vm);179 RELEASE_AND_RETURN(scope, createZero(globalObject)); 144 180 145 181 // This path is not just an optimization: because we do not call rightTrim at the end of this function, 146 182 // it would be a bug to create a BigInt with length=2 in this case. 147 183 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); 149 186 bigInt->setDigit(0, static_cast<Digit>(value)); 150 187 bigInt->setSign(sign); … … 153 190 154 191 ASSERT(sizeof(Digit) == 4); 155 JSBigInt* bigInt = createWithLengthUnchecked(vm, 2); 192 JSBigInt* bigInt = createWithLength(globalObject, 2); 193 RETURN_IF_EXCEPTION(scope, nullptr); 156 194 Digit lowBits = static_cast<Digit>(value & 0xffffffff); 157 195 Digit highBits = static_cast<Digit>((value >> 32) & 0xffffffff); … … 166 204 } 167 205 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)206 JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, uint64_t value) 207 { 208 return createFromImpl(globalObject, value, false); 209 } 210 211 JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, int64_t value) 174 212 { 175 213 uint64_t unsignedValue; … … 180 218 } else 181 219 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 223 JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, bool value) 224 { 225 VM& vm = globalObject->vm(); 226 auto scope = DECLARE_THROW_SCOPE(vm); 227 187 228 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); 191 233 bigInt->setDigit(0, static_cast<Digit>(value)); 192 234 return bigInt; 193 235 } 194 236 195 JSBigInt* JSBigInt::createFrom(VM& vm, double value) 196 { 237 JSBigInt* JSBigInt::createFrom(JSGlobalObject* globalObject, double value) 238 { 239 VM& vm = globalObject->vm(); 240 auto scope = DECLARE_THROW_SCOPE(vm); 241 197 242 ASSERT(isInteger(value)); 198 243 if (!value) 199 return createZero(vm);244 RELEASE_AND_RETURN(scope, createZero(globalObject)); 200 245 201 246 bool sign = value < 0; // -0 was already handled above. … … 206 251 int32_t exponent = rawExponent - 0x3ff; 207 252 int32_t digits = exponent / digitBits + 1; 208 JSBigInt* result = createWithLengthUnchecked(vm, digits); 253 JSBigInt* result = createWithLength(globalObject, digits); 254 RETURN_IF_EXCEPTION(scope, nullptr); 209 255 ASSERT(result); 210 256 result->initialize(InitializationType::WithZero); … … 260 306 result->setDigit(digitIndex, digit); 261 307 } 262 return result->rightTrim(vm);308 RELEASE_AND_RETURN(scope, result->rightTrim(globalObject)); 263 309 } 264 310 … … 275 321 } 276 322 277 JSValue JSBigInt::parseInt(JSGlobalObject* globalObject, VM& vm, StringView s, uint8_t radix, ErrorParseMode parserMode, ParseIntSign sign)323 JSValue JSBigInt::parseInt(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, StringView s, uint8_t radix, ErrorParseMode parserMode, ParseIntSign sign) 278 324 { 279 325 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); 282 328 } 283 329 … … 319 365 ALWAYS_INLINE unsigned length() { return m_bigInt->length(); } 320 366 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; } 322 369 323 370 private: … … 344 391 } 345 392 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 } 347 402 348 403 private: … … 403 458 } 404 459 405 static ALWAYS_INLINE JSBigInt::ImplResult zeroImpl( VM& vm)460 static ALWAYS_INLINE JSBigInt::ImplResult zeroImpl(JSGlobalObject* globalObject) 406 461 { 407 462 #if USE(BIGINT32) 408 UNUSED_PARAM( vm);463 UNUSED_PARAM(globalObject); 409 464 return jsBigInt32(0); 410 465 #else 411 return JSBigInt::createZero( vm);466 return JSBigInt::createZero(globalObject); 412 467 #endif 413 468 } … … 432 487 // 2. If base is 0n and exponent is 0n, return 1n. 433 488 if (exponent.isZero()) 434 return JSBigInt::createFrom(vm, 1);489 RELEASE_AND_RETURN(scope, JSBigInt::createFrom(globalObject, 1)); 435 490 436 491 // 3. Return a BigInt representing the mathematical value of base raised … … 442 497 // (-1) ** even_number == 1. 443 498 if (base.sign() && !(exponent.digit(0) & 1)) 444 return JSBigInt::unaryMinusImpl(vm, base);499 RELEASE_AND_RETURN(scope, JSBigInt::unaryMinusImpl(globalObject, base)); 445 500 446 501 // (-1) ** odd_number == -1; 1 ** anything == 1. … … 469 524 // Fast path for 2^n. 470 525 int neededDigits = 1 + (n / digitBits); 471 JSBigInt* result = JSBigInt:: tryCreateWithLength(globalObject, neededDigits);526 JSBigInt* result = JSBigInt::createWithLength(globalObject, neededDigits); 472 527 RETURN_IF_EXCEPTION(scope, nullptr); 473 528 … … 484 539 485 540 JSBigInt* result = nullptr; 486 JSBigInt* runningSquare = base.toHeapBigInt(vm); 541 JSBigInt* runningSquare = base.toHeapBigInt(globalObject); 542 RETURN_IF_EXCEPTION(scope, nullptr); 487 543 488 544 // 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 } 491 549 492 550 n >>= 1; … … 549 607 550 608 unsigned resultLength = x.length() + y.length(); 551 JSBigInt* result = JSBigInt:: tryCreateWithLength(globalObject, resultLength);609 JSBigInt* result = JSBigInt::createWithLength(globalObject, resultLength); 552 610 RETURN_IF_EXCEPTION(scope, nullptr); 553 611 result->initialize(InitializationType::WithZero); … … 557 615 558 616 result->setSign(x.sign() != y.sign()); 559 return result->rightTrim(vm);617 RELEASE_AND_RETURN(scope, result->rightTrim(globalObject)); 560 618 } 561 619 … … 591 649 // integral value. 592 650 if (absoluteCompare(x, y) == ComparisonResult::LessThan) 593 return zeroImpl(vm);651 RELEASE_AND_RETURN(scope, zeroImpl(globalObject)); 594 652 595 653 JSBigInt* quotient = nullptr; … … 597 655 if (y.length() == 1) { 598 656 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 } 601 662 602 663 Digit remainder; 603 absoluteDivWithDigitDivisor(vm, x, divisor, "ient, remainder); 664 absoluteDivWithDigitDivisor(globalObject, vm, x, divisor, "ient, remainder); 665 RETURN_IF_EXCEPTION(scope, nullptr); 604 666 } else { 605 absoluteDivWithBigIntDivisor(globalObject, x, y.toHeapBigInt(vm), "ient, nullptr);667 JSBigInt* yBigInt = y.toHeapBigInt(globalObject); 606 668 RETURN_IF_EXCEPTION(scope, nullptr); 669 absoluteDivWithBigIntDivisor(globalObject, x, yBigInt, "ient, nullptr); 670 RETURN_IF_EXCEPTION(scope, nullptr); 607 671 } 608 672 609 673 quotient->setSign(resultSign); 610 return quotient->rightTrim(vm);674 RELEASE_AND_RETURN(scope, quotient->rightTrim(globalObject)); 611 675 } 612 676 … … 627 691 628 692 template <typename BigIntImpl> 629 JSBigInt* JSBigInt::copy(VM& vm, BigIntImpl x) 630 { 693 JSBigInt* JSBigInt::copy(JSGlobalObject* globalObject, BigIntImpl x) 694 { 695 VM& vm = globalObject->vm(); 696 auto scope = DECLARE_THROW_SCOPE(vm); 697 631 698 ASSERT(!x.isZero()); 632 699 633 JSBigInt* result = JSBigInt::createWithLengthUnchecked(vm, x.length()); 700 JSBigInt* result = createWithLength(globalObject, x.length()); 701 RETURN_IF_EXCEPTION(scope, nullptr); 702 634 703 for (unsigned i = 0; i < result->length(); ++i) 635 704 result->setDigit(i, x.digit(i)); … … 639 708 640 709 template <typename BigIntImpl> 641 JSBigInt::ImplResult JSBigInt::unaryMinusImpl(VM& vm, BigIntImpl x) 642 { 710 JSBigInt::ImplResult JSBigInt::unaryMinusImpl(JSGlobalObject* globalObject, BigIntImpl x) 711 { 712 VM& vm = globalObject->vm(); 713 auto scope = DECLARE_THROW_SCOPE(vm); 714 643 715 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 647 721 result->setSign(!x.sign()); 648 722 return result; 649 723 } 650 724 651 JSValue JSBigInt::unaryMinus( VM& vm, JSBigInt* x)652 { 653 return tryConvertToBigInt32(unaryMinusImpl( vm, HeapBigIntImpl { x }));725 JSValue JSBigInt::unaryMinus(JSGlobalObject* globalObject, JSBigInt* x) 726 { 727 return tryConvertToBigInt32(unaryMinusImpl(globalObject, HeapBigIntImpl { x })); 654 728 } 655 729 … … 675 749 Digit divisor = y.digit(0); 676 750 if (divisor == 1) 677 return zeroImpl(vm);751 RELEASE_AND_RETURN(scope, zeroImpl(globalObject)); 678 752 679 753 Digit remainderDigit; 680 absoluteDivWithDigitDivisor(vm, x, divisor, nullptr, remainderDigit); 754 absoluteDivWithDigitDivisor(globalObject, vm, x, divisor, nullptr, remainderDigit); 755 RETURN_IF_EXCEPTION(scope, nullptr); 756 681 757 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); 685 762 remainder->setDigit(0, remainderDigit); 686 763 } else { 687 absoluteDivWithBigIntDivisor(globalObject, x, y.toHeapBigInt(vm), nullptr, &remainder);764 JSBigInt* yBigInt = y.toHeapBigInt(globalObject); 688 765 RETURN_IF_EXCEPTION(scope, nullptr); 766 absoluteDivWithBigIntDivisor(globalObject, x, yBigInt, nullptr, &remainder); 767 RETURN_IF_EXCEPTION(scope, nullptr); 689 768 } 690 769 691 770 remainder->setSign(x.sign()); 692 return remainder->rightTrim(vm);771 RELEASE_AND_RETURN(scope, remainder->rightTrim(globalObject)); 693 772 } 694 773 JSValue JSBigInt::remainder(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y) … … 710 789 JSBigInt::ImplResult JSBigInt::incImpl(JSGlobalObject* globalObject, BigIntImpl x) 711 790 { 791 VM& vm = globalObject->vm(); 792 auto scope = DECLARE_THROW_SCOPE(vm); 793 712 794 if (!x.sign()) 713 return absoluteAddOne(globalObject, x, SignOption::Unsigned);795 RELEASE_AND_RETURN(scope, absoluteAddOne(globalObject, x, SignOption::Unsigned)); 714 796 JSBigInt* result = absoluteSubOne(globalObject, x, x.length()); 797 RETURN_IF_EXCEPTION(scope, nullptr); 715 798 if (result->isZero()) 716 799 return result; … … 731 814 return jsBigInt32(-1); 732 815 #else 733 return createFrom(globalObject ->vm(), -1);816 return createFrom(globalObject, -1); 734 817 #endif 735 818 } … … 747 830 JSBigInt::ImplResult JSBigInt::addImpl(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y) 748 831 { 749 VM& vm = globalObject->vm();750 832 bool xSign = x.sign(); 751 833 … … 759 841 ComparisonResult comparisonResult = absoluteCompare(x, y); 760 842 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); 764 846 } 765 847 JSValue JSBigInt::add(JSGlobalObject* globalObject, JSBigInt* x, JSBigInt* y) … … 781 863 JSBigInt::ImplResult JSBigInt::subImpl(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y) 782 864 { 783 VM& vm = globalObject->vm();784 865 bool xSign = x.sign(); 785 866 if (xSign != y.sign()) { … … 792 873 ComparisonResult comparisonResult = absoluteCompare(x, y); 793 874 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); 797 878 } 798 879 … … 818 899 auto scope = DECLARE_THROW_SCOPE(vm); 819 900 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)); 824 903 825 904 if (x.sign() && y.sign()) { … … 832 911 JSBigInt* y1 = absoluteSubOne(globalObject, y, y.length()); 833 912 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)); 837 916 } 838 917 … … 844 923 JSBigInt* y1 = absoluteSubOne(globalObject, y, y.length()); 845 924 RETURN_IF_EXCEPTION(scope, nullptr); 846 return absoluteAndNot(vm, x, HeapBigIntImpl { y1 });925 RELEASE_AND_RETURN(scope, absoluteAndNot(globalObject, x, HeapBigIntImpl { y1 })); 847 926 }; 848 927 if (x.sign()) … … 874 953 unsigned resultLength = std::max(x.length(), y.length()); 875 954 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)); 880 957 881 958 if (x.sign() && y.sign()) { … … 886 963 JSBigInt* y1 = absoluteSubOne(globalObject, y, y.length()); 887 964 RETURN_IF_EXCEPTION(scope, nullptr); 888 result = absoluteAnd( vm, HeapBigIntImpl { result }, HeapBigIntImpl { y1 });965 result = absoluteAnd(globalObject, HeapBigIntImpl { result }, HeapBigIntImpl { y1 }); 889 966 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)); 893 968 } 894 969 … … 902 977 JSBigInt* result = absoluteSubOne(globalObject, y, resultLength); 903 978 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)); 908 982 }; 909 983 … … 934 1008 auto scope = DECLARE_THROW_SCOPE(vm); 935 1009 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)); 940 1012 941 1013 if (x.sign() && y.sign()) { … … 947 1019 JSBigInt* y1 = absoluteSubOne(globalObject, y, y.length()); 948 1020 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 })); 952 1022 } 953 1023 ASSERT(x.sign() != y.sign()); … … 961 1031 RETURN_IF_EXCEPTION(scope, nullptr); 962 1032 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)); 966 1036 }; 967 1037 … … 1375 1445 { 1376 1446 VM& vm = globalObject->vm(); 1447 auto scope = DECLARE_THROW_SCOPE(vm); 1377 1448 1378 1449 if (x.length() < y.length()) 1379 return absoluteAdd(globalObject, y, x, resultSign);1450 RELEASE_AND_RETURN(scope, absoluteAdd(globalObject, y, x, resultSign)); 1380 1451 1381 1452 if (x.isZero()) { … … 1384 1455 } 1385 1456 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); 1392 1466 Digit carry = 0; 1393 1467 unsigned i = 0; … … 1410 1484 result->setSign(resultSign); 1411 1485 1412 return result->rightTrim(vm);1486 RELEASE_AND_RETURN(scope, result->rightTrim(globalObject)); 1413 1487 } 1414 1488 1415 1489 template <typename BigIntImpl1, typename BigIntImpl2> 1416 JSBigInt::ImplResult JSBigInt::absoluteSub(VM& vm, BigIntImpl1 x, BigIntImpl2 y, bool resultSign) 1417 { 1490 JSBigInt::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 1418 1495 ComparisonResult comparisonResult = absoluteCompare(x, y); 1419 1496 ASSERT(x.length() >= y.length()); … … 1425 1502 } 1426 1503 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 } 1429 1509 1430 1510 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); 1434 1515 1435 1516 Digit borrow = 0; … … 1452 1533 ASSERT(!borrow); 1453 1534 result->setSign(resultSign); 1454 return result->rightTrim(vm);1535 RELEASE_AND_RETURN(scope, result->rightTrim(globalObject)); 1455 1536 } 1456 1537 … … 1463 1544 // also be nullptr if the caller is only interested in the remainder. 1464 1545 template <typename BigIntImpl> 1465 void JSBigInt::absoluteDivWithDigitDivisor(VM& vm, BigIntImpl x, Digit divisor, JSBigInt** quotient, Digit& remainder)1546 bool JSBigInt::absoluteDivWithDigitDivisor(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, BigIntImpl x, Digit divisor, JSBigInt** quotient, Digit& remainder) 1466 1547 { 1467 1548 ASSERT(divisor); … … 1470 1551 remainder = 0; 1471 1552 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; 1475 1560 } 1476 1561 1477 1562 unsigned length = x.length(); 1478 1563 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 } 1481 1570 1482 1571 for (int i = length - 1; i >= 0; i--) { … … 1488 1577 digitDiv(remainder, x.digit(i), divisor, remainder); 1489 1578 } 1579 return true; 1490 1580 } 1491 1581 … … 1513 1603 // The quotient to be computed. 1514 1604 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 } 1517 1609 1518 1610 // In each iteration, {qhatv} holds {divisor} * {current quotient digit}. 1519 1611 // "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); 1521 1613 RETURN_IF_EXCEPTION(scope, void()); 1522 1614 … … 1668 1760 JSBigInt* JSBigInt::absoluteLeftShiftAlwaysCopy(JSGlobalObject* globalObject, BigIntImpl x, unsigned shift, LeftShiftMode mode) 1669 1761 { 1762 VM& vm = globalObject->vm(); 1763 auto scope = DECLARE_THROW_SCOPE(vm); 1764 1670 1765 ASSERT(shift < digitBits); 1671 1766 ASSERT(!x.isZero()); … … 1673 1768 unsigned n = x.length(); 1674 1769 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, { }); 1678 1772 1679 1773 if (!shift) { … … 1717 1811 // result: [ 0 ][ x3 ][ r2 ][ r1 ][ r0 ] 1718 1812 template <typename BigIntImpl1, typename BigIntImpl2, typename BitwiseOp> 1719 inline JSBigInt* JSBigInt::absoluteBitwiseOp(VM& vm, BigIntImpl1 x, BigIntImpl2 y, ExtraDigitsHandling extraDigits, BitwiseOp&& op) 1720 { 1813 inline 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 1721 1818 unsigned xLength = x.length(); 1722 1819 unsigned yLength = y.length(); … … 1731 1828 ASSERT(maxLength == std::max(xLength, yLength)); 1732 1829 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); 1734 1832 unsigned i = 0; 1735 1833 for (; i < numPairs; i++) … … 1749 1847 result->setDigit(i, 0); 1750 1848 1751 return result->rightTrim(vm);1849 RELEASE_AND_RETURN(scope, result->rightTrim(globalObject)); 1752 1850 } 1753 1851 1754 1852 template <typename BigIntImpl1, typename BigIntImpl2> 1755 JSBigInt* JSBigInt::absoluteAnd( VM& vm, BigIntImpl1 x, BigIntImpl2 y)1853 JSBigInt* JSBigInt::absoluteAnd(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y) 1756 1854 { 1757 1855 auto digitOperation = [](Digit a, Digit b) { 1758 1856 return a & b; 1759 1857 }; 1760 return absoluteBitwiseOp( vm, x, y, ExtraDigitsHandling::Skip, digitOperation);1858 return absoluteBitwiseOp(globalObject, x, y, ExtraDigitsHandling::Skip, digitOperation); 1761 1859 } 1762 1860 1763 1861 template <typename BigIntImpl1, typename BigIntImpl2> 1764 JSBigInt* JSBigInt::absoluteOr( VM& vm, BigIntImpl1 x, BigIntImpl2 y)1862 JSBigInt* JSBigInt::absoluteOr(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y) 1765 1863 { 1766 1864 auto digitOperation = [](Digit a, Digit b) { 1767 1865 return a | b; 1768 1866 }; 1769 return absoluteBitwiseOp( vm, x, y, ExtraDigitsHandling::Copy, digitOperation);1867 return absoluteBitwiseOp(globalObject, x, y, ExtraDigitsHandling::Copy, digitOperation); 1770 1868 } 1771 1869 1772 1870 template <typename BigIntImpl1, typename BigIntImpl2> 1773 JSBigInt* JSBigInt::absoluteAndNot( VM& vm, BigIntImpl1 x, BigIntImpl2 y)1871 JSBigInt* JSBigInt::absoluteAndNot(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y) 1774 1872 { 1775 1873 // x & ~y 1874 1875 VM& vm = globalObject->vm(); 1876 auto scope = DECLARE_THROW_SCOPE(vm); 1776 1877 1777 1878 unsigned xLength = x.length(); … … 1779 1880 unsigned resultLength = xLength; 1780 1881 1781 JSBigInt* result = createWithLengthUnchecked(vm, resultLength); 1882 JSBigInt* result = createWithLength(globalObject, resultLength); 1883 RETURN_IF_EXCEPTION(scope, nullptr); 1782 1884 unsigned i = 0; 1783 1885 for (; i < std::min(xLength, yLength); i++) … … 1786 1888 result->setDigit(i, x.digit(i)); 1787 1889 1788 return result->rightTrim(vm);1890 RELEASE_AND_RETURN(scope, result->rightTrim(globalObject)); 1789 1891 } 1790 1892 1791 1893 template <typename BigIntImpl1, typename BigIntImpl2> 1792 JSBigInt* JSBigInt::absoluteXor( VM& vm, BigIntImpl1 x, BigIntImpl2 y)1894 JSBigInt* JSBigInt::absoluteXor(JSGlobalObject* globalObject, BigIntImpl1 x, BigIntImpl2 y) 1793 1895 { 1794 1896 auto digitOperation = [](Digit a, Digit b) { 1795 1897 return a ^ b; 1796 1898 }; 1797 return absoluteBitwiseOp( vm, x, y, ExtraDigitsHandling::Copy, digitOperation);1899 return absoluteBitwiseOp(globalObject, x, y, ExtraDigitsHandling::Copy, digitOperation); 1798 1900 } 1799 1901 … … 1801 1903 JSBigInt* JSBigInt::absoluteAddOne(JSGlobalObject* globalObject, BigIntImpl x, SignOption signOption) 1802 1904 { 1905 VM& vm = globalObject->vm(); 1906 auto scope = DECLARE_THROW_SCOPE(vm); 1907 1803 1908 unsigned inputLength = x.length(); 1804 1909 // The addition will overflow into a new digit if all existing digits are … … 1813 1918 1814 1919 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); 1818 1922 1819 1923 Digit carry = 1; … … 1829 1933 1830 1934 result->setSign(signOption == SignOption::Signed); 1831 return result->rightTrim(globalObject->vm());1935 RELEASE_AND_RETURN(scope, result->rightTrim(globalObject)); 1832 1936 } 1833 1937 … … 1840 1944 auto scope = DECLARE_THROW_SCOPE(vm); 1841 1945 1842 JSBigInt* result = tryCreateWithLength(globalObject, resultLength);1946 JSBigInt* result = createWithLength(globalObject, resultLength); 1843 1947 RETURN_IF_EXCEPTION(scope, nullptr); 1844 1948 … … 1854 1958 result->setDigit(i, borrow); 1855 1959 1856 return result->rightTrim(vm);1960 RELEASE_AND_RETURN(scope, result->rightTrim(globalObject)); 1857 1961 } 1858 1962 … … 1880 1984 } 1881 1985 1882 JSBigInt* result = tryCreateWithLength(globalObject, resultLength);1986 JSBigInt* result = createWithLength(globalObject, resultLength); 1883 1987 RETURN_IF_EXCEPTION(scope, nullptr); 1884 1988 if (!bitsShift) { … … 1907 2011 1908 2012 result->setSign(x.sign()); 1909 return result->rightTrim(vm);2013 RELEASE_AND_RETURN(scope, result->rightTrim(globalObject)); 1910 2014 } 1911 2015 … … 1914 2018 { 1915 2019 VM& vm = globalObject->vm(); 2020 auto scope = DECLARE_THROW_SCOPE(vm); 2021 1916 2022 unsigned length = x.length(); 1917 2023 bool sign = x.sign(); 1918 2024 auto optionalShift = toShiftAmount(y); 1919 2025 if (!optionalShift) 1920 return rightShiftByMaximum(vm, sign);2026 RELEASE_AND_RETURN(scope, rightShiftByMaximum(globalObject, sign)); 1921 2027 1922 2028 Digit shift = *optionalShift; … … 1925 2031 int resultLength = length - digitalShift; 1926 2032 if (resultLength <= 0) 1927 return rightShiftByMaximum(vm, sign);2033 RELEASE_AND_RETURN(scope, rightShiftByMaximum(globalObject, sign)); 1928 2034 1929 2035 // For negative numbers, round down if any bit was shifted out (so that e.g. … … 1956 2062 1957 2063 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 1959 2067 if (!bitsShift) { 1960 2068 for (unsigned i = digitalShift; i < length; i++) … … 1976 2084 // Since the result is negative, rounding down means adding one to 1977 2085 // 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)); 1980 2089 } 1981 2090 } 1982 2091 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 2095 JSBigInt::ImplResult JSBigInt::rightShiftByMaximum(JSGlobalObject* globalObject, bool sign) 1987 2096 { 1988 2097 if (sign) 1989 return createFrom( vm, -1);1990 1991 return createZero( vm);2098 return createFrom(globalObject, -1); 2099 2100 return createZero(globalObject); 1992 2101 } 1993 2102 … … 2035 2144 } 2036 2145 2037 String JSBigInt::toStringBasePowerOfTwo(VM& vm, JSGlobalObject* globalObject, JSBigInt* x, unsigned radix)2146 String JSBigInt::toStringBasePowerOfTwo(VM& vm, JSGlobalObject* nullOrGlobalObjectForOOM, JSBigInt* x, unsigned radix) 2038 2147 { 2039 2148 ASSERT(hasOneBitSet(radix)); … … 2055 2164 2056 2165 if (charsRequired > JSString::MaxLength) { 2057 if ( globalObject) {2166 if (nullOrGlobalObjectForOOM) { 2058 2167 auto scope = DECLARE_THROW_SCOPE(vm); 2059 throwOutOfMemoryError( globalObject, scope);2168 throwOutOfMemoryError(nullOrGlobalObjectForOOM, scope); 2060 2169 } 2061 2170 return String(); … … 2097 2206 } 2098 2207 2099 String JSBigInt::toStringGeneric(VM& vm, JSGlobalObject* globalObject, JSBigInt* x, unsigned radix)2208 String JSBigInt::toStringGeneric(VM& vm, JSGlobalObject* nullOrGlobalObjectForOOM, JSBigInt* x, unsigned radix) 2100 2209 { 2101 2210 // FIXME: [JSC] Revisit usage of Vector into JSBigInt::toString … … 2113 2222 2114 2223 if (maximumCharactersRequired > JSString::MaxLength) { 2115 if ( globalObject) {2224 if (nullOrGlobalObjectForOOM) { 2116 2225 auto scope = DECLARE_THROW_SCOPE(vm); 2117 throwOutOfMemoryError( globalObject, scope);2226 throwOutOfMemoryError(nullOrGlobalObjectForOOM, scope); 2118 2227 } 2119 2228 return String(); … … 2141 2250 do { 2142 2251 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(); 2144 2255 dividend = &rest; 2145 2256 for (unsigned i = 0; i < chunkChars; i++) { … … 2182 2293 } 2183 2294 2184 JSBigInt* JSBigInt::rightTrim( VM& vm)2295 JSBigInt* JSBigInt::rightTrim(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm) 2185 2296 { 2186 2297 if (isZero()) { … … 2194 2305 2195 2306 if (nonZeroIndex < 0) 2196 return createZero( vm);2307 return createZero(nullOrGlobalObjectForOOM, vm); 2197 2308 2198 2309 if (nonZeroIndex == static_cast<int>(m_length - 1)) … … 2200 2311 2201 2312 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()); 2204 2317 2205 2318 trimmedBigInt->setSign(this->sign()); … … 2208 2321 } 2209 2322 2210 JSBigInt* JSBigInt::allocateFor(JSGlobalObject* globalObject, VM& vm, unsigned radix, unsigned charcount) 2211 { 2323 JSBigInt* JSBigInt::rightTrim(JSGlobalObject* globalObject) 2324 { 2325 return rightTrim(globalObject, globalObject->vm()); 2326 } 2327 2328 JSBigInt* JSBigInt::tryRightTrim(VM& vm) 2329 { 2330 return rightTrim(nullptr, vm); 2331 } 2332 2333 JSBigInt* JSBigInt::allocateFor(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, unsigned radix, unsigned charcount) 2334 { 2335 auto scope = DECLARE_THROW_SCOPE(vm); 2336 2212 2337 ASSERT(2 <= radix && radix <= 36); 2213 2338 … … 2223 2348 // Divide by kDigitsBits, rounding up. 2224 2349 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)); 2229 2352 } 2230 2353 } 2231 2354 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 2236 2358 return nullptr; 2237 2359 } … … 2291 2413 2292 2414 template <typename CharType> 2293 JSValue JSBigInt::parseInt(JSGlobalObject* globalObject, VM& vm, CharType* data, unsigned length, unsigned startIndex, unsigned radix, ErrorParseMode errorParseMode, ParseIntSign sign, ParseIntMode parseMode)2415 JSValue JSBigInt::parseInt(JSGlobalObject* nullOrGlobalObjectForOOM, VM& vm, CharType* data, unsigned length, unsigned startIndex, unsigned radix, ErrorParseMode errorParseMode, ParseIntSign sign, ParseIntMode parseMode) 2294 2416 { 2295 2417 ASSERT(length >= 0); 2296 2418 unsigned p = startIndex; 2297 2419 2298 auto scope = DECLARE_THROW_SCOPE(vm);2299 2300 2420 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 } 2304 2426 return JSValue(); 2305 2427 } … … 2320 2442 return jsBigInt32(0); 2321 2443 #else 2322 return createZero( vm);2444 return createZero(nullOrGlobalObjectForOOM, vm); 2323 2445 #endif 2324 2446 } … … 2415 2537 else { 2416 2538 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")); 2419 2542 } 2420 2543 return JSValue(); … … 2434 2557 return jsBigInt32(static_cast<int32_t>(maybeResult)); 2435 2558 #else 2436 return JSBigInt::createFrom( vm, static_cast<int32_t>(maybeResult));2559 return JSBigInt::createFrom(nullOrGlobalObjectForOOM, vm, static_cast<int32_t>(maybeResult)); 2437 2560 #endif 2438 2561 } 2439 2562 } 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); 2443 2564 if (!heapResult) 2444 2565 return JSValue(); … … 2452 2573 2453 2574 heapResult->setSign(sign == ParseIntSign::Signed); 2454 return heapResult->rightTrim( vm);2575 return heapResult->rightTrim(nullOrGlobalObjectForOOM, vm); 2455 2576 } 2456 2577 … … 2739 2860 { 2740 2861 VM& vm = globalObject->vm(); 2862 auto scope = DECLARE_THROW_SCOPE(vm); 2741 2863 2742 2864 if (bigInt.isZero()) 2743 2865 return bigInt; 2744 2866 if (n == 0) 2745 return zeroImpl(vm);2867 RELEASE_AND_RETURN(scope, zeroImpl(globalObject)); 2746 2868 2747 2869 uint64_t neededLength = (n + digitBits - 1) / digitBits; … … 2767 2889 int32_t N = static_cast<int32_t>(n); 2768 2890 if (!hasBit) 2769 return truncateToNBits(vm, N, bigInt);2891 RELEASE_AND_RETURN(scope, truncateToNBits(globalObject, N, bigInt)); 2770 2892 if (!bigInt.sign()) 2771 return truncateAndSubFromPowerOfTwo(vm, N, bigInt, true);2893 RELEASE_AND_RETURN(scope, truncateAndSubFromPowerOfTwo(globalObject, N, bigInt, true)); 2772 2894 2773 2895 // Negative numbers must subtract from 2^n, except for the special case … … 2776 2898 for (int32_t i = static_cast<int32_t>(neededLength) - 2; i >= 0; i--) { 2777 2899 if (bigInt.digit(i) != 0) 2778 return truncateAndSubFromPowerOfTwo(vm, N, bigInt, false);2900 RELEASE_AND_RETURN(scope, truncateAndSubFromPowerOfTwo(globalObject, N, bigInt, false)); 2779 2901 } 2780 2902 // Truncation is no-op if bigInt == -2^(n-1). 2781 2903 if (length == neededLength && topDigit == compareDigit) 2782 2904 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)); 2786 2908 } 2787 2909 … … 2795 2917 return bigInt; 2796 2918 if (n == 0) 2797 return zeroImpl(vm);2919 RELEASE_AND_RETURN(scope, zeroImpl(globalObject)); 2798 2920 2799 2921 // If bigInt is negative, simulate two's complement representation. … … 2803 2925 return nullptr; 2804 2926 } 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)); 2806 2928 } 2807 2929 … … 2825 2947 // Otherwise, truncate. 2826 2948 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)); 2828 2950 } 2829 2951 2830 2952 template <typename BigIntImpl> 2831 JSBigInt::ImplResult JSBigInt::truncateToNBits(VM& vm, int32_t n, BigIntImpl bigInt) 2832 { 2953 JSBigInt::ImplResult JSBigInt::truncateToNBits(JSGlobalObject* globalObject, int32_t n, BigIntImpl bigInt) 2954 { 2955 VM& vm = globalObject->vm(); 2956 auto scope = DECLARE_THROW_SCOPE(vm); 2957 2833 2958 ASSERT(n != 0); 2834 2959 ASSERT(bigInt.length() > n / digitBits); … … 2836 2961 int32_t neededDigits = (n + (digitBits - 1)) / digitBits; 2837 2962 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); 2839 2965 ASSERT(result); 2840 2966 … … 2852 2978 result->setDigit(last, msd); 2853 2979 result->setSign(bigInt.sign()); 2854 return result->rightTrim(vm);2980 RELEASE_AND_RETURN(scope, result->rightTrim(globalObject)); 2855 2981 } 2856 2982 2857 2983 // Subtracts the least significant n bits of abs(bigInt) from 2^n. 2858 2984 template <typename BigIntImpl> 2859 JSBigInt::ImplResult JSBigInt::truncateAndSubFromPowerOfTwo(VM& vm, int32_t n, BigIntImpl bigInt, bool resultSign) 2860 { 2985 JSBigInt::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 2861 2990 ASSERT(n != 0); 2862 2991 ASSERT(n <= static_cast<int32_t>(maxLengthBits)); … … 2864 2993 int32_t neededDigits = (n + (digitBits - 1)) / digitBits; 2865 2994 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); 2867 2997 ASSERT(result); 2868 2998 … … 2911 3041 result->setDigit(last, resultMSD); 2912 3042 result->setSign(resultSign); 2913 return result->rightTrim(vm);3043 RELEASE_AND_RETURN(scope, result->rightTrim(globalObject)); 2914 3044 } 2915 3045
Note:
See TracChangeset
for help on using the changeset viewer.