Skip to content

Commit 910c0b0

Browse files
committed
[GR-44489] Accept long values for casting pointers
PullRequest: graalpython/2656
2 parents d756bc9 + cb8e767 commit 910c0b0

File tree

2 files changed

+95
-68
lines changed

2 files changed

+95
-68
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesModuleBuiltins.java

Lines changed: 90 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@
169169
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode;
170170
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
171171
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
172-
import com.oracle.graal.python.nodes.object.GetClassNode;
172+
import com.oracle.graal.python.nodes.object.InlinedGetClassNode;
173173
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
174174
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
175175
import com.oracle.graal.python.runtime.PythonContext;
@@ -554,13 +554,14 @@ Object pointer(VirtualFrame frame, Object arg,
554554
@Cached HashingStorageGetItem getItem,
555555
@Cached PointerTypeNode callPOINTER,
556556
@Cached CallNode callNode,
557-
@Cached GetClassNode getClassNode) {
557+
@Bind("this") Node inliningTarget,
558+
@Cached InlinedGetClassNode getClassNode) {
558559
CtypesThreadState ctypes = CtypesThreadState.get(getContext(), getLanguage());
559-
Object typ = getItem.execute(frame, ctypes.ptrtype_cache, getClassNode.execute(arg));
560+
Object typ = getItem.execute(frame, ctypes.ptrtype_cache, getClassNode.execute(inliningTarget, arg));
560561
if (typ != null) {
561562
return callNode.execute(frame, typ, arg);
562563
}
563-
typ = callPOINTER.execute(frame, getClassNode.execute(arg));
564+
typ = callPOINTER.execute(frame, getClassNode.execute(inliningTarget, arg));
564565
return callNode.execute(frame, typ, arg);
565566
}
566567
}
@@ -1039,10 +1040,12 @@ protected ArgumentClinicProvider getArgumentClinic() {
10391040

10401041
@Specialization
10411042
Object doit(CDataObject obj, int offset,
1043+
@Bind("this") Node inliningTarget,
1044+
@Shared @Cached InlinedGetClassNode getClassNode,
10421045
@Cached PyTypeCheck pyTypeCheck,
10431046
@Cached PyObjectStgDictNode pyObjectStgDictNode) {
10441047
if (!pyTypeCheck.isCDataObject(obj)) {
1045-
return error(null, obj, offset);
1048+
return error(null, obj, offset, inliningTarget, getClassNode);
10461049
}
10471050
FFIType ffiType = pyObjectStgDictNode.execute(obj).ffi_type_pointer;
10481051
PyCArgObject parg = factory().createCArgObject();
@@ -1062,8 +1065,10 @@ Object doit(CDataObject obj, int offset,
10621065

10631066
@SuppressWarnings("unused")
10641067
@Fallback
1065-
Object error(VirtualFrame frame, Object obj, Object off) {
1066-
Object clazz = GetClassNode.getUncached().execute(obj);
1068+
Object error(VirtualFrame frame, Object obj, Object off,
1069+
@Bind("this") Node inliningTarget,
1070+
@Shared @Cached InlinedGetClassNode getClassNode) {
1071+
Object clazz = getClassNode.execute(inliningTarget, obj);
10671072
TruffleString name = GetNameNode.getUncached().execute(clazz);
10681073
throw raise(TypeError, BYREF_ARGUMENT_MUST_BE_A_CTYPES_INSTANCE_NOT_S, name);
10691074
}
@@ -1729,43 +1734,96 @@ Object execute(Object[] arguments,
17291734
}
17301735
}
17311736

1732-
@ImportStatic(PGuards.class)
17331737
@GenerateUncached
1734-
protected abstract static class CastFunctionNode extends Node {
1738+
abstract static class FailedCastCheckNode extends Node {
1739+
abstract void execute(Object arg);
1740+
1741+
@Specialization
1742+
static void raiseError(Object arg,
1743+
@Cached PRaiseNode raiseNode,
1744+
@Cached IsTypeNode isTypeNode,
1745+
@Bind("this") Node inliningTarget,
1746+
@Cached InlinedGetClassNode getClassNode,
1747+
@Cached GetNameNode getNameNode) {
1748+
Object clazz = isTypeNode.execute(arg) ? arg : getClassNode.execute(inliningTarget, arg);
1749+
throw raiseNode.raise(TypeError, CAST_ARGUMENT_2_MUST_BE_A_POINTER_TYPE_NOT_S, getNameNode.execute(clazz));
1750+
}
1751+
}
1752+
1753+
// cast_check_pointertype
1754+
@GenerateUncached
1755+
abstract static class CastCheckPtrTypeNode extends Node {
17351756

17361757
private static final char[] sPzUZXO = "sPzUZXO".toCharArray();
17371758

1738-
abstract Object execute(Object ptr, Object src, Object ctype);
1759+
abstract void execute(Object arg);
17391760

1740-
@Specialization
1741-
static Object cast(PythonNativeVoidPtr ptr, @SuppressWarnings("unused") PythonNativeVoidPtr src, Object ctype,
1742-
@Cached PyTypeCheck pyTypeCheck,
1743-
@Cached CallNode callNode,
1744-
@Cached PRaiseNode raiseNode,
1761+
protected static boolean isPtrTypeObject(Object arg, PyTypeCheck pyTypeCheck) {
1762+
return pyTypeCheck.isPyCPointerTypeObject(arg) || pyTypeCheck.isPyCFuncPtrTypeObject(arg);
1763+
}
1764+
1765+
@Specialization(guards = "isPtrTypeObject(arg, pyTypeCheck)")
1766+
static void fastCheck(@SuppressWarnings("unused") Object arg,
1767+
@SuppressWarnings("unused") @Shared @Cached PyTypeCheck pyTypeCheck) {
1768+
}
1769+
1770+
@Specialization(replaces = {"fastCheck"})
1771+
static void fullcheck(Object arg,
1772+
@Shared @Cached PyTypeCheck pyTypeCheck,
17451773
@Cached PyTypeStgDictNode pyTypeStgDictNode,
1746-
@Cached IsTypeNode isTypeNode,
1747-
@Cached GetClassNode getClassNode,
1748-
@Cached GetNameNode getNameNode,
1774+
@Cached FailedCastCheckNode failedCastCheckNode,
17491775
@Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
1750-
cast_check_pointertype(ctype, raiseNode, pyTypeCheck, pyTypeStgDictNode, isTypeNode, getClassNode, getNameNode, codePointAtIndexNode);
1776+
if (isPtrTypeObject(arg, pyTypeCheck)) {
1777+
return;
1778+
}
1779+
StgDictObject dict = pyTypeStgDictNode.execute(arg);
1780+
if (dict != null && dict.proto != null) {
1781+
if (PGuards.isTruffleString(dict.proto)) {
1782+
int code = codePointAtIndexNode.execute((TruffleString) dict.proto, 0, TS_ENCODING);
1783+
if (strchr(sPzUZXO, code)) {
1784+
/* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
1785+
return;
1786+
}
1787+
}
1788+
}
1789+
failedCastCheckNode.execute(arg);
1790+
}
1791+
}
1792+
1793+
@ImportStatic(PGuards.class)
1794+
@GenerateUncached
1795+
protected abstract static class CastFunctionNode extends Node {
1796+
1797+
abstract Object execute(Object ptr, Object src, Object ctype);
1798+
1799+
@Specialization
1800+
static Object l(long ptr, @SuppressWarnings("unused") long src, Object ctype,
1801+
@Shared @Cached CastCheckPtrTypeNode castCheckPtrTypeNode,
1802+
@Shared @Cached CallNode callNode) {
1803+
castCheckPtrTypeNode.execute(ctype);
1804+
CDataObject result = (CDataObject) callNode.execute(ctype);
1805+
result.b_ptr = PtrValue.nativePointer(ptr);
1806+
return result;
1807+
}
1808+
1809+
@Specialization
1810+
static Object nativeptr(PythonNativeVoidPtr ptr, @SuppressWarnings("unused") PythonNativeVoidPtr src, Object ctype,
1811+
@Shared @Cached CastCheckPtrTypeNode castCheckPtrTypeNode,
1812+
@Shared @Cached CallNode callNode) {
1813+
castCheckPtrTypeNode.execute(ctype);
17511814
CDataObject result = (CDataObject) callNode.execute(ctype);
17521815
result.b_ptr = PtrValue.nativePointer(ptr.getPointerObject());
17531816
return result;
17541817
}
17551818

17561819
@Specialization
1757-
static Object cast(CDataObject ptr, CDataObject src, Object ctype,
1820+
static Object cdata(CDataObject ptr, CDataObject src, Object ctype,
17581821
@Cached HashingStorageSetItem setItem,
17591822
@Cached PyTypeCheck pyTypeCheck,
17601823
@Cached PythonObjectFactory factory,
1761-
@Cached CallNode callNode,
1762-
@Cached PRaiseNode raiseNode,
1763-
@Cached PyTypeStgDictNode pyTypeStgDictNode,
1764-
@Cached IsTypeNode isTypeNode,
1765-
@Cached GetClassNode getClassNode,
1766-
@Cached GetNameNode getNameNode,
1767-
@Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
1768-
cast_check_pointertype(ctype, raiseNode, pyTypeCheck, pyTypeStgDictNode, isTypeNode, getClassNode, getNameNode, codePointAtIndexNode);
1824+
@Shared @Cached CallNode callNode,
1825+
@Shared @Cached CastCheckPtrTypeNode castCheckPtrTypeNode) {
1826+
castCheckPtrTypeNode.execute(ctype);
17691827
CDataObject result = (CDataObject) callNode.execute(ctype);
17701828

17711829
/*
@@ -1800,16 +1858,10 @@ static Object cast(CDataObject ptr, CDataObject src, Object ctype,
18001858
}
18011859

18021860
@Specialization(guards = "!isCDataObject(src)")
1803-
static Object cast(PtrValue ptr, @SuppressWarnings("unused") Object src, Object ctype,
1804-
@Cached PyTypeCheck pyTypeCheck,
1805-
@Cached CallNode callNode,
1806-
@Cached PRaiseNode raiseNode,
1807-
@Cached PyTypeStgDictNode pyTypeStgDictNode,
1808-
@Cached IsTypeNode isTypeNode,
1809-
@Cached GetClassNode getClassNode,
1810-
@Cached GetNameNode getNameNode,
1811-
@Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
1812-
cast_check_pointertype(ctype, raiseNode, pyTypeCheck, pyTypeStgDictNode, isTypeNode, getClassNode, getNameNode, codePointAtIndexNode);
1861+
static Object ptr(PtrValue ptr, @SuppressWarnings("unused") Object src, Object ctype,
1862+
@Shared @Cached CastCheckPtrTypeNode castCheckPtrTypeNode,
1863+
@Shared @Cached CallNode callNode) {
1864+
castCheckPtrTypeNode.execute(ctype);
18131865
CDataObject result = (CDataObject) callNode.execute(ctype);
18141866

18151867
/* Should we assert that result is a pointer type? */
@@ -1818,33 +1870,6 @@ static Object cast(PtrValue ptr, @SuppressWarnings("unused") Object src, Object
18181870
return result;
18191871
}
18201872

1821-
static void cast_check_pointertype(Object arg,
1822-
PRaiseNode raiseNode,
1823-
PyTypeCheck pyTypeCheck,
1824-
PyTypeStgDictNode pyTypeStgDictNode,
1825-
IsTypeNode isTypeNode,
1826-
GetClassNode getClassNode,
1827-
GetNameNode getNameNode,
1828-
TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
1829-
if (pyTypeCheck.isPyCPointerTypeObject(arg)) {
1830-
return;
1831-
}
1832-
if (pyTypeCheck.isPyCFuncPtrTypeObject(arg)) {
1833-
return;
1834-
}
1835-
StgDictObject dict = pyTypeStgDictNode.execute(arg);
1836-
if (dict != null && dict.proto != null) {
1837-
if (PGuards.isTruffleString(dict.proto)) {
1838-
int code = codePointAtIndexNode.execute((TruffleString) dict.proto, 0, TS_ENCODING);
1839-
if (strchr(sPzUZXO, code)) {
1840-
/* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
1841-
return;
1842-
}
1843-
}
1844-
}
1845-
Object clazz = isTypeNode.execute(arg) ? arg : getClassNode.execute(arg);
1846-
throw raiseNode.raise(TypeError, CAST_ARGUMENT_2_MUST_BE_A_POINTER_TYPE_NOT_S, getNameNode.execute(clazz));
1847-
}
18481873
}
18491874

18501875
@ExportLibrary(InteropLibrary.class)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesNodes.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,11 @@
6363
import com.oracle.graal.python.nodes.PNodeWithContext;
6464
import com.oracle.graal.python.nodes.PRaiseNode;
6565
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
66-
import com.oracle.graal.python.nodes.object.GetClassNode;
66+
import com.oracle.graal.python.nodes.object.InlinedGetClassNode;
6767
import com.oracle.graal.python.runtime.PythonContext;
6868
import com.oracle.truffle.api.CompilerDirectives;
6969
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
70+
import com.oracle.truffle.api.dsl.Bind;
7071
import com.oracle.truffle.api.dsl.Cached;
7172
import com.oracle.truffle.api.dsl.Cached.Shared;
7273
import com.oracle.truffle.api.dsl.GenerateUncached;
@@ -151,9 +152,10 @@ protected final boolean isPyCStructTypeObject(Object obj) {
151152

152153
@Specialization
153154
static boolean checkType(Object receiver, Object type,
154-
@Cached GetClassNode getClassNode,
155+
@Bind("this") Node inliningTarget,
156+
@Cached InlinedGetClassNode getClassNode,
155157
@Cached IsSubtypeNode isSubtypeNode) {
156-
Object clazz = getClassNode.execute(receiver);
158+
Object clazz = getClassNode.execute(inliningTarget, receiver);
157159
// IsSameTypeNode.execute(clazz, type) is done within IsSubtypeNode
158160
return isSubtypeNode.execute(clazz, type);
159161
}

0 commit comments

Comments
 (0)