Changeset 238132 in webkit
- Timestamp:
- Nov 13, 2018 7:46:34 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r238004 r238132 1 2018-11-13 Caio Lima <ticaiolima@gmail.com> 2 3 [BigInt] JSBigInt::createWithLength should throw when length is greater than JSBigInt::maxLength 4 https://bugs.webkit.org/show_bug.cgi?id=190836 5 6 Reviewed by Saam Barati. 7 8 * stress/big-int-out-of-memory-tests.js: Added. 9 1 10 2018-11-08 Ross Kirsling <ross.kirsling@sony.com> 2 11 -
trunk/Source/JavaScriptCore/ChangeLog
r238122 r238132 1 2018-11-13 Caio Lima <ticaiolima@gmail.com> 2 3 [BigInt] JSBigInt::createWithLength should throw when length is greater than JSBigInt::maxLength 4 https://bugs.webkit.org/show_bug.cgi?id=190836 5 6 Reviewed by Saam Barati. 7 8 In this patch we are creating a new method called `JSBigInt::createWithLengthUnchecked` 9 where we allocate a BigInt trusting the length received as argument. 10 With this additional method, we now check if length passed to 11 `JSBigInt::createWithLength` is not greater than JSBigInt::maxLength. 12 When the length is greater than maxLength, we then throw OOM 13 exception. 14 This required change the interface of some JSBigInt operations to 15 receive `ExecState*` instead of `VM&`. We changed only operations that 16 can throw because of OOM. 17 We beleive that this approach of throwing instead of finishing the 18 execution abruptly is better because JS programs can catch such 19 exception and handle this issue properly. 20 21 * dfg/DFGOperations.cpp: 22 * jit/JITOperations.cpp: 23 * runtime/CommonSlowPaths.cpp: 24 (JSC::SLOW_PATH_DECL): 25 * runtime/JSBigInt.cpp: 26 (JSC::JSBigInt::createZero): 27 (JSC::JSBigInt::tryCreateWithLength): 28 (JSC::JSBigInt::createWithLengthUnchecked): 29 (JSC::JSBigInt::createFrom): 30 (JSC::JSBigInt::multiply): 31 (JSC::JSBigInt::divide): 32 (JSC::JSBigInt::copy): 33 (JSC::JSBigInt::unaryMinus): 34 (JSC::JSBigInt::remainder): 35 (JSC::JSBigInt::add): 36 (JSC::JSBigInt::sub): 37 (JSC::JSBigInt::bitwiseAnd): 38 (JSC::JSBigInt::bitwiseOr): 39 (JSC::JSBigInt::bitwiseXor): 40 (JSC::JSBigInt::absoluteAdd): 41 (JSC::JSBigInt::absoluteSub): 42 (JSC::JSBigInt::absoluteDivWithDigitDivisor): 43 (JSC::JSBigInt::absoluteDivWithBigIntDivisor): 44 (JSC::JSBigInt::absoluteLeftShiftAlwaysCopy): 45 (JSC::JSBigInt::absoluteBitwiseOp): 46 (JSC::JSBigInt::absoluteAddOne): 47 (JSC::JSBigInt::absoluteSubOne): 48 (JSC::JSBigInt::toStringGeneric): 49 (JSC::JSBigInt::rightTrim): 50 (JSC::JSBigInt::allocateFor): 51 (JSC::JSBigInt::createWithLength): Deleted. 52 * runtime/JSBigInt.h: 53 * runtime/Operations.cpp: 54 (JSC::jsAddSlowCase): 55 * runtime/Operations.h: 56 (JSC::jsSub): 57 (JSC::jsMul): 58 1 59 2018-11-12 Devin Rousso <drousso@apple.com> 2 60 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r237972 r238132 350 350 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 351 351 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 352 JSBigInt* result = JSBigInt::bitwiseAnd( *vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));352 JSBigInt* result = JSBigInt::bitwiseAnd(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 353 353 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 354 354 return JSValue::encode(result); … … 377 377 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 378 378 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 379 JSBigInt* result = JSBigInt::bitwiseOr( *vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));379 JSBigInt* result = JSBigInt::bitwiseOr(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 380 380 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 381 381 return JSValue::encode(result); … … 1295 1295 JSBigInt* rightOperand = jsCast<JSBigInt*>(op2); 1296 1296 1297 return JSBigInt::sub( *vm, leftOperand, rightOperand);1297 return JSBigInt::sub(exec, leftOperand, rightOperand); 1298 1298 } 1299 1299 … … 1306 1306 JSBigInt* rightOperand = jsCast<JSBigInt*>(op2); 1307 1307 1308 return JSBigInt::bitwiseAnd( *vm, leftOperand, rightOperand);1308 return JSBigInt::bitwiseAnd(exec, leftOperand, rightOperand); 1309 1309 } 1310 1310 … … 1317 1317 JSBigInt* rightOperand = jsCast<JSBigInt*>(op2); 1318 1318 1319 return JSBigInt::add( *vm, leftOperand, rightOperand);1319 return JSBigInt::add(exec, leftOperand, rightOperand); 1320 1320 } 1321 1321 … … 1328 1328 JSBigInt* rightOperand = jsCast<JSBigInt*>(op2); 1329 1329 1330 return JSBigInt::bitwiseOr( *vm, leftOperand, rightOperand);1330 return JSBigInt::bitwiseOr(exec, leftOperand, rightOperand); 1331 1331 } 1332 1332 -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r237547 r238132 2767 2767 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 2768 2768 2769 if (primValue.isBigInt()) { 2770 JSBigInt* result = JSBigInt::unaryMinus(vm, asBigInt(primValue)); 2771 return JSValue::encode(result); 2772 } 2769 if (primValue.isBigInt()) 2770 return JSValue::encode(JSBigInt::unaryMinus(vm, asBigInt(primValue))); 2773 2771 2774 2772 double number = primValue.toNumber(exec); -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r237972 r238132 564 564 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 565 565 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 566 JSBigInt* result = JSBigInt::sub(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 566 JSBigInt* result = JSBigInt::sub(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 567 CHECK_EXCEPTION(); 567 568 RETURN_WITH_PROFILING(result, { 568 569 updateArithProfileForBinaryArithOp(exec, pc, result, left, right); … … 700 701 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 701 702 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 702 JSBigInt* result = JSBigInt::bitwiseAnd( vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));703 JSBigInt* result = JSBigInt::bitwiseAnd(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 703 704 CHECK_EXCEPTION(); 704 705 RETURN_PROFILED(result); … … 721 722 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 722 723 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 723 JSBigInt* result = JSBigInt::bitwiseOr( vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));724 JSBigInt* result = JSBigInt::bitwiseOr(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 724 725 CHECK_EXCEPTION(); 725 726 RETURN_PROFILED(result); … … 742 743 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 743 744 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 744 JSBigInt* result = JSBigInt::bitwiseXor( vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric));745 JSBigInt* result = JSBigInt::bitwiseXor(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 745 746 CHECK_EXCEPTION(); 746 747 RETURN(result); -
trunk/Source/JavaScriptCore/runtime/JSBigInt.cpp
r237296 r238132 82 82 JSBigInt* JSBigInt::createZero(VM& vm) 83 83 { 84 JSBigInt* zeroBigInt = createWithLength (vm, 0);84 JSBigInt* zeroBigInt = createWithLengthUnchecked(vm, 0); 85 85 return zeroBigInt; 86 86 } … … 92 92 } 93 93 94 JSBigInt* JSBigInt::createWithLength(VM& vm, unsigned length) 94 JSBigInt* JSBigInt::tryCreateWithLength(ExecState* exec, unsigned length) 95 { 96 VM& vm = exec->vm(); 97 auto scope = DECLARE_THROW_SCOPE(vm); 98 99 if (UNLIKELY(length > maxLength)) { 100 throwOutOfMemoryError(exec, scope); 101 return nullptr; 102 } 103 104 scope.release(); 105 106 return createWithLengthUnchecked(vm, length); 107 } 108 109 JSBigInt* JSBigInt::createWithLengthUnchecked(VM& vm, unsigned length) 95 110 { 96 111 JSBigInt* bigInt = new (NotNull, allocateCell<JSBigInt>(vm.heap, allocationSize(length))) JSBigInt(vm, vm.bigIntStructure.get(), length); … … 104 119 return createZero(vm); 105 120 106 JSBigInt* bigInt = createWithLength(vm, 1); 107 121 JSBigInt* bigInt = createWithLengthUnchecked(vm, 1); 108 122 if (value < 0) { 109 123 bigInt->setDigit(0, static_cast<Digit>(-1 * static_cast<int64_t>(value))); … … 120 134 return createZero(vm); 121 135 122 JSBigInt* bigInt = createWithLength (vm, 1);136 JSBigInt* bigInt = createWithLengthUnchecked(vm, 1); 123 137 bigInt->setDigit(0, static_cast<Digit>(value)); 124 138 return bigInt; … … 131 145 132 146 if (sizeof(Digit) == 8) { 133 JSBigInt* bigInt = createWithLength(vm, 1); 134 147 JSBigInt* bigInt = createWithLengthUnchecked(vm, 1); 135 148 if (value < 0) { 136 149 bigInt->setDigit(0, static_cast<Digit>(static_cast<uint64_t>(-(value + 1)) + 1)); … … 142 155 } 143 156 144 JSBigInt* bigInt = createWithLength(vm, 2); 145 157 JSBigInt* bigInt = createWithLengthUnchecked(vm, 2); 146 158 uint64_t tempValue; 147 159 bool sign = false; … … 167 179 return createZero(vm); 168 180 169 JSBigInt* bigInt = createWithLength (vm, 1);181 JSBigInt* bigInt = createWithLengthUnchecked(vm, 1); 170 182 bigInt->setDigit(0, static_cast<Digit>(value)); 171 183 return bigInt; … … 235 247 { 236 248 VM& vm = exec->vm(); 249 auto scope = DECLARE_CATCH_SCOPE(vm); 237 250 238 251 if (x->isZero()) … … 242 255 243 256 unsigned resultLength = x->length() + y->length(); 244 JSBigInt* result = JSBigInt::createWithLength(vm, resultLength); 257 JSBigInt* result = JSBigInt::tryCreateWithLength(exec, resultLength); 258 RETURN_IF_EXCEPTION(scope, nullptr); 245 259 result->initialize(InitializationType::WithZero); 246 260 … … 278 292 Digit remainder; 279 293 absoluteDivWithDigitDivisor(vm, x, divisor, "ient, remainder); 280 } else 281 absoluteDivWithBigIntDivisor(vm, x, y, "ient, nullptr); 294 } else { 295 absoluteDivWithBigIntDivisor(exec, x, y, "ient, nullptr); 296 RETURN_IF_EXCEPTION(scope, nullptr); 297 } 282 298 283 299 quotient->setSign(resultSign); … … 289 305 ASSERT(!x->isZero()); 290 306 291 JSBigInt* result = JSBigInt::createWithLength (vm, x->length());307 JSBigInt* result = JSBigInt::createWithLengthUnchecked(vm, x->length()); 292 308 std::copy(x->dataStorage(), x->dataStorage() + x->length(), result->dataStorage()); 293 309 result->setSign(x->sign()); … … 332 348 return createZero(vm); 333 349 334 remainder = createWithLength (vm, 1);350 remainder = createWithLengthUnchecked(vm, 1); 335 351 remainder->setDigit(0, remainderDigit); 336 } else 337 absoluteDivWithBigIntDivisor(vm, x, y, nullptr, &remainder); 352 } else { 353 absoluteDivWithBigIntDivisor(exec, x, y, nullptr, &remainder); 354 RETURN_IF_EXCEPTION(scope, nullptr); 355 } 338 356 339 357 remainder->setSign(x->sign()); … … 341 359 } 342 360 343 JSBigInt* JSBigInt::add(VM& vm, JSBigInt* x, JSBigInt* y) 344 { 361 JSBigInt* JSBigInt::add(ExecState* exec, JSBigInt* x, JSBigInt* y) 362 { 363 VM& vm = exec->vm(); 345 364 bool xSign = x->sign(); 346 365 … … 348 367 // -x + -y == -(x + y) 349 368 if (xSign == y->sign()) 350 return absoluteAdd( vm, x, y, xSign);369 return absoluteAdd(exec, x, y, xSign); 351 370 352 371 // x + -y == x - y == -(y - x) … … 359 378 } 360 379 361 JSBigInt* JSBigInt::sub(VM& vm, JSBigInt* x, JSBigInt* y) 362 { 380 JSBigInt* JSBigInt::sub(ExecState* exec, JSBigInt* x, JSBigInt* y) 381 { 382 VM& vm = exec->vm(); 363 383 bool xSign = x->sign(); 364 384 if (xSign != y->sign()) { 365 385 // x - (-y) == x + y 366 386 // (-x) - y == -(x + y) 367 return absoluteAdd( vm, x, y, xSign);387 return absoluteAdd(exec, x, y, xSign); 368 388 } 369 389 // x - y == -(y - x) … … 376 396 } 377 397 378 JSBigInt* JSBigInt::bitwiseAnd(VM& vm, JSBigInt* x, JSBigInt* y) 379 { 398 JSBigInt* JSBigInt::bitwiseAnd(ExecState* exec, JSBigInt* x, JSBigInt* y) 399 { 400 VM& vm = exec->vm(); 401 auto scope = DECLARE_THROW_SCOPE(vm); 402 380 403 if (!x->sign() && !y->sign()) 381 404 return absoluteAnd(vm, x, y); … … 385 408 // (-x) & (-y) == ~(x-1) & ~(y-1) == ~((x-1) | (y-1)) 386 409 // == -(((x-1) | (y-1)) + 1) 387 JSBigInt* result = absoluteSubOne(vm, x, resultLength); 388 JSBigInt* y1 = absoluteSubOne(vm, y, y->length()); 410 JSBigInt* result = absoluteSubOne(exec, x, resultLength); 411 RETURN_IF_EXCEPTION(scope, nullptr); 412 413 JSBigInt* y1 = absoluteSubOne(exec, y, y->length()); 414 ASSERT(y1); 389 415 result = absoluteOr(vm, result, y1); 390 391 return absoluteAddOne( vm, result, SignOption::Signed);416 scope.release(); 417 return absoluteAddOne(exec, result, SignOption::Signed); 392 418 } 393 419 … … 398 424 399 425 // x & (-y) == x & ~(y-1) == x & ~(y-1) 400 return absoluteAndNot(vm, x, absoluteSubOne(vm, y, y->length())); 401 } 402 403 JSBigInt* JSBigInt::bitwiseOr(VM& vm, JSBigInt* x, JSBigInt* y) 404 { 426 JSBigInt* y1 = absoluteSubOne(exec, y, y->length()); 427 ASSERT(y1); 428 return absoluteAndNot(vm, x, y1); 429 } 430 431 JSBigInt* JSBigInt::bitwiseOr(ExecState* exec, JSBigInt* x, JSBigInt* y) 432 { 433 VM& vm = exec->vm(); 434 405 435 unsigned resultLength = std::max(x->length(), y->length()); 406 436 … … 411 441 // (-x) | (-y) == ~(x-1) | ~(y-1) == ~((x-1) & (y-1)) 412 442 // == -(((x-1) & (y-1)) + 1) 413 JSBigInt* result = absoluteSubOne(vm, x, resultLength); 414 JSBigInt* y1 = absoluteSubOne(vm, y, y->length()); 443 JSBigInt* result = absoluteSubOne(exec, x, resultLength); 444 ASSERT(result); 445 JSBigInt* y1 = absoluteSubOne(exec, y, y->length()); 446 ASSERT(y1); 415 447 result = absoluteAnd(vm, result, y1); 416 return absoluteAddOne( vm, result, SignOption::Signed);448 return absoluteAddOne(exec, result, SignOption::Signed); 417 449 } 418 450 … … 424 456 425 457 // x | (-y) == x | ~(y-1) == ~((y-1) &~ x) == -(((y-1) &~ x) + 1) 426 JSBigInt* result = absoluteSubOne(vm, y, resultLength); 458 JSBigInt* result = absoluteSubOne(exec, y, resultLength); 459 ASSERT(result); 427 460 result = absoluteAndNot(vm, result, x); 428 return absoluteAddOne(vm, result, SignOption::Signed); 429 } 430 431 JSBigInt* JSBigInt::bitwiseXor(VM& vm, JSBigInt* x, JSBigInt* y) 432 { 461 return absoluteAddOne(exec, result, SignOption::Signed); 462 } 463 464 JSBigInt* JSBigInt::bitwiseXor(ExecState* exec, JSBigInt* x, JSBigInt* y) 465 { 466 VM& vm = exec->vm(); 467 auto scope = DECLARE_THROW_SCOPE(vm); 468 433 469 if (!x->sign() && !y->sign()) 434 470 return absoluteXor(vm, x, y); … … 438 474 439 475 // (-x) ^ (-y) == ~(x-1) ^ ~(y-1) == (x-1) ^ (y-1) 440 JSBigInt* result = absoluteSubOne(vm, x, resultLength); 441 JSBigInt* y1 = absoluteSubOne(vm, y, y->length()); 476 JSBigInt* result = absoluteSubOne(exec, x, resultLength); 477 ASSERT(result); 478 JSBigInt* y1 = absoluteSubOne(exec, y, y->length()); 479 ASSERT(y1); 442 480 return absoluteXor(vm, result, y1); 443 481 } … … 450 488 451 489 // x ^ (-y) == x ^ ~(y-1) == ~(x ^ (y-1)) == -((x ^ (y-1)) + 1) 452 JSBigInt* result = absoluteSubOne(vm, y, resultLength); 490 JSBigInt* result = absoluteSubOne(exec, y, resultLength); 491 RETURN_IF_EXCEPTION(scope, nullptr); 492 453 493 result = absoluteXor(vm, result, x); 454 return absoluteAddOne(vm, result, SignOption::Signed); 494 scope.release(); 495 return absoluteAddOne(exec, result, SignOption::Signed); 455 496 } 456 497 … … 752 793 } 753 794 754 JSBigInt* JSBigInt::absoluteAdd(VM& vm, JSBigInt* x, JSBigInt* y, bool resultSign) 755 { 795 JSBigInt* JSBigInt::absoluteAdd(ExecState* exec, JSBigInt* x, JSBigInt* y, bool resultSign) 796 { 797 VM& vm = exec->vm(); 798 756 799 if (x->length() < y->length()) 757 return absoluteAdd( vm, y, x, resultSign);800 return absoluteAdd(exec, y, x, resultSign); 758 801 759 802 if (x->isZero()) { … … 765 808 return resultSign == x->sign() ? x : unaryMinus(vm, x); 766 809 767 JSBigInt* result = JSBigInt::createWithLength(vm, x->length() + 1); 768 ASSERT(result); 810 JSBigInt* result = JSBigInt::tryCreateWithLength(exec, x->length() + 1); 811 if (!result) 812 return nullptr; 769 813 Digit carry = 0; 770 814 unsigned i = 0; … … 807 851 return JSBigInt::createZero(vm); 808 852 809 JSBigInt* result = JSBigInt::createWithLength(vm, x->length()); 853 JSBigInt* result = JSBigInt::createWithLengthUnchecked(vm, x->length()); 854 810 855 Digit borrow = 0; 811 856 unsigned i = 0; … … 852 897 if (quotient != nullptr) { 853 898 if (*quotient == nullptr) 854 *quotient = JSBigInt::createWithLength (vm, length);899 *quotient = JSBigInt::createWithLengthUnchecked(vm, length); 855 900 856 901 for (int i = length - 1; i >= 0; i--) { … … 870 915 // interested in one of them. 871 916 // See Knuth, Volume 2, section 4.3.1, Algorithm D. 872 void JSBigInt::absoluteDivWithBigIntDivisor( VM& vm, JSBigInt* dividend, JSBigInt* divisor, JSBigInt** quotient, JSBigInt** remainder)917 void JSBigInt::absoluteDivWithBigIntDivisor(ExecState* exec, JSBigInt* dividend, JSBigInt* divisor, JSBigInt** quotient, JSBigInt** remainder) 873 918 { 874 919 ASSERT(divisor->length() >= 2); 875 920 ASSERT(dividend->length() >= divisor->length()); 921 VM& vm = exec->vm(); 922 auto scope = DECLARE_CATCH_SCOPE(vm); 876 923 877 924 // The unusual variable names inside this function are consistent with … … 885 932 JSBigInt* q = nullptr; 886 933 if (quotient != nullptr) 887 q = createWithLength (vm, m + 1);934 q = createWithLengthUnchecked(exec->vm(), m + 1); 888 935 889 936 // In each iteration, {qhatv} holds {divisor} * {current quotient digit}. 890 937 // "v" is the book's name for {divisor}, "qhat" the current quotient digit. 891 JSBigInt* qhatv = createWithLength(vm, n + 1); 938 JSBigInt* qhatv = tryCreateWithLength(exec, n + 1); 939 RETURN_IF_EXCEPTION(scope, void()); 892 940 893 941 // D1. … … 899 947 unsigned shift = sizeof(lastDigit) == 8 ? clz64(lastDigit) : clz32(lastDigit); 900 948 901 if (shift > 0) 902 divisor = absoluteLeftShiftAlwaysCopy(vm, divisor, shift, LeftShiftMode::SameSizeResult); 949 if (shift > 0) { 950 divisor = absoluteLeftShiftAlwaysCopy(exec, divisor, shift, LeftShiftMode::SameSizeResult); 951 RETURN_IF_EXCEPTION(scope, void()); 952 } 903 953 904 954 // Holds the (continuously updated) remaining part of the dividend, which 905 955 // eventually becomes the remainder. 906 JSBigInt* u = absoluteLeftShiftAlwaysCopy(vm, dividend, shift, LeftShiftMode::AlwaysAddOneDigit); 956 JSBigInt* u = absoluteLeftShiftAlwaysCopy(exec, dividend, shift, LeftShiftMode::AlwaysAddOneDigit); 957 RETURN_IF_EXCEPTION(scope, void()); 907 958 908 959 // D2. … … 1032 1083 1033 1084 // Always copies the input, even when {shift} == 0. 1034 JSBigInt* JSBigInt::absoluteLeftShiftAlwaysCopy( VM& vm, JSBigInt* x, unsigned shift, LeftShiftMode mode)1085 JSBigInt* JSBigInt::absoluteLeftShiftAlwaysCopy(ExecState* exec, JSBigInt* x, unsigned shift, LeftShiftMode mode) 1035 1086 { 1036 1087 ASSERT(shift < digitBits); … … 1039 1090 unsigned n = x->length(); 1040 1091 unsigned resultLength = mode == LeftShiftMode::AlwaysAddOneDigit ? n + 1 : n; 1041 JSBigInt* result = createWithLength(vm, resultLength); 1092 JSBigInt* result = tryCreateWithLength(exec, resultLength); 1093 if (!result) 1094 return nullptr; 1042 1095 1043 1096 if (!shift) { … … 1096 1149 ASSERT(numPairs == std::min(xLength, yLength)); 1097 1150 unsigned resultLength = extraDigits == ExtraDigitsHandling::Copy ? xLength : numPairs; 1098 JSBigInt* result = createWithLength(vm, resultLength); 1099 1151 JSBigInt* result = createWithLengthUnchecked(vm, resultLength); 1100 1152 unsigned i = 0; 1101 1153 for (; i < numPairs; i++) … … 1145 1197 } 1146 1198 1147 JSBigInt* JSBigInt::absoluteAddOne( VM& vm, JSBigInt* x, SignOption signOption)1199 JSBigInt* JSBigInt::absoluteAddOne(ExecState* exec, JSBigInt* x, SignOption signOption) 1148 1200 { 1149 1201 unsigned inputLength = x->length(); … … 1159 1211 1160 1212 unsigned resultLength = inputLength + willOverflow; 1161 JSBigInt* result = createWithLength(vm, resultLength); 1213 JSBigInt* result = tryCreateWithLength(exec, resultLength); 1214 if (!result) 1215 return nullptr; 1162 1216 1163 1217 Digit carry = 1; … … 1173 1227 1174 1228 result->setSign(signOption == SignOption::Signed); 1175 return result->rightTrim(vm); 1176 } 1177 1178 // Like the above, but you can specify that the allocated result should have 1179 // length {resultLength}, which must be at least as large as {x->length()}. 1180 JSBigInt* JSBigInt::absoluteSubOne(VM& vm, JSBigInt* x, unsigned resultLength) 1229 return result->rightTrim(exec->vm()); 1230 } 1231 1232 JSBigInt* JSBigInt::absoluteSubOne(ExecState* exec, JSBigInt* x, unsigned resultLength) 1181 1233 { 1182 1234 ASSERT(!x->isZero()); 1183 1235 ASSERT(resultLength >= x->length()); 1184 JSBigInt* result = createWithLength(vm, resultLength); 1236 VM& vm = exec->vm(); 1237 auto scope = DECLARE_CATCH_SCOPE(vm); 1238 1239 JSBigInt* result = tryCreateWithLength(exec, resultLength); 1240 RETURN_IF_EXCEPTION(scope, nullptr); 1185 1241 1186 1242 unsigned length = x->length(); … … 1355 1411 Digit chunk; 1356 1412 absoluteDivWithDigitDivisor(vm, *dividend, chunkDivisor, &rest, chunk); 1357 ASSERT(rest);1358 1359 1413 dividend = &rest; 1360 1414 for (unsigned i = 0; i < chunkChars; i++) { … … 1415 1469 1416 1470 unsigned newLength = nonZeroIndex + 1; 1417 JSBigInt* trimmedBigInt = createWithLength(vm, newLength); 1418 RELEASE_ASSERT(trimmedBigInt); 1471 JSBigInt* trimmedBigInt = createWithLengthUnchecked(vm, newLength); 1419 1472 std::copy(dataStorage(), dataStorage() + newLength, trimmedBigInt->dataStorage()); 1420 1473 … … 1440 1493 unsigned length = (bitsMin + digitBits - 1) / digitBits; 1441 1494 if (length <= maxLength) { 1442 JSBigInt* result = JSBigInt::createWithLength (vm, length);1495 JSBigInt* result = JSBigInt::createWithLengthUnchecked(vm, length); 1443 1496 return result; 1444 1497 } -
trunk/Source/JavaScriptCore/runtime/JSBigInt.h
r237296 r238132 52 52 static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype); 53 53 static JSBigInt* createZero(VM&); 54 static JSBigInt* createWithLength(VM&, unsigned length); 54 static JSBigInt* tryCreateWithLength(ExecState*, unsigned length); 55 static JSBigInt* createWithLengthUnchecked(VM&, unsigned length); 55 56 56 57 static JSBigInt* createFrom(VM&, int32_t value); … … 109 110 ComparisonResult static compareToDouble(JSBigInt* x, double y); 110 111 111 static JSBigInt* add( VM&, JSBigInt* x, JSBigInt* y);112 static JSBigInt* sub( VM&, JSBigInt* x, JSBigInt* y);112 static JSBigInt* add(ExecState*, JSBigInt* x, JSBigInt* y); 113 static JSBigInt* sub(ExecState*, JSBigInt* x, JSBigInt* y); 113 114 static JSBigInt* divide(ExecState*, JSBigInt* x, JSBigInt* y); 114 115 static JSBigInt* remainder(ExecState*, JSBigInt* x, JSBigInt* y); 115 116 static JSBigInt* unaryMinus(VM&, JSBigInt* x); 116 117 117 static JSBigInt* bitwiseAnd( VM&, JSBigInt* x, JSBigInt* y);118 static JSBigInt* bitwiseOr( VM&, JSBigInt* x, JSBigInt* y);119 static JSBigInt* bitwiseXor( VM&, JSBigInt* x, JSBigInt* y);118 static JSBigInt* bitwiseAnd(ExecState*, JSBigInt* x, JSBigInt* y); 119 static JSBigInt* bitwiseOr(ExecState*, JSBigInt* x, JSBigInt* y); 120 static JSBigInt* bitwiseXor(ExecState*, JSBigInt* x, JSBigInt* y); 120 121 121 122 private: … … 140 141 static void internalMultiplyAdd(JSBigInt* source, Digit factor, Digit summand, unsigned, JSBigInt* result); 141 142 static void multiplyAccumulate(JSBigInt* multiplicand, Digit multiplier, JSBigInt* accumulator, unsigned accumulatorIndex); 142 static void absoluteDivWithBigIntDivisor( VM&, JSBigInt* dividend, JSBigInt* divisor, JSBigInt** quotient, JSBigInt** remainder);143 static void absoluteDivWithBigIntDivisor(ExecState*, JSBigInt* dividend, JSBigInt* divisor, JSBigInt** quotient, JSBigInt** remainder); 143 144 144 145 enum class LeftShiftMode { … … 147 148 }; 148 149 149 static JSBigInt* absoluteLeftShiftAlwaysCopy( VM&, JSBigInt* x, unsigned shift, LeftShiftMode);150 static JSBigInt* absoluteLeftShiftAlwaysCopy(ExecState*, JSBigInt* x, unsigned shift, LeftShiftMode); 150 151 static bool productGreaterThan(Digit factor1, Digit factor2, Digit high, Digit low); 151 152 … … 177 178 }; 178 179 179 static JSBigInt* absoluteAddOne( VM&, JSBigInt* x, SignOption);180 static JSBigInt* absoluteSubOne( VM&, JSBigInt* x, unsigned resultLength);180 static JSBigInt* absoluteAddOne(ExecState*, JSBigInt* x, SignOption); 181 static JSBigInt* absoluteSubOne(ExecState*, JSBigInt* x, unsigned resultLength); 181 182 182 183 // Digit arithmetic helpers. … … 204 205 205 206 void inplaceMultiplyAdd(Digit multiplier, Digit part); 206 static JSBigInt* absoluteAdd( VM&, JSBigInt* x, JSBigInt* y, bool resultSign);207 static JSBigInt* absoluteAdd(ExecState*, JSBigInt* x, JSBigInt* y, bool resultSign); 207 208 static JSBigInt* absoluteSub(VM&, JSBigInt* x, JSBigInt* y, bool resultSign); 208 209 -
trunk/Source/JavaScriptCore/runtime/Operations.cpp
r236697 r238132 70 70 71 71 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 72 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) 73 return JSBigInt::add(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 72 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 73 scope.release(); 74 return JSBigInt::add(callFrame, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 75 } 74 76 75 77 return throwTypeError(callFrame, scope, "Invalid mix of BigInt and other type in addition."_s); -
trunk/Source/JavaScriptCore/runtime/Operations.h
r236804 r238132 349 349 350 350 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 351 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) 352 return JSBigInt::sub(vm, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 351 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 352 scope.release(); 353 return JSBigInt::sub(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 354 } 353 355 354 356 return throwTypeError(exec, scope, "Invalid mix of BigInt and other type in subtraction."_s); … … 369 371 370 372 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 371 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) 373 if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { 374 scope.release(); 372 375 return JSBigInt::multiply(state, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); 376 } 373 377 374 378 throwTypeError(state, scope, "Invalid mix of BigInt and other type in multiplication."_s);
Note: See TracChangeset
for help on using the changeset viewer.