@@ -161,63 +161,69 @@ public PInt roundPIntNone(PInt arg, PNone n) {
161
161
}
162
162
163
163
@ Specialization
164
- public Object roundLongInt (long arg , int n ) {
164
+ public Object roundLongInt (long arg , int n ,
165
+ @ Shared ("intOvf" ) @ Cached BranchProfile intOverflow ) {
165
166
if (n >= 0 ) {
166
167
return arg ;
167
168
}
168
- return makeInt (op (arg , n ));
169
+ return makeInt (op (arg , n ), intOverflow );
169
170
}
170
171
171
172
@ Specialization
172
- public Object roundPIntInt (PInt arg , int n ) {
173
+ public Object roundPIntInt (PInt arg , int n ,
174
+ @ Shared ("intOvf" ) @ Cached BranchProfile intOverflow ) {
173
175
if (n >= 0 ) {
174
176
return arg ;
175
177
}
176
- return makeInt (op (arg .getValue (), n ));
178
+ return makeInt (op (arg .getValue (), n ), intOverflow );
177
179
}
178
180
179
181
@ Specialization
180
- public Object roundLongLong (long arg , long n ) {
182
+ public Object roundLongLong (long arg , long n ,
183
+ @ Shared ("intOvf" ) @ Cached BranchProfile intOverflow ) {
181
184
if (n >= 0 ) {
182
185
return arg ;
183
186
}
184
187
if (n < Integer .MIN_VALUE ) {
185
188
return 0 ;
186
189
}
187
- return makeInt (op (arg , (int ) n ));
190
+ return makeInt (op (arg , (int ) n ), intOverflow );
188
191
}
189
192
190
193
@ Specialization
191
- public Object roundPIntLong (PInt arg , long n ) {
194
+ public Object roundPIntLong (PInt arg , long n ,
195
+ @ Shared ("intOvf" ) @ Cached BranchProfile intOverflow ) {
192
196
if (n >= 0 ) {
193
197
return arg ;
194
198
}
195
199
if (n < Integer .MIN_VALUE ) {
196
200
return 0 ;
197
201
}
198
- return makeInt (op (arg .getValue (), (int ) n ));
202
+ return makeInt (op (arg .getValue (), (int ) n ), intOverflow );
199
203
}
200
204
201
205
@ Specialization
202
- public Object roundPIntLong (long arg , PInt n ) {
206
+ public Object roundPIntLong (long arg , PInt n ,
207
+ @ Shared ("intOvf" ) @ Cached BranchProfile intOverflow ) {
203
208
if (n .isZeroOrPositive ()) {
204
209
return arg ;
205
210
}
206
211
try {
207
- return makeInt (op (arg , n .intValueExact ()));
212
+ return makeInt (op (arg , n .intValueExact ()), intOverflow );
208
213
} catch (OverflowException e ) {
209
214
// n is < -2^31, max. number of base-10 digits in BigInteger is 2^31 * log10(2)
210
215
return 0 ;
211
216
}
212
217
}
213
218
214
219
@ Specialization
215
- public Object roundPIntPInt (PInt arg , PInt n ) {
220
+ public Object roundPIntPInt (PInt arg , PInt n ,
221
+ @ Shared ("intOvf" ) @ Cached BranchProfile intOverflow ) {
216
222
if (n .isZeroOrPositive ()) {
217
223
return arg ;
218
224
}
219
225
try {
220
- return makeInt (op (arg .getValue (), n .intValueExact ()));
226
+ return makeInt (op (arg .getValue (), n .intValueExact ()), intOverflow );
221
227
} catch (OverflowException e ) {
222
228
// n is < -2^31, max. number of base-10 digits in BigInteger is 2^31 * log10(2)
223
229
return 0 ;
@@ -230,33 +236,52 @@ public Object roundPIntPInt(Object arg, Object n) {
230
236
throw raise (PythonErrorType .TypeError , ErrorMessages .OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER , n );
231
237
}
232
238
233
- private Object makeInt (BigDecimal d ) {
239
+ private Object makeInt (BigDecimal d , BranchProfile intOverflow ) {
234
240
try {
235
241
return intValueExact (d );
236
- } catch (ArithmeticException e ) {
242
+ } catch (OverflowException e ) {
237
243
// does not fit int, so try long
244
+ intOverflow .enter ();
238
245
}
239
246
try {
240
247
return longValueExact (d );
241
- } catch (ArithmeticException e ) {
248
+ } catch (OverflowException e ) {
242
249
// does not fit long, try BigInteger
243
250
}
244
251
try {
245
- return factory ().createInt (d .toBigIntegerExact ());
246
- } catch (ArithmeticException e ) {
252
+ // lazy factory initialization should serve as branch profile
253
+ return factory ().createInt (toBigIntegerExact (d ));
254
+ } catch (OverflowException e ) {
247
255
// has non-zero fractional part, which should not happen
248
256
throw CompilerDirectives .shouldNotReachHere ("non-integer produced after rounding an integer" , e );
249
257
}
250
258
}
251
259
252
260
@ TruffleBoundary
253
- private static int intValueExact (BigDecimal d ) {
254
- return d .intValueExact ();
261
+ private static BigInteger toBigIntegerExact (BigDecimal d ) throws OverflowException {
262
+ try {
263
+ return d .toBigIntegerExact ();
264
+ } catch (ArithmeticException ex ) {
265
+ throw OverflowException .INSTANCE ;
266
+ }
267
+ }
268
+
269
+ @ TruffleBoundary
270
+ private static int intValueExact (BigDecimal d ) throws OverflowException {
271
+ try {
272
+ return d .intValueExact ();
273
+ } catch (ArithmeticException ex ) {
274
+ throw OverflowException .INSTANCE ;
275
+ }
255
276
}
256
277
257
278
@ TruffleBoundary
258
- private static long longValueExact (BigDecimal d ) {
259
- return d .longValueExact ();
279
+ private static long longValueExact (BigDecimal d ) throws OverflowException {
280
+ try {
281
+ return d .longValueExact ();
282
+ } catch (ArithmeticException ex ) {
283
+ throw OverflowException .INSTANCE ;
284
+ }
260
285
}
261
286
262
287
@ TruffleBoundary
@@ -1357,10 +1382,13 @@ Object doLLOvf(long left, long right) {
1357
1382
} catch (OverflowException e ) {
1358
1383
int rightI = (int ) right ;
1359
1384
if (rightI == right ) {
1360
- return factory ().createInt (op (PInt .longToBigInteger (left ), rightI ));
1361
- } else {
1362
- throw raise (PythonErrorType .OverflowError );
1385
+ try {
1386
+ return factory ().createInt (op (PInt .longToBigInteger (left ), rightI ));
1387
+ } catch (OverflowException ex ) {
1388
+ // fallback to the raise of overflow error
1389
+ }
1363
1390
}
1391
+ throw raise (PythonErrorType .OverflowError );
1364
1392
}
1365
1393
}
1366
1394
@@ -1392,7 +1420,7 @@ PInt doPiI(PInt left, int right) {
1392
1420
protected PInt doGuardedBiI (BigInteger left , int right ) {
1393
1421
try {
1394
1422
return factory ().createInt (op (left , right ));
1395
- } catch (ArithmeticException e ) {
1423
+ } catch (OverflowException e ) {
1396
1424
throw raise (PythonErrorType .OverflowError );
1397
1425
}
1398
1426
}
@@ -1432,8 +1460,12 @@ PNotImplemented doGeneric(Object a, Object b) {
1432
1460
}
1433
1461
1434
1462
@ TruffleBoundary
1435
- public static BigInteger op (BigInteger left , int right ) {
1436
- return left .shiftLeft (right );
1463
+ public static BigInteger op (BigInteger left , int right ) throws OverflowException {
1464
+ try {
1465
+ return left .shiftLeft (right );
1466
+ } catch (ArithmeticException ex ) {
1467
+ throw OverflowException .INSTANCE ;
1468
+ }
1437
1469
}
1438
1470
1439
1471
private void raiseNegativeShiftCount (boolean cond ) {
0 commit comments