Skip to content

Commit 501571d

Browse files
committed
Fix: do not use asPointer for PythonNativeVoidPtr.
1 parent 791d48d commit 501571d

File tree

5 files changed

+137
-100
lines changed

5 files changed

+137
-100
lines changed

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

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@
128128
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToNewRefNode;
129129
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.TransformExceptionToNativeNode;
130130
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.VoidPtrToJavaNode;
131+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.CastToNativeLongNodeGen;
132+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.MayRaiseBinaryNodeGen;
133+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.MayRaiseTernaryNodeGen;
134+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.MayRaiseUnaryNodeGen;
135+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.PRaiseNativeNodeGen;
136+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.ToJavaNodeGen;
137+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.TransformExceptionToNativeNodeGen;
131138
import com.oracle.graal.python.builtins.objects.cext.DynamicObjectNativeWrapper;
132139
import com.oracle.graal.python.builtins.objects.cext.DynamicObjectNativeWrapper.PrimitiveNativeWrapper;
133140
import com.oracle.graal.python.builtins.objects.cext.HandleCache;
@@ -144,13 +151,6 @@
144151
import com.oracle.graal.python.builtins.objects.cext.PythonNativeWrapper;
145152
import com.oracle.graal.python.builtins.objects.cext.PythonNativeWrapperLibrary;
146153
import com.oracle.graal.python.builtins.objects.cext.UnicodeObjectNodes.UnicodeAsWideCharNode;
147-
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.CastToNativeLongNodeGen;
148-
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.MayRaiseBinaryNodeGen;
149-
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.MayRaiseTernaryNodeGen;
150-
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.MayRaiseUnaryNodeGen;
151-
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.PRaiseNativeNodeGen;
152-
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.ToJavaNodeGen;
153-
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.TransformExceptionToNativeNodeGen;
154154
import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext;
155155
import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext.AllocInfo;
156156
import com.oracle.graal.python.builtins.objects.cext.capi.NativeReferenceCache;
@@ -162,11 +162,11 @@
162162
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.EncodeNativeStringNode;
163163
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.PCallCExtFunction;
164164
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.UnicodeFromWcharNode;
165+
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.ConvertPIntToPrimitiveNodeGen;
165166
import com.oracle.graal.python.builtins.objects.cext.common.CExtContext;
166167
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode;
167168
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode.SplitFormatStringNode;
168169
import com.oracle.graal.python.builtins.objects.cext.common.VaListWrapper;
169-
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.ConvertPIntToPrimitiveNodeGen;
170170
import com.oracle.graal.python.builtins.objects.code.PCode;
171171
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
172172
import com.oracle.graal.python.builtins.objects.common.IndexNodes.NormalizeIndexNode;
@@ -2513,9 +2513,18 @@ private static BigInteger convertToBigInteger(long n) {
25132513
@Builtin(name = "PyLong_FromVoidPtr", minNumOfPositionalArgs = 1)
25142514
@GenerateNodeFactory
25152515
abstract static class PyLongFromVoidPtr extends PythonUnaryBuiltinNode {
2516-
@Specialization
2516+
@Specialization(limit = "2")
25172517
Object doPointer(TruffleObject pointer,
2518-
@Cached CExtNodes.ToSulongNode toSulongNode) {
2518+
@Cached CExtNodes.ToSulongNode toSulongNode,
2519+
@CachedLibrary("pointer") InteropLibrary lib) {
2520+
// We capture the native pointer at the time when we create the wrapper if it exists.
2521+
if (lib.isPointer(pointer)) {
2522+
try {
2523+
return toSulongNode.execute(factory().createNativeVoidPtr(pointer, lib.asPointer(pointer)));
2524+
} catch (UnsupportedMessageException e) {
2525+
CompilerDirectives.shouldNotReachHere(e);
2526+
}
2527+
}
25192528
return toSulongNode.execute(factory().createNativeVoidPtr(pointer));
25202529
}
25212530
}
@@ -2547,8 +2556,8 @@ long doPointer(PInt n,
25472556
}
25482557

25492558
@Specialization
2550-
static TruffleObject doPointer(PythonNativeVoidPtr n) {
2551-
return n.object;
2559+
static Object doPointer(PythonNativeVoidPtr n) {
2560+
return n.getPointerObject();
25522561
}
25532562

25542563
@Fallback

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,7 +1504,7 @@ public boolean execute(@SuppressWarnings("unused") String opName, PythonNativeVo
15041504
@Shared("op") @Cached(value = "findOp(opName)", allowUncached = true) int op,
15051505
@CachedLibrary(limit = "1") InteropLibrary interopLibrary,
15061506
@Shared("importCAPISymbolNode") @Cached ImportCAPISymbolNode importCAPISymbolNode) {
1507-
return executeCFunction(op, a.object, b, interopLibrary, importCAPISymbolNode);
1507+
return executeCFunction(op, a.getPointerObject(), b, interopLibrary, importCAPISymbolNode);
15081508
}
15091509

15101510
public static int findOp(String specialMethodName) {
@@ -2264,7 +2264,7 @@ static long doPFloat(PFloat value) {
22642264

22652265
@Specialization
22662266
static Object doPythonNativeVoidPtr(PythonNativeVoidPtr object) {
2267-
return object.object;
2267+
return object.getPointerObject();
22682268
}
22692269

22702270
@Specialization(guards = "!object.isDouble()")

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

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,55 @@
4545
import com.oracle.graal.python.builtins.objects.function.PArguments.ThreadState;
4646
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
4747
import com.oracle.truffle.api.CompilerAsserts;
48+
import com.oracle.truffle.api.CompilerDirectives;
49+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
50+
import com.oracle.truffle.api.interop.InteropLibrary;
4851
import com.oracle.truffle.api.interop.TruffleObject;
52+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
53+
import com.oracle.truffle.api.library.CachedLibrary;
4954
import com.oracle.truffle.api.library.ExportLibrary;
5055
import com.oracle.truffle.api.library.ExportMessage;
5156

57+
/**
58+
* Represents the value of a native pointer as Python int.<br/>
59+
* Such objects are created using C API function {@code PyLong_FromVoidPtr} and semantics are best
60+
* explained by looking at how CPython constructs the value:
61+
* {@code PyLong_FromUnsignedLong((unsigned long)(uintptr_t)p)}. CPython casts the {@code (void *)}
62+
* to an integer and this will be the value for the Python int. In our case, to get a numeric
63+
* representation of a pointer, we would need to send a to-native message. However, we try to avoid
64+
* this eager transformation using this wrapper.
65+
*/
5266
@ExportLibrary(PythonObjectLibrary.class)
5367
public class PythonNativeVoidPtr extends PythonAbstractObject {
54-
public final TruffleObject object;
68+
private final TruffleObject object;
69+
private final long nativePointerValue;
70+
private final boolean hasNativePointer;
5571

5672
public PythonNativeVoidPtr(TruffleObject object) {
5773
this.object = object;
74+
this.nativePointerValue = 0;
75+
this.hasNativePointer = false;
76+
}
77+
78+
public PythonNativeVoidPtr(TruffleObject object, long nativePointerValue) {
79+
this.object = object;
80+
this.nativePointerValue = nativePointerValue;
81+
this.hasNativePointer = true;
82+
}
83+
84+
public Object getPointerObject() {
85+
return object;
86+
}
87+
88+
public long getNativePointer() {
89+
return nativePointerValue;
90+
}
91+
92+
public boolean isNativePointer() {
93+
return hasNativePointer;
5894
}
5995

96+
@Override
6097
public int compareTo(Object o) {
6198
return 0;
6299
}
@@ -79,4 +116,21 @@ public String toString() {
79116
return String.format("PythonNativeVoidPtr(%s)", object);
80117
}
81118

119+
@ExportMessage(limit = "2")
120+
long hash(
121+
@CachedLibrary("this.getPointerObject()") InteropLibrary lib) {
122+
if (lib.hasIdentity(object)) {
123+
try {
124+
return lib.identityHashCode(object);
125+
} catch (UnsupportedMessageException e) {
126+
CompilerDirectives.shouldNotReachHere(e);
127+
}
128+
}
129+
return hashCodeBoundary(object);
130+
}
131+
132+
@TruffleBoundary
133+
private static long hashCodeBoundary(Object object) {
134+
return object.hashCode();
135+
}
82136
}

0 commit comments

Comments
 (0)