@@ -704,7 +704,9 @@ static long doLLFast(long left, long right, @SuppressWarnings("unused") PNone no
704
704
result = Math .multiplyExact (result , base );
705
705
}
706
706
exponent >>= 1 ;
707
- base = Math .multiplyExact (base , base );
707
+ if (exponent != 0 ) { // prevent overflow in last iteration
708
+ base = Math .multiplyExact (base , base );
709
+ }
708
710
}
709
711
return result ;
710
712
}
@@ -1313,15 +1315,13 @@ long doLL(long left, long right) {
1313
1315
}
1314
1316
1315
1317
@ Specialization
1316
- PInt doIPi (int left , PInt right ) {
1317
- raiseNegativeShiftCount (!right .isZeroOrPositive ());
1318
- return factory ().createInt (op (PInt .longToBigInteger (left ), right .intValue ()));
1318
+ Object doIPi (int left , PInt right ) {
1319
+ return doHugeShift (PInt .longToBigInteger (left ), right );
1319
1320
}
1320
1321
1321
1322
@ Specialization
1322
- PInt doLPi (long left , PInt right ) {
1323
- raiseNegativeShiftCount (!right .isZeroOrPositive ());
1324
- return factory ().createInt (op (PInt .longToBigInteger (left ), right .intValue ()));
1323
+ Object doLPi (long left , PInt right ) {
1324
+ return doHugeShift (PInt .longToBigInteger (left ), right );
1325
1325
}
1326
1326
1327
1327
@ Specialization
@@ -1331,15 +1331,20 @@ PInt doPiI(PInt left, int right) {
1331
1331
}
1332
1332
1333
1333
@ Specialization
1334
- PInt doPiL (PInt left , long right ) {
1334
+ Object doPiL (PInt left , long right ) {
1335
1335
raiseNegativeShiftCount (right < 0 );
1336
- return factory ().createInt (op (left .getValue (), (int ) right ));
1336
+ int rightI = (int ) right ;
1337
+ if (rightI == right ) {
1338
+ return factory ().createInt (op (left .getValue (), rightI ));
1339
+ }
1340
+ // right is >= 2**31, BigInteger's bitLength is at most 2**31-1
1341
+ // therefore the result of shifting right is just the sign bit
1342
+ return left .isNegative () ? -1 : 0 ;
1337
1343
}
1338
1344
1339
1345
@ Specialization
1340
- PInt doPInt (PInt left , PInt right ) {
1341
- raiseNegativeShiftCount (!right .isZeroOrPositive ());
1342
- return factory ().createInt (op (left .getValue (), right .intValue ()));
1346
+ Object doPInt (PInt left , PInt right ) {
1347
+ return doHugeShift (left .getValue (), right );
1343
1348
}
1344
1349
1345
1350
private void raiseNegativeShiftCount (boolean cond ) {
@@ -1354,8 +1359,19 @@ PNotImplemented doGeneric(Object a, Object b) {
1354
1359
return PNotImplemented .NOT_IMPLEMENTED ;
1355
1360
}
1356
1361
1362
+ private Object doHugeShift (BigInteger left , PInt right ) {
1363
+ raiseNegativeShiftCount (!right .isZeroOrPositive ());
1364
+ try {
1365
+ return factory ().createInt (op (left , right .intValueExact ()));
1366
+ } catch (ArithmeticException e ) {
1367
+ // right is >= 2**31, BigInteger's bitLength is at most 2**31-1
1368
+ // therefore the result of shifting right is just the sign bit
1369
+ return left .signum () < 0 ? -1 : 0 ;
1370
+ }
1371
+ }
1372
+
1357
1373
@ TruffleBoundary
1358
- public static BigInteger op (BigInteger left , int right ) {
1374
+ private static BigInteger op (BigInteger left , int right ) {
1359
1375
return left .shiftRight (right );
1360
1376
}
1361
1377
0 commit comments