Skip to content

Commit cf52b22

Browse files
committed
[GR-25992] Do not catch arithmetic exceptions in PE code when working with ranges and BigDecimals.
PullRequest: graalpython/1253
2 parents 54cd95b + ec969c7 commit cf52b22

File tree

7 files changed

+249
-107
lines changed

7 files changed

+249
-107
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
import com.oracle.graal.python.builtins.objects.range.PBigRange;
155155
import com.oracle.graal.python.builtins.objects.range.PIntRange;
156156
import com.oracle.graal.python.builtins.objects.range.RangeNodes;
157+
import com.oracle.graal.python.builtins.objects.range.RangeNodes.LenOfIntRangeNodeExact;
157158
import com.oracle.graal.python.builtins.objects.set.PFrozenSet;
158159
import com.oracle.graal.python.builtins.objects.set.PSet;
159160
import com.oracle.graal.python.builtins.objects.str.PString;
@@ -213,6 +214,7 @@
213214
import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage;
214215
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
215216
import com.oracle.graal.python.util.PythonUtils;
217+
import com.oracle.graal.python.util.OverflowException;
216218
import com.oracle.truffle.api.Assumption;
217219
import com.oracle.truffle.api.CompilerAsserts;
218220
import com.oracle.truffle.api.CompilerDirectives;
@@ -701,7 +703,7 @@ public PythonObject reversed(@SuppressWarnings("unused") Object cls, PIntRange r
701703
int lstart = range.getIntStart();
702704
int lstop = range.getIntStop();
703705
int lstep = range.getIntStep();
704-
int ulen = lenOfRangeNode.len(lstart, lstop, lstep);
706+
int ulen = lenOfRangeNode.executeInt(lstart, lstop, lstep);
705707
int new_stop = lstart - lstep;
706708
int new_start = new_stop + ulen * lstep;
707709

@@ -715,7 +717,7 @@ public PythonObject reversed(@SuppressWarnings("unused") Object cls, PBigRange r
715717
BigInteger lstart = range.getBigIntegerStart();
716718
BigInteger lstop = range.getBigIntegerStop();
717719
BigInteger lstep = range.getBigIntegerStep();
718-
BigInteger ulen = (BigInteger) lenOfRangeNode.execute(lstart, lstop, lstep);
720+
BigInteger ulen = lenOfRangeNode.execute(lstart, lstop, lstep);
719721

720722
BigInteger new_stop = lstart.subtract(lstep);
721723
BigInteger new_start = new_stop.add(ulen.multiply(lstep));
@@ -1649,9 +1651,9 @@ public abstract static class RangeNode extends PythonQuaternaryBuiltinNode {
16491651
Object doIntStop(Object cls, int stop, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone step,
16501652
@Shared("stepZeroProfile") @Cached ConditionProfile stepZeroProfile,
16511653
@Shared("exceptionProfile") @Cached BranchProfile exceptionProfile,
1652-
@Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode,
1654+
@Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact,
16531655
@Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode) {
1654-
return doInt(cls, 0, stop, 1, stepZeroProfile, exceptionProfile, lenOfRangeNode, createBigRangeNode);
1656+
return doInt(cls, 0, stop, 1, stepZeroProfile, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode);
16551657
}
16561658

16571659
@Specialization(guards = "isStop(start, stop, step)")
@@ -1665,21 +1667,21 @@ Object doPintStop(Object cls, PInt stop, @SuppressWarnings("unused") PNone start
16651667
Object doGenericStop(Object cls, Object stop, @SuppressWarnings("unused") PNone start, @SuppressWarnings("unused") PNone step,
16661668
@Shared("stepZeroProfile") @Cached ConditionProfile stepZeroProfile,
16671669
@Shared("exceptionProfile") @Cached BranchProfile exceptionProfile,
1668-
@Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode,
1670+
@Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact,
16691671
@Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode,
16701672
@Shared("polGeneric") @CachedLibrary(limit = "3") PythonObjectLibrary pol,
16711673
@Shared("libGeneric") @CachedLibrary(limit = "3") InteropLibrary lib) {
1672-
return doGeneric(cls, 0, stop, 1, stepZeroProfile, exceptionProfile, lenOfRangeNode, createBigRangeNode, pol, lib);
1674+
return doGeneric(cls, 0, stop, 1, stepZeroProfile, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, pol, lib);
16731675
}
16741676

16751677
// start stop
16761678
@Specialization(guards = "isStartStop(start, stop, step)")
16771679
Object doIntStartStop(Object cls, int start, int stop, @SuppressWarnings("unused") PNone step,
16781680
@Shared("stepZeroProfile") @Cached ConditionProfile stepZeroProfile,
16791681
@Shared("exceptionProfile") @Cached BranchProfile exceptionProfile,
1680-
@Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode,
1682+
@Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact,
16811683
@Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode) {
1682-
return doInt(cls, start, stop, 1, stepZeroProfile, exceptionProfile, lenOfRangeNode, createBigRangeNode);
1684+
return doInt(cls, start, stop, 1, stepZeroProfile, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode);
16831685
}
16841686

16851687
@Specialization(guards = "isStartStop(start, stop, step)")
@@ -1693,27 +1695,27 @@ Object doPintStartStop(Object cls, PInt start, PInt stop, @SuppressWarnings("unu
16931695
Object doGenericStartStop(Object cls, Object start, Object stop, @SuppressWarnings("unused") PNone step,
16941696
@Shared("stepZeroProfile") @Cached ConditionProfile stepZeroProfile,
16951697
@Shared("exceptionProfile") @Cached BranchProfile exceptionProfile,
1696-
@Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode,
1698+
@Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact,
16971699
@Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode,
16981700
@Shared("polGeneric") @CachedLibrary(limit = "3") PythonObjectLibrary pol,
16991701
@Shared("libGeneric") @CachedLibrary(limit = "3") InteropLibrary lib) {
1700-
return doGeneric(cls, start, stop, 1, stepZeroProfile, exceptionProfile, lenOfRangeNode, createBigRangeNode, pol, lib);
1702+
return doGeneric(cls, start, stop, 1, stepZeroProfile, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode, pol, lib);
17011703
}
17021704

17031705
// start stop step
17041706
@Specialization
17051707
Object doInt(@SuppressWarnings("unused") Object cls, int start, int stop, int step,
17061708
@Shared("stepZeroProfile") @Cached ConditionProfile stepZeroProfile,
17071709
@Shared("exceptionProfile") @Cached BranchProfile exceptionProfile,
1708-
@Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode,
1710+
@Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNode,
17091711
@Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode) {
17101712
if (stepZeroProfile.profile(step == 0)) {
17111713
throw raise(ValueError, ARG_MUST_NOT_BE_ZERO, "range()", 3);
17121714
}
17131715
try {
1714-
int len = lenOfRangeNode.len(start, stop, step);
1716+
int len = lenOfRangeNode.executeInt(start, stop, step);
17151717
return factory().createIntRange(start, stop, step, len);
1716-
} catch (ArithmeticException e) {
1718+
} catch (OverflowException e) {
17171719
exceptionProfile.enter();
17181720
return createBigRangeNode.execute(start, stop, step, factory());
17191721
}
@@ -1726,20 +1728,20 @@ Object doPint(@SuppressWarnings("unused") Object cls, PInt start, PInt stop, PIn
17261728
if (stepZeroProfile.profile(step.isZero())) {
17271729
throw raise(ValueError, ARG_MUST_NOT_BE_ZERO, "range()", 3);
17281730
}
1729-
BigInteger len = (BigInteger) lenOfRangeNode.execute(start, stop, step);
1731+
BigInteger len = lenOfRangeNode.execute(start.getValue(), stop.getValue(), step.getValue());
17301732
return factory().createBigRange(start, stop, step, factory().createInt(len));
17311733
}
17321734

17331735
@Specialization(guards = "isStartStopStep(start, stop, step)")
17341736
Object doGeneric(@SuppressWarnings("unused") Object cls, Object start, Object stop, Object step,
17351737
@Shared("stepZeroProfile") @Cached ConditionProfile stepZeroProfile,
17361738
@Shared("exceptionProfile") @Cached BranchProfile exceptionProfile,
1737-
@Shared("lenOfRangeNode") @Cached RangeNodes.LenOfRangeNode lenOfRangeNode,
1739+
@Shared("lenOfRangeNodeExact") @Cached LenOfIntRangeNodeExact lenOfRangeNodeExact,
17381740
@Shared("createBigRangeNode") @Cached RangeNodes.CreateBigRangeNode createBigRangeNode,
17391741
@Shared("polGeneric") @CachedLibrary(limit = "3") PythonObjectLibrary pol,
17401742
@Shared("libGeneric") @CachedLibrary(limit = "3") InteropLibrary lib) {
17411743
if (canBeInt(start, stop, step, lib)) {
1742-
return doInt(cls, pol.asSize(start), pol.asSize(stop), pol.asSize(step), stepZeroProfile, exceptionProfile, lenOfRangeNode, createBigRangeNode);
1744+
return doInt(cls, pol.asSize(start), pol.asSize(stop), pol.asSize(step), stepZeroProfile, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode);
17431745
} else if (canBePint(start, stop, step, pol)) {
17441746
return createBigRangeNode.execute(start, stop, step, factory());
17451747
} else {
@@ -1748,7 +1750,7 @@ Object doGeneric(@SuppressWarnings("unused") Object cls, Object start, Object st
17481750
Object lstep = pol.asIndex(step);
17491751

17501752
if (canBeInt(start, stop, step, lib)) {
1751-
return doInt(cls, pol.asSize(start), pol.asSize(stop), pol.asSize(step), stepZeroProfile, exceptionProfile, lenOfRangeNode, createBigRangeNode);
1753+
return doInt(cls, pol.asSize(start), pol.asSize(stop), pol.asSize(step), stepZeroProfile, exceptionProfile, lenOfRangeNodeExact, createBigRangeNode);
17521754
} else {
17531755
return createBigRangeNode.execute(lstart, lstop, lstep, factory());
17541756
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,10 @@
125125
import com.oracle.graal.python.nodes.subscript.SliceLiteralNode.ComputeIndices;
126126
import com.oracle.graal.python.nodes.util.CastToByteNode;
127127
import com.oracle.graal.python.nodes.util.CastToJavaByteNode;
128+
import com.oracle.graal.python.nodes.util.ExactMath;
128129
import com.oracle.graal.python.runtime.PythonContext;
129130
import com.oracle.graal.python.runtime.PythonOptions;
130131
import com.oracle.graal.python.runtime.exception.PException;
131-
import com.oracle.graal.python.runtime.exception.PythonErrorType;
132132
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
133133
import com.oracle.graal.python.runtime.sequence.PSequence;
134134
import com.oracle.graal.python.runtime.sequence.storage.BasicSequenceStorage;
@@ -2301,8 +2301,8 @@ public ExtendNode(GenNodeSupplier genNodeProvider) {
23012301

23022302
private static int lengthResult(int current, int ext) {
23032303
try {
2304-
return Math.addExact(current, ext);
2305-
} catch (ArithmeticException e) {
2304+
return ExactMath.addExact(current, ext);
2305+
} catch (OverflowException e) {
23062306
// (mq) There is no need to ensure capacity as we either
23072307
// run out of memory or dealing with a fake length.
23082308
return current;
@@ -2314,9 +2314,7 @@ SequenceStorage doWithStorage(SequenceStorage left, PSequence seq, int len,
23142314
@SuppressWarnings("unused") @CachedLibrary(limit = "3") PythonObjectLibrary lib,
23152315
@Cached GetSequenceStorageNode getStorageNode,
23162316
@Cached LenNode lenNode,
2317-
@Cached PRaiseNode raiseNode,
23182317
@Cached EnsureCapacityNode ensureCapacityNode,
2319-
@Cached BranchProfile overflowErrorProfile,
23202318
@Cached ConcatBaseNode concatStoragesNode) {
23212319
SequenceStorage right = getStorageNode.execute(seq);
23222320
int lenLeft = lenNode.execute(left);
@@ -2328,15 +2326,13 @@ SequenceStorage doWithStorage(SequenceStorage left, PSequence seq, int len,
23282326
}
23292327
SequenceStorage dest = null;
23302328
try {
2329+
// EnsureCapacityNode handles the overflow and raises an error
23312330
dest = ensureCapacityNode.execute(left, lenResult);
23322331
return concatStoragesNode.execute(dest, left, right);
23332332
} catch (SequenceStoreException e) {
23342333
dest = generalizeStore(dest, e.getIndicationValue());
23352334
dest = ensureCapacityNode.execute(dest, lenResult);
23362335
return concatStoragesNode.execute(dest, left, right);
2337-
} catch (ArithmeticException e) {
2338-
overflowErrorProfile.enter();
2339-
throw raiseNode.raise(PythonErrorType.OverflowError);
23402336
}
23412337
}
23422338

0 commit comments

Comments
 (0)