@@ -163,18 +163,24 @@ long addLong(long left, long right) {
163
163
}
164
164
165
165
@ Specialization
166
- PInt addPInt (long left , long right ) {
167
- return factory ().createInt (op (BigInteger .valueOf (left ), BigInteger .valueOf (right )));
166
+ Object addLongWithOverflow (long x , long y ) {
167
+ /* Inlined version of Math.addExact(x, y) with BigInteger fallback. */
168
+ long r = x + y ;
169
+ // HD 2-12 Overflow iff both arguments have the opposite sign of the result
170
+ if (((x ^ r ) & (y ^ r )) < 0 ) {
171
+ return factory ().createInt (op (PInt .longToBigInteger (x ), PInt .longToBigInteger (y )));
172
+ }
173
+ return r ;
168
174
}
169
175
170
176
@ Specialization
171
177
PInt add (PInt left , long right ) {
172
- return add ( left , factory ().createInt (right ));
178
+ return factory ().createInt (op ( left . getValue (), PInt . longToBigInteger ( right ) ));
173
179
}
174
180
175
181
@ Specialization
176
182
PInt add (long left , PInt right ) {
177
- return add ( factory ().createInt (left ), right );
183
+ return factory ().createInt (op ( PInt . longToBigInteger ( left ), right . getValue ()) );
178
184
}
179
185
180
186
@ Specialization
@@ -220,18 +226,25 @@ long doLL(long x, long y) throws ArithmeticException {
220
226
}
221
227
222
228
@ Specialization
223
- PInt doLLOvf (long x , long y ) {
224
- return factory ().createInt (op (BigInteger .valueOf (x ), BigInteger .valueOf (y )));
229
+ Object doLongWithOverflow (long x , long y ) {
230
+ /* Inlined version of Math.subtractExact(x, y) with BigInteger fallback. */
231
+ long r = x - y ;
232
+ // HD 2-12 Overflow iff the arguments have different signs and
233
+ // the sign of the result is different than the sign of x
234
+ if (((x ^ y ) & (x ^ r )) < 0 ) {
235
+ return factory ().createInt (op (PInt .longToBigInteger (x ), PInt .longToBigInteger (y )));
236
+ }
237
+ return r ;
225
238
}
226
239
227
240
@ Specialization
228
241
PInt doPIntLong (PInt left , long right ) {
229
- return doPIntPInt ( left , factory ().createInt (right ));
242
+ return factory ().createInt (op ( left . getValue (), PInt . longToBigInteger ( right ) ));
230
243
}
231
244
232
245
@ Specialization
233
246
PInt doLongPInt (long left , PInt right ) {
234
- return doPIntPInt ( factory ().createInt (left ), right );
247
+ return factory ().createInt (op ( PInt . longToBigInteger ( left ), right . getValue ()) );
235
248
}
236
249
237
250
@ Specialization
@@ -272,18 +285,25 @@ long doLL(long y, long x) throws ArithmeticException {
272
285
}
273
286
274
287
@ Specialization
275
- PInt doLLOvf (long y , long x ) {
276
- return factory ().createInt (op (BigInteger .valueOf (x ), BigInteger .valueOf (y )));
288
+ Object doLongWithOverflow (long y , long x ) {
289
+ /* Inlined version of Math.subtractExact(x, y) with BigInteger fallback. */
290
+ long r = x - y ;
291
+ // HD 2-12 Overflow iff the arguments have different signs and
292
+ // the sign of the result is different than the sign of x
293
+ if (((x ^ y ) & (x ^ r )) < 0 ) {
294
+ return factory ().createInt (op (PInt .longToBigInteger (x ), PInt .longToBigInteger (y )));
295
+ }
296
+ return r ;
277
297
}
278
298
279
299
@ Specialization
280
300
PInt doPIntLong (PInt right , long left ) {
281
- return doPIntPInt ( factory ().createInt (left ), right );
301
+ return factory ().createInt (op ( PInt . longToBigInteger ( left ), right . getValue ()) );
282
302
}
283
303
284
304
@ Specialization
285
305
PInt doLongPInt (long right , PInt left ) {
286
- return doPIntPInt ( factory ().createInt (right ), left );
306
+ return factory ().createInt (op ( PInt . longToBigInteger ( right ), left . getValue ()) );
287
307
}
288
308
289
309
@ Specialization
@@ -327,15 +347,18 @@ public abstract static class TrueDivNode extends PythonBinaryBuiltinNode {
327
347
328
348
@ Specialization
329
349
double doPI (long left , PInt right ) {
330
- return doPP (factory ().createInt (left ), right );
350
+ if (right .isZero ()) {
351
+ throw raise (PythonErrorType .ZeroDivisionError , "division by zero" );
352
+ }
353
+ return op (PInt .longToBigInteger (left ), right .getValue ());
331
354
}
332
355
333
356
@ Specialization
334
357
double doPL (PInt left , long right ) {
335
358
if (right == 0 ) {
336
359
throw raise (PythonErrorType .ZeroDivisionError , "division by zero" );
337
360
}
338
- return doPP (left , factory (). createInt (right ));
361
+ return op (left . getValue (), PInt . longToBigInteger (right ));
339
362
}
340
363
341
364
@ Specialization
@@ -391,7 +414,10 @@ public abstract static class RTrueDivNode extends PythonBinaryBuiltinNode {
391
414
392
415
@ Specialization
393
416
double doPL (PInt right , long left ) {
394
- return doPP (right , factory ().createInt (left ));
417
+ if (right .isZero ()) {
418
+ throw raise (PythonErrorType .ZeroDivisionError , "division by zero" );
419
+ }
420
+ return op (PInt .longToBigInteger (left ), right .getValue ());
395
421
}
396
422
397
423
@ Specialization
@@ -477,13 +503,13 @@ long doLPiOvf(long left, PInt right) {
477
503
@ Specialization
478
504
PInt doPiL (PInt left , int right ) {
479
505
raiseDivisionByZero (right == 0 );
480
- return factory ().createInt (op (left .getValue (), BigInteger . valueOf (right )));
506
+ return factory ().createInt (op (left .getValue (), PInt . longToBigInteger (right )));
481
507
}
482
508
483
509
@ Specialization
484
510
PInt doPiL (PInt left , long right ) {
485
511
raiseDivisionByZero (right == 0 );
486
- return factory ().createInt (op (left .getValue (), BigInteger . valueOf (right )));
512
+ return factory ().createInt (op (left .getValue (), PInt . longToBigInteger (right )));
487
513
}
488
514
489
515
@ Specialization
@@ -530,13 +556,13 @@ long doLL(long right, long left) {
530
556
@ Specialization
531
557
PInt doPiL (PInt right , long left ) {
532
558
raiseDivisionByZero (right .isZero ());
533
- return factory ().createInt (op (BigInteger . valueOf (left ), right .getValue ()));
559
+ return factory ().createInt (op (PInt . longToBigInteger (left ), right .getValue ()));
534
560
}
535
561
536
562
@ Specialization
537
563
PInt doLPi (long right , PInt left ) {
538
564
raiseDivisionByZero (right == 0 );
539
- return factory ().createInt (op (left .getValue (), BigInteger . valueOf (right )));
565
+ return factory ().createInt (op (left .getValue (), PInt . longToBigInteger (right )));
540
566
}
541
567
542
568
@ Specialization
@@ -576,13 +602,13 @@ long doLL(long left, long right) {
576
602
@ Specialization
577
603
PInt doLPi (long left , PInt right ) {
578
604
raiseDivisionByZero (right .isZero ());
579
- return factory ().createInt (op (BigInteger . valueOf (left ), right .getValue ()));
605
+ return factory ().createInt (op (PInt . longToBigInteger (left ), right .getValue ()));
580
606
}
581
607
582
608
@ Specialization (guards = "right >= 0" )
583
609
PInt doPiL (PInt left , long right ) {
584
610
raiseDivisionByZero (right == 0 );
585
- return factory ().createInt (op (left .getValue (), BigInteger . valueOf (right )));
611
+ return factory ().createInt (op (left .getValue (), PInt . longToBigInteger (right )));
586
612
}
587
613
588
614
@ Specialization (guards = "right.isZeroOrPositive()" )
@@ -593,7 +619,7 @@ PInt doPiPi(PInt left, PInt right) {
593
619
594
620
@ Specialization (guards = "right < 0" )
595
621
PInt doPiLNeg (PInt left , long right ) {
596
- return factory ().createInt (opNeg (left .getValue (), BigInteger . valueOf (right )));
622
+ return factory ().createInt (opNeg (left .getValue (), PInt . longToBigInteger (right )));
597
623
}
598
624
599
625
@ Specialization (guards = "!right.isZeroOrPositive()" )
@@ -642,17 +668,21 @@ long doLL(long x, long y) {
642
668
}
643
669
644
670
@ Specialization
645
- PInt doLLOvf (long x , long y ) {
671
+ Object doLongWithOverflow (long x , long y ) {
672
+ /* Inlined version of Math.multiplyExact(x, y) with BigInteger fallback. */
646
673
long r = x * y ;
647
674
long ax = Math .abs (x );
648
675
long ay = Math .abs (y );
649
676
if (((ax | ay ) >>> 31 != 0 )) {
650
- int leadingZeros = Long .numberOfLeadingZeros (ax ) + Long .numberOfLeadingZeros (ay );
651
- if (leadingZeros < 66 ) {
652
- return factory ().createInt (mul (BigInteger .valueOf (x ), BigInteger .valueOf (y )));
677
+ // Some bits greater than 2^31 that might cause overflow
678
+ // Check the result using the divide operator
679
+ // and check for the special case of Long.MIN_VALUE * -1
680
+ if (((y != 0 ) && (r / y != x )) ||
681
+ (x == Long .MIN_VALUE && y == -1 )) {
682
+ return factory ().createInt (mul (PInt .longToBigInteger (x ), PInt .longToBigInteger (y )));
653
683
}
654
684
}
655
- return factory (). createInt ( r ) ;
685
+ return r ;
656
686
}
657
687
658
688
@ Specialization (guards = "right == 0" )
@@ -668,7 +698,7 @@ PInt doPIntLongOne(PInt left, @SuppressWarnings("unused") long right) {
668
698
669
699
@ Specialization (guards = {"right != 0" , "right != 1" })
670
700
PInt doPIntLong (PInt left , long right ) {
671
- return factory ().createInt (mul (left .getValue (), BigInteger . valueOf (right )));
701
+ return factory ().createInt (mul (left .getValue (), PInt . longToBigInteger (right )));
672
702
}
673
703
674
704
@ Specialization
@@ -733,7 +763,7 @@ int doIntegerFast(int left, int right, @SuppressWarnings("unused") PNone none) {
733
763
734
764
@ Specialization (guards = "right >= 0" )
735
765
PInt doInteger (int left , int right , @ SuppressWarnings ("unused" ) PNone none ) {
736
- return factory ().createInt (op (BigInteger . valueOf (left ), right ));
766
+ return factory ().createInt (op (PInt . longToBigInteger (left ), right ));
737
767
}
738
768
739
769
@ Specialization (guards = "right >= 0" , rewriteOn = ArithmeticException .class )
@@ -773,7 +803,7 @@ long doLongFast(long left, long right, @SuppressWarnings("unused") PNone none) {
773
803
774
804
@ Specialization (guards = "right >= 0" )
775
805
PInt doLong (long left , long right , @ SuppressWarnings ("unused" ) PNone none ) {
776
- return factory ().createInt (op (BigInteger . valueOf (left ), right ));
806
+ return factory ().createInt (op (PInt . longToBigInteger (left ), right ));
777
807
}
778
808
779
809
@ Specialization
@@ -839,7 +869,7 @@ private BigInteger op(BigInteger a, long b) {
839
869
} else if (value == 1 ) {
840
870
return BigInteger .ONE ;
841
871
} else if (value == -1 ) {
842
- return (b & 1 ) != 0 ? BigInteger . valueOf (-1 ) : BigInteger .ONE ;
872
+ return (b & 1 ) != 0 ? PInt . longToBigInteger (-1 ) : BigInteger .ONE ;
843
873
}
844
874
} catch (ArithmeticException e ) {
845
875
// fall through to normal computation
@@ -888,9 +918,9 @@ long pos(long arg) {
888
918
PInt posOvf (long arg ) throws IllegalArgumentException {
889
919
long result = Math .abs (arg );
890
920
if (result < 0 ) {
891
- return factory ().createInt (op (BigInteger . valueOf (arg )));
921
+ return factory ().createInt (op (PInt . longToBigInteger (arg )));
892
922
} else {
893
- return factory ().createInt (BigInteger . valueOf (arg ));
923
+ return factory ().createInt (PInt . longToBigInteger (arg ));
894
924
}
895
925
}
896
926
@@ -986,7 +1016,7 @@ long neg(long arg) {
986
1016
987
1017
@ Specialization
988
1018
PInt negOvf (long arg ) {
989
- BigInteger value = arg == Long .MIN_VALUE ? negate (BigInteger . valueOf (arg )) : BigInteger . valueOf (-arg );
1019
+ BigInteger value = arg == Long .MIN_VALUE ? negate (PInt . longToBigInteger (arg )) : PInt . longToBigInteger (-arg );
990
1020
return factory ().createInt (value );
991
1021
}
992
1022
@@ -1084,7 +1114,7 @@ Object doIIOvf(int left, int right) {
1084
1114
try {
1085
1115
return leftShiftExact (left , right );
1086
1116
} catch (ArithmeticException e ) {
1087
- return doGuardedBiI (BigInteger . valueOf (left ), right );
1117
+ return doGuardedBiI (PInt . longToBigInteger (left ), right );
1088
1118
}
1089
1119
}
1090
1120
@@ -1102,7 +1132,7 @@ Object doLLOvf(long left, long right) {
1102
1132
} catch (ArithmeticException e ) {
1103
1133
int rightI = (int ) right ;
1104
1134
if (rightI == right ) {
1105
- return factory ().createInt (op (BigInteger . valueOf (left ), rightI ));
1135
+ return factory ().createInt (op (PInt . longToBigInteger (left ), rightI ));
1106
1136
} else {
1107
1137
throw raise (PythonErrorType .OverflowError );
1108
1138
}
@@ -1113,7 +1143,7 @@ Object doLLOvf(long left, long right) {
1113
1143
PInt doLPi (long left , PInt right ) {
1114
1144
raiseNegativeShiftCount (!right .isZeroOrPositive ());
1115
1145
try {
1116
- return factory ().createInt (op (BigInteger . valueOf (left ), right .intValue ()));
1146
+ return factory ().createInt (op (PInt . longToBigInteger (left ), right .intValue ()));
1117
1147
} catch (ArithmeticException e ) {
1118
1148
throw raise (PythonErrorType .OverflowError );
1119
1149
}
@@ -1191,13 +1221,13 @@ long doLL(long left, long right) {
1191
1221
@ Specialization
1192
1222
PInt doIPi (int left , PInt right ) {
1193
1223
raiseNegativeShiftCount (!right .isZeroOrPositive ());
1194
- return factory ().createInt (op (BigInteger . valueOf (left ), right .intValue ()));
1224
+ return factory ().createInt (op (PInt . longToBigInteger (left ), right .intValue ()));
1195
1225
}
1196
1226
1197
1227
@ Specialization
1198
1228
PInt doLPi (long left , PInt right ) {
1199
1229
raiseNegativeShiftCount (!right .isZeroOrPositive ());
1200
- return factory ().createInt (op (BigInteger . valueOf (left ), right .intValue ()));
1230
+ return factory ().createInt (op (PInt . longToBigInteger (left ), right .intValue ()));
1201
1231
}
1202
1232
1203
1233
@ Specialization
@@ -1266,12 +1296,12 @@ long doInteger(long left, long right) {
1266
1296
1267
1297
@ Specialization
1268
1298
PInt doPInt (long left , PInt right ) {
1269
- return factory ().createInt (op (BigInteger . valueOf (left ), right .getValue ()));
1299
+ return factory ().createInt (op (PInt . longToBigInteger (left ), right .getValue ()));
1270
1300
}
1271
1301
1272
1302
@ Specialization
1273
1303
PInt doPInt (PInt left , long right ) {
1274
- return factory ().createInt (op (left .getValue (), BigInteger . valueOf (right )));
1304
+ return factory ().createInt (op (left .getValue (), PInt . longToBigInteger (right )));
1275
1305
}
1276
1306
1277
1307
@ Specialization
@@ -1449,10 +1479,10 @@ boolean eqVoidPtrPInt(PythonNativeVoidPtr a, PInt b,
1449
1479
long ptrVal = lib .asPointer (a .object );
1450
1480
if (ptrVal < 0 ) {
1451
1481
// pointers are considered unsigned
1452
- BigInteger bi = BigInteger . valueOf (ptrVal ).add (BigInteger .ONE .shiftLeft (64 ));
1482
+ BigInteger bi = PInt . longToBigInteger (ptrVal ).add (BigInteger .ONE .shiftLeft (64 ));
1453
1483
return bi .equals (b .getValue ());
1454
1484
}
1455
- return BigInteger . valueOf (ptrVal ).equals (b .getValue ());
1485
+ return PInt . longToBigInteger (ptrVal ).equals (b .getValue ());
1456
1486
} catch (UnsupportedMessageException e ) {
1457
1487
// fall through
1458
1488
}
0 commit comments