Skip to content

Commit fd8706a

Browse files
committed
make asIndex method closer to PyNumber_AsSsize_t by passing in the error type in case of overflow
1 parent 65b0f0f commit fd8706a

File tree

8 files changed

+53
-35
lines changed

8 files changed

+53
-35
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -709,12 +709,13 @@ public final boolean canBeIndex(@Exclusive @Cached HasInheritedAttributeNode.Dyn
709709
}
710710

711711
@ExportMessage
712-
public int asIndexWithState(ThreadState state,
712+
public int asIndexWithState(LazyPythonClass type, ThreadState state,
713713
@Exclusive @Cached("createBinaryProfile()") ConditionProfile wasPInt,
714714
@Exclusive @Cached("createBinaryProfile()") ConditionProfile gotState,
715715
@Exclusive @Cached("createBinaryProfile()") ConditionProfile noIndex,
716716
@Exclusive @Cached LookupInheritedAttributeNode.Dynamic lookupIndex,
717717
@Exclusive @Cached BranchProfile overflow,
718+
@Exclusive @Cached("createBinaryProfile()") ConditionProfile ignoreOverflow,
718719
@Exclusive @Cached PRaiseNode raise,
719720
@Exclusive @Cached CallNode callNode,
720721
@Exclusive @Cached CastToJavaLongNode castToLong) {
@@ -725,21 +726,34 @@ public int asIndexWithState(ThreadState state,
725726
} else {
726727
Object indexAttr = lookupIndex.execute(this, __INDEX__);
727728
if (noIndex.profile(indexAttr == PNone.NO_VALUE)) {
728-
throw raise.raise(PythonBuiltinClassType.TypeError, "'%p' object cannot be interpreted as an integer", this);
729+
throw raise.raiseIntegerInterpretationError(this);
729730
}
730731
if (gotState.profile(state == null)) {
731732
result = callNode.execute(indexAttr, this);
732733
} else {
733734
result = callNode.execute(PArguments.frameForCall(state), indexAttr, this);
734735
}
735736
}
737+
long longResult;
736738
try {
737-
return PInt.intValueExact(castToLong.execute(result));
739+
longResult = castToLong.execute(result); // this is a lossy cast
738740
} catch (CastToJavaLongNode.CannotCastException e) {
739741
throw raise.raise(PythonBuiltinClassType.TypeError, "__index__ returned non-int (type %p)", result);
742+
}
743+
try {
744+
return PInt.intValueExact(longResult);
740745
} catch (ArithmeticException e) {
741746
overflow.enter();
742-
throw raise.raise(PythonBuiltinClassType.OverflowError, "cannot fit '%p' into an index-sized integer", result);
747+
if (ignoreOverflow.profile(type != null)) {
748+
throw raise.raiseIndexError(type, result);
749+
} else {
750+
// If no error-handling desired then the default clipping is done as in CPython.
751+
if (longResult < 0) {
752+
return Integer.MIN_VALUE;
753+
} else {
754+
return Integer.MAX_VALUE;
755+
}
756+
}
743757
}
744758
}
745759

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ int doLongOvf(long index, int length, String errorMessage,
213213
try {
214214
return doLong(index, length, errorMessage, negativeIndexProfile, boundsCheckNode);
215215
} catch (ArithmeticException e) {
216-
throw raiseNode.raiseIndexError();
216+
throw raiseNode.raiseIndexError(PythonBuiltinClassType.IndexError, index);
217217
}
218218
}
219219

@@ -233,7 +233,7 @@ int doPIntOvf(PInt index, int length, String errorMessage,
233233
try {
234234
return doPInt(index, length, errorMessage, negativeIndexProfile, boundsCheckNode);
235235
} catch (ArithmeticException e) {
236-
throw raiseNode.raiseIndexError();
236+
throw raiseNode.raiseIndexError(PythonBuiltinClassType.IndexError, index);
237237
}
238238
}
239239

@@ -272,7 +272,7 @@ int doLongOvf(long index, int length, String errorMessage,
272272
try {
273273
return doLong(index, length, errorMessage, negativeIndexProfile);
274274
} catch (ArithmeticException e) {
275-
throw raiseNode.raiseIndexError();
275+
throw raiseNode.raiseIndexError(PythonBuiltinClassType.IndexError, index);
276276
}
277277
}
278278

@@ -290,7 +290,7 @@ int doPIntOvf(PInt index, int length, String errorMessage,
290290
try {
291291
return doPInt(index, length, errorMessage, negativeIndexProfile);
292292
} catch (ArithmeticException e) {
293-
throw raiseNode.raiseIndexError();
293+
throw raiseNode.raiseIndexError(PythonBuiltinClassType.IndexError, index);
294294
}
295295
}
296296
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/DefaultPythonBooleanExports.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static boolean canBeIndex(@SuppressWarnings("unused") Boolean value) {
5353
}
5454

5555
@ExportMessage
56-
static int asIndex(Boolean value) {
56+
static int asIndex(Boolean value, @SuppressWarnings("unused") LazyPythonClass errorType) {
5757
return value ? 1 : 0;
5858
}
5959

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/DefaultPythonIntegerExports.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ static boolean canBeIndex(@SuppressWarnings("unused") Integer value) {
5858
}
5959

6060
@ExportMessage
61-
static int asIndex(Integer value) {
61+
static int asIndex(Integer value, @SuppressWarnings("unused") LazyPythonClass errorType) {
6262
return value;
6363
}
6464

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/DefaultPythonLongExports.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,17 @@ static boolean canBeIndex(@SuppressWarnings("unused") Long value) {
6464
@ExportMessage
6565
static class AsIndex {
6666
@Specialization(rewriteOn = ArithmeticException.class)
67-
static int noOverflow(Long self) {
67+
static int noOverflow(Long self, @SuppressWarnings("unused") LazyPythonClass type) {
6868
return PInt.intValueExact(self);
6969
}
7070

7171
@Specialization(replaces = "noOverflow")
72-
static int withOverflow(Long self,
72+
static int withOverflow(Long self, LazyPythonClass type,
7373
@Cached PRaiseNode raise) {
7474
try {
7575
return PInt.intValueExact(self);
7676
} catch (ArithmeticException e) {
77-
throw raise.raise(PythonBuiltinClassType.OverflowError, "cannot fit '%p' into an index-sized integer", self);
77+
throw raise.raiseIndexError(type, self);
7878
}
7979
}
8080
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/DefaultPythonStringExports.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,7 @@
4242

4343
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4444
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
45-
import com.oracle.graal.python.nodes.PRaiseNode;
4645
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
47-
import com.oracle.truffle.api.dsl.Cached;
4846
import com.oracle.truffle.api.library.ExportLibrary;
4947
import com.oracle.truffle.api.library.ExportMessage;
5048

@@ -86,10 +84,4 @@ static byte[] getBufferBytes(String str) {
8684
static long hash(String self) {
8785
return self.hashCode();
8886
}
89-
90-
@ExportMessage
91-
static int asIndex(String self,
92-
@Cached PRaiseNode raise) {
93-
throw raise.raise(PythonBuiltinClassType.TypeError, "'%p' object cannot be interpreted as an integer", self);
94-
}
9587
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObjectLibrary.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -238,23 +238,32 @@ public boolean canBeIndex(Object receiver) {
238238
* </ol>
239239
* @return <code>-1</code> if the cast fails or overflows the <code>int</code> range
240240
*/
241-
public int asIndexWithState(Object receiver, ThreadState threadState) {
241+
public int asIndexWithState(Object receiver, LazyPythonClass errorType, ThreadState threadState) {
242242
if (threadState == null) {
243-
throw new AbstractMethodError();
243+
throw PRaiseNode.getUncached().raiseIntegerInterpretationError(receiver);
244244
}
245-
return asIndex(receiver);
245+
return asIndex(receiver, errorType);
246246
}
247247

248248
/**
249-
* Coerces the receiver into an index-sized integer, using the same
250-
* mechanism as {@code PyNumber_AsSsize_t}:
251-
* <ol>
252-
* <li> Call <code>__index__</code> (resp. <code>PyNumber_Index</code>)
253-
* <li> Do a hard cast to long as per <code>PyLong_AsSsize_t</code>
254-
* </ol>
249+
* @see #asIndexWithState(Object, LazyPythonClass, ThreadState)
250+
*/
251+
public final int asIndexWithState(Object receiver, ThreadState threadState) {
252+
return asIndexWithState(receiver, PythonBuiltinClassType.OverflowError, threadState);
253+
}
254+
255+
/**
256+
* @see #asIndexWithState(Object, LazyPythonClass, ThreadState)
257+
*/
258+
public int asIndex(Object receiver, LazyPythonClass errorClass) {
259+
return asIndexWithState(receiver, errorClass, null);
260+
}
261+
262+
/**
263+
* @see #asIndexWithState(Object, LazyPythonClass, ThreadState)
255264
*/
256-
public int asIndex(Object receiver) {
257-
return asIndexWithState(receiver, null);
265+
public final int asIndex(Object receiver) {
266+
return asIndex(receiver, PythonBuiltinClassType.OverflowError);
258267
}
259268

260269
/**

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
5050
import com.oracle.graal.python.nodes.attributes.WriteAttributeToDynamicObjectNode;
5151
import com.oracle.graal.python.runtime.exception.PException;
52-
import com.oracle.graal.python.runtime.exception.PythonErrorType;
5352
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
5453
import com.oracle.truffle.api.Assumption;
5554
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -77,8 +76,12 @@ public final PException raise(PythonBuiltinClassType type, Exception e) {
7776
throw execute(type, PNone.NO_VALUE, getMessage(e), new Object[0]);
7877
}
7978

80-
public final PException raiseIndexError() {
81-
return raise(PythonErrorType.IndexError, "cannot fit 'int' into an index-sized integer");
79+
public final PException raiseIndexError(LazyPythonClass type, Object result) {
80+
return execute(type, PNone.NO_VALUE, "cannot fit '%p' into an index-sized integer", new Object[] { result });
81+
}
82+
83+
public final PException raiseIntegerInterpretationError(Object result) {
84+
return raise(PythonBuiltinClassType.TypeError, "'%p' object cannot be interpreted as an integer", result);
8285
}
8386

8487
public final PException raise(LazyPythonClass exceptionType) {

0 commit comments

Comments
 (0)