Skip to content

Commit be77d44

Browse files
committed
IntBuiltins: do not catch ArithmeticException in PE code when using BigDecimal
1 parent e42db99 commit be77d44

File tree

1 file changed

+59
-27
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints

1 file changed

+59
-27
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntBuiltins.java

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -161,63 +161,69 @@ public PInt roundPIntNone(PInt arg, PNone n) {
161161
}
162162

163163
@Specialization
164-
public Object roundLongInt(long arg, int n) {
164+
public Object roundLongInt(long arg, int n,
165+
@Shared("intOvf") @Cached BranchProfile intOverflow) {
165166
if (n >= 0) {
166167
return arg;
167168
}
168-
return makeInt(op(arg, n));
169+
return makeInt(op(arg, n), intOverflow);
169170
}
170171

171172
@Specialization
172-
public Object roundPIntInt(PInt arg, int n) {
173+
public Object roundPIntInt(PInt arg, int n,
174+
@Shared("intOvf") @Cached BranchProfile intOverflow) {
173175
if (n >= 0) {
174176
return arg;
175177
}
176-
return makeInt(op(arg.getValue(), n));
178+
return makeInt(op(arg.getValue(), n), intOverflow);
177179
}
178180

179181
@Specialization
180-
public Object roundLongLong(long arg, long n) {
182+
public Object roundLongLong(long arg, long n,
183+
@Shared("intOvf") @Cached BranchProfile intOverflow) {
181184
if (n >= 0) {
182185
return arg;
183186
}
184187
if (n < Integer.MIN_VALUE) {
185188
return 0;
186189
}
187-
return makeInt(op(arg, (int) n));
190+
return makeInt(op(arg, (int) n), intOverflow);
188191
}
189192

190193
@Specialization
191-
public Object roundPIntLong(PInt arg, long n) {
194+
public Object roundPIntLong(PInt arg, long n,
195+
@Shared("intOvf") @Cached BranchProfile intOverflow) {
192196
if (n >= 0) {
193197
return arg;
194198
}
195199
if (n < Integer.MIN_VALUE) {
196200
return 0;
197201
}
198-
return makeInt(op(arg.getValue(), (int) n));
202+
return makeInt(op(arg.getValue(), (int) n), intOverflow);
199203
}
200204

201205
@Specialization
202-
public Object roundPIntLong(long arg, PInt n) {
206+
public Object roundPIntLong(long arg, PInt n,
207+
@Shared("intOvf") @Cached BranchProfile intOverflow) {
203208
if (n.isZeroOrPositive()) {
204209
return arg;
205210
}
206211
try {
207-
return makeInt(op(arg, n.intValueExact()));
212+
return makeInt(op(arg, n.intValueExact()), intOverflow);
208213
} catch (OverflowException e) {
209214
// n is < -2^31, max. number of base-10 digits in BigInteger is 2^31 * log10(2)
210215
return 0;
211216
}
212217
}
213218

214219
@Specialization
215-
public Object roundPIntPInt(PInt arg, PInt n) {
220+
public Object roundPIntPInt(PInt arg, PInt n,
221+
@Shared("intOvf") @Cached BranchProfile intOverflow) {
216222
if (n.isZeroOrPositive()) {
217223
return arg;
218224
}
219225
try {
220-
return makeInt(op(arg.getValue(), n.intValueExact()));
226+
return makeInt(op(arg.getValue(), n.intValueExact()), intOverflow);
221227
} catch (OverflowException e) {
222228
// n is < -2^31, max. number of base-10 digits in BigInteger is 2^31 * log10(2)
223229
return 0;
@@ -230,33 +236,52 @@ public Object roundPIntPInt(Object arg, Object n) {
230236
throw raise(PythonErrorType.TypeError, ErrorMessages.OBJ_CANNOT_BE_INTERPRETED_AS_INTEGER, n);
231237
}
232238

233-
private Object makeInt(BigDecimal d) {
239+
private Object makeInt(BigDecimal d, BranchProfile intOverflow) {
234240
try {
235241
return intValueExact(d);
236-
} catch (ArithmeticException e) {
242+
} catch (OverflowException e) {
237243
// does not fit int, so try long
244+
intOverflow.enter();
238245
}
239246
try {
240247
return longValueExact(d);
241-
} catch (ArithmeticException e) {
248+
} catch (OverflowException e) {
242249
// does not fit long, try BigInteger
243250
}
244251
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) {
247255
// has non-zero fractional part, which should not happen
248256
throw CompilerDirectives.shouldNotReachHere("non-integer produced after rounding an integer", e);
249257
}
250258
}
251259

252260
@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+
}
255276
}
256277

257278
@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+
}
260285
}
261286

262287
@TruffleBoundary
@@ -1357,10 +1382,13 @@ Object doLLOvf(long left, long right) {
13571382
} catch (OverflowException e) {
13581383
int rightI = (int) right;
13591384
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+
}
13631390
}
1391+
throw raise(PythonErrorType.OverflowError);
13641392
}
13651393
}
13661394

@@ -1392,7 +1420,7 @@ PInt doPiI(PInt left, int right) {
13921420
protected PInt doGuardedBiI(BigInteger left, int right) {
13931421
try {
13941422
return factory().createInt(op(left, right));
1395-
} catch (ArithmeticException e) {
1423+
} catch (OverflowException e) {
13961424
throw raise(PythonErrorType.OverflowError);
13971425
}
13981426
}
@@ -1432,8 +1460,12 @@ PNotImplemented doGeneric(Object a, Object b) {
14321460
}
14331461

14341462
@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+
}
14371469
}
14381470

14391471
private void raiseNegativeShiftCount(boolean cond) {

0 commit comments

Comments
 (0)