Skip to content

Commit 16ff27c

Browse files
committed
simplify pointer comparison of a PyLong-wrapped void* by going through Sulong
1 parent 9b11aa7 commit 16ff27c

File tree

7 files changed

+58
-54
lines changed

7 files changed

+58
-54
lines changed

graalpython/com.oracle.graal.python.cext/src/capi.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,21 @@ void* wrap_unsupported(void *fun, ...) {
655655
return NULL;
656656
}
657657

658-
int truffle_ptr_compare(void* x, void* y) {
659-
return x == y;
658+
int truffle_ptr_compare(void* x, void* y, int op) {
659+
switch (op) {
660+
case Py_LT:
661+
return x < y;
662+
case Py_LE:
663+
return x <= y;
664+
case Py_EQ:
665+
return x == y;
666+
case Py_NE:
667+
return x != y;
668+
case Py_GT:
669+
return x > y;
670+
case Py_GE:
671+
return x >= y;
672+
default:
673+
return -1;
674+
}
660675
}

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -415,14 +415,8 @@ PString run(PString str) {
415415
@Builtin(name = "do_richcompare", fixedNumOfPositionalArgs = 3)
416416
@GenerateNodeFactory
417417
abstract static class RichCompareNode extends PythonBuiltinNode {
418-
private static final String[] opstrings = new String[]{"<", "<=", "==", "!=", ">", ">="};
419-
private static final String[] opnames = new String[]{
420-
SpecialMethodNames.__LT__, SpecialMethodNames.__LE__, SpecialMethodNames.__EQ__, SpecialMethodNames.__NE__, SpecialMethodNames.__GT__, SpecialMethodNames.__GE__};
421-
private static final String[] reversals = new String[]{
422-
SpecialMethodNames.__GT__, SpecialMethodNames.__GE__, SpecialMethodNames.__EQ__, SpecialMethodNames.__NE__, SpecialMethodNames.__GT__, SpecialMethodNames.__GE__};
423-
424418
protected static BinaryComparisonNode create(int op) {
425-
return BinaryComparisonNode.create(opnames[op], reversals[op], opstrings[op]);
419+
return BinaryComparisonNode.create(SpecialMethodNames.COMPARE_OPNAMES[op], SpecialMethodNames.COMPARE_REVERSALS[op], SpecialMethodNames.COMPARE_OPSTRINGS[op]);
426420
}
427421

428422
@Specialization(guards = "op == 0")

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/CExtNodes.java

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -848,19 +848,36 @@ public static SizeofWCharNode create() {
848848
}
849849
}
850850

851-
public static class IsNode extends CExtBaseNode {
851+
public static final class PointerCompareNode extends CExtBaseNode {
852+
private final int op;
852853
@CompilationFinal private TruffleObject isFunc = null;
853854
@Child Node executeNode = Message.EXECUTE.createNode();
854855

855-
public boolean execute(PythonNativeObject a, PythonNativeObject b) {
856+
private PointerCompareNode(int op) {
857+
this.op = op;
858+
}
859+
860+
private boolean executeCFunction(Object a, Object b) {
856861
try {
857-
return (int) ForeignAccess.sendExecute(executeNode, getNativeFunction(), a.object, b.object) != 0;
862+
return (int) ForeignAccess.sendExecute(executeNode, getNativeFunction(), a, b, op) != 0;
858863
} catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) {
859864
CompilerDirectives.transferToInterpreter();
860865
throw new IllegalStateException(NativeCAPISymbols.FUN_PTR_COMPARE + " didn't work!");
861866
}
862867
}
863868

869+
public boolean execute(PythonNativeObject a, PythonNativeObject b) {
870+
return executeCFunction(a.object, b.object);
871+
}
872+
873+
public boolean execute(PythonNativeObject a, long b) {
874+
return executeCFunction(a.object, b);
875+
}
876+
877+
public boolean execute(PythonNativeVoidPtr a, long b) {
878+
return executeCFunction(a.object, b);
879+
}
880+
864881
private TruffleObject getNativeFunction() {
865882
if (isFunc == null) {
866883
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -869,10 +886,14 @@ private TruffleObject getNativeFunction() {
869886
return isFunc;
870887
}
871888

872-
public static IsNode create() {
873-
return new CExtNodes.IsNode();
889+
public static PointerCompareNode create(String specialMethodName) {
890+
for (int i = 0; i < SpecialMethodNames.COMPARE_OPNAMES.length; i++) {
891+
if (SpecialMethodNames.COMPARE_OPNAMES[i].equals(specialMethodName)) {
892+
return new CExtNodes.PointerCompareNode(i);
893+
}
894+
}
895+
throw new RuntimeException("The special method used for Python C API pointer comparison must be a constant literal (i.e., interned) string");
874896
}
875-
876897
}
877898

878899
public abstract static class AllToJavaNode extends PNodeWithContext {

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

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import com.oracle.graal.python.builtins.objects.bytes.PByteArray;
5757
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
5858
import com.oracle.graal.python.builtins.objects.bytes.PIBytesLike;
59+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes;
5960
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.FromNativeSubclassNode;
6061
import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject;
6162
import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr;
@@ -90,10 +91,6 @@
9091
import com.oracle.truffle.api.dsl.NodeFactory;
9192
import com.oracle.truffle.api.dsl.Specialization;
9293
import com.oracle.truffle.api.dsl.TypeSystemReference;
93-
import com.oracle.truffle.api.interop.ForeignAccess;
94-
import com.oracle.truffle.api.interop.Message;
95-
import com.oracle.truffle.api.interop.UnsupportedMessageException;
96-
import com.oracle.truffle.api.nodes.Node;
9794
import com.oracle.truffle.api.profiles.BranchProfile;
9895
import com.oracle.truffle.api.profiles.ConditionProfile;
9996

@@ -1489,39 +1486,10 @@ boolean doDN(PythonNativeObject x, double y,
14891486
return fromNativeNode.execute(x) < y;
14901487
}
14911488

1492-
protected static Node createAsPointerNode() {
1493-
return Message.AS_POINTER.createNode();
1494-
}
1495-
1496-
protected static Node createIsPointerNode() {
1497-
return Message.IS_POINTER.createNode();
1498-
}
1499-
1500-
protected static Node createIsNullNode() {
1501-
return Message.IS_NULL.createNode();
1502-
}
1503-
15041489
@Specialization
15051490
boolean doVoidPtr(PythonNativeVoidPtr x, long y,
1506-
@Cached("createIsPointerNode()") Node isPointerNode,
1507-
@Cached("createAsPointerNode()") Node asPointerNode,
1508-
@Cached("createIsNullNode()") Node isNullNode) {
1509-
boolean isPointer = ForeignAccess.sendIsPointer(isPointerNode, x.object);
1510-
if (isPointer) {
1511-
try {
1512-
return ForeignAccess.sendAsPointer(asPointerNode, x.object) < y;
1513-
} catch (UnsupportedMessageException e) {
1514-
CompilerDirectives.transferToInterpreter();
1515-
throw new IllegalStateException("a void ptr should be a ptr");
1516-
}
1517-
} else if (ForeignAccess.sendIsNull(isNullNode, x.object)) {
1518-
return 0 < y;
1519-
} else if (y <= 0) {
1520-
return false;
1521-
} else {
1522-
CompilerDirectives.transferToInterpreter();
1523-
throw new IllegalStateException("cannot compare a wrapped void ptr that has no native allocation against arbitrary integers");
1524-
}
1491+
@Cached("create(__LT__)") CExtNodes.PointerCompareNode ltNode) {
1492+
return ltNode.execute(x, y);
15251493
}
15261494

15271495
@SuppressWarnings("unused")

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ public int hash(Object self) {
225225
public abstract static class EqNode extends PythonBinaryBuiltinNode {
226226
@Specialization
227227
public boolean eq(PythonNativeObject self, PythonNativeObject other,
228-
@Cached("create()") CExtNodes.IsNode nativeIsNode) {
228+
@Cached("create(__EQ__)") CExtNodes.PointerCompareNode nativeIsNode) {
229229
return nativeIsNode.execute(self, other);
230230
}
231231

@@ -244,8 +244,8 @@ public abstract static class NeNode extends PythonBinaryBuiltinNode {
244244

245245
@Specialization
246246
public boolean ne(PythonNativeObject self, PythonNativeObject other,
247-
@Cached("create()") CExtNodes.IsNode nativeIsNode) {
248-
return !nativeIsNode.execute(self, other);
247+
@Cached("create(__NE__)") CExtNodes.PointerCompareNode nativeNeNode) {
248+
return nativeNeNode.execute(self, other);
249249
}
250250

251251
@Fallback

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,10 @@ public abstract class SpecialMethodNames {
162162

163163
public static final String RICHCMP = "__truffle_richcompare__";
164164
public static final String TRUFFLE_SOURCE = "__truffle_source__";
165+
166+
// (tfel): The order of these matches the one in CPython, and thus is assumed to remain the same
167+
// in various places
168+
public static final String[] COMPARE_OPSTRINGS = new String[]{"<", "<=", "==", "!=", ">", ">="};
169+
public static final String[] COMPARE_OPNAMES = new String[]{__LT__, __LE__, __EQ__, __NE__, __GT__, __GE__};
170+
public static final String[] COMPARE_REVERSALS = new String[]{__GT__, __GE__, __EQ__, __NE__, __GT__, __GE__};
165171
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/IsNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ boolean doDD(double left, double right) {
165165

166166
@Specialization
167167
boolean doNative(PythonNativeObject left, PythonNativeObject right,
168-
@Cached("create()") CExtNodes.IsNode isNode) {
168+
@Cached("create(__EQ__)") CExtNodes.PointerCompareNode isNode) {
169169
return isNode.execute(left, right);
170170
}
171171

0 commit comments

Comments
 (0)