168
168
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryClinicBuiltinNode ;
169
169
import com .oracle .graal .python .nodes .function .builtins .clinic .ArgumentClinicProvider ;
170
170
import com .oracle .graal .python .nodes .object .BuiltinClassProfiles .IsBuiltinObjectProfile ;
171
- import com .oracle .graal .python .nodes .object .GetClassNode ;
171
+ import com .oracle .graal .python .nodes .object .InlinedGetClassNode ;
172
172
import com .oracle .graal .python .nodes .util .CastToJavaStringNode ;
173
173
import com .oracle .graal .python .nodes .util .CastToTruffleStringNode ;
174
174
import com .oracle .graal .python .runtime .ExecutionContext .IndirectCallContext ;
@@ -554,13 +554,14 @@ Object pointer(VirtualFrame frame, Object arg,
554
554
@ Cached HashingStorageGetItem getItem ,
555
555
@ Cached PointerTypeNode callPOINTER ,
556
556
@ Cached CallNode callNode ,
557
- @ Cached GetClassNode getClassNode ) {
557
+ @ Bind ("this" ) Node inliningTarget ,
558
+ @ Cached InlinedGetClassNode getClassNode ) {
558
559
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 ));
560
561
if (typ != null ) {
561
562
return callNode .execute (frame , typ , arg );
562
563
}
563
- typ = callPOINTER .execute (frame , getClassNode .execute (arg ));
564
+ typ = callPOINTER .execute (frame , getClassNode .execute (inliningTarget , arg ));
564
565
return callNode .execute (frame , typ , arg );
565
566
}
566
567
}
@@ -1039,10 +1040,12 @@ protected ArgumentClinicProvider getArgumentClinic() {
1039
1040
1040
1041
@ Specialization
1041
1042
Object doit (CDataObject obj , int offset ,
1043
+ @ Bind ("this" ) Node inliningTarget ,
1044
+ @ Shared @ Cached InlinedGetClassNode getClassNode ,
1042
1045
@ Cached PyTypeCheck pyTypeCheck ,
1043
1046
@ Cached PyObjectStgDictNode pyObjectStgDictNode ) {
1044
1047
if (!pyTypeCheck .isCDataObject (obj )) {
1045
- return error (null , obj , offset );
1048
+ return error (null , obj , offset , inliningTarget , getClassNode );
1046
1049
}
1047
1050
FFIType ffiType = pyObjectStgDictNode .execute (obj ).ffi_type_pointer ;
1048
1051
PyCArgObject parg = factory ().createCArgObject ();
@@ -1062,8 +1065,10 @@ Object doit(CDataObject obj, int offset,
1062
1065
1063
1066
@ SuppressWarnings ("unused" )
1064
1067
@ 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 );
1067
1072
TruffleString name = GetNameNode .getUncached ().execute (clazz );
1068
1073
throw raise (TypeError , BYREF_ARGUMENT_MUST_BE_A_CTYPES_INSTANCE_NOT_S , name );
1069
1074
}
@@ -1733,43 +1738,96 @@ Object execute(Object[] arguments,
1733
1738
}
1734
1739
}
1735
1740
1736
- @ ImportStatic (PGuards .class )
1737
1741
@ GenerateUncached
1738
- protected abstract static class CastFunctionNode extends Node {
1742
+ abstract static class FailedCastCheckNode extends Node {
1743
+ abstract void execute (Object arg );
1744
+
1745
+ @ Specialization
1746
+ static void raiseError (Object arg ,
1747
+ @ Cached PRaiseNode raiseNode ,
1748
+ @ Cached IsTypeNode isTypeNode ,
1749
+ @ Bind ("this" ) Node inliningTarget ,
1750
+ @ Cached InlinedGetClassNode getClassNode ,
1751
+ @ Cached GetNameNode getNameNode ) {
1752
+ Object clazz = isTypeNode .execute (arg ) ? arg : getClassNode .execute (inliningTarget , arg );
1753
+ throw raiseNode .raise (TypeError , CAST_ARGUMENT_2_MUST_BE_A_POINTER_TYPE_NOT_S , getNameNode .execute (clazz ));
1754
+ }
1755
+ }
1756
+
1757
+ // cast_check_pointertype
1758
+ @ GenerateUncached
1759
+ abstract static class CastCheckPtrTypeNode extends Node {
1739
1760
1740
1761
private static final char [] sPzUZXO = "sPzUZXO" .toCharArray ();
1741
1762
1742
- abstract Object execute (Object ptr , Object src , Object ctype );
1763
+ abstract void execute (Object arg );
1743
1764
1744
- @ Specialization
1745
- static Object cast (PythonNativeVoidPtr ptr , @ SuppressWarnings ("unused" ) PythonNativeVoidPtr src , Object ctype ,
1746
- @ Cached PyTypeCheck pyTypeCheck ,
1747
- @ Cached CallNode callNode ,
1748
- @ Cached PRaiseNode raiseNode ,
1765
+ protected static boolean isPtrTypeObject (Object arg , PyTypeCheck pyTypeCheck ) {
1766
+ return pyTypeCheck .isPyCPointerTypeObject (arg ) || pyTypeCheck .isPyCFuncPtrTypeObject (arg );
1767
+ }
1768
+
1769
+ @ Specialization (guards = "isPtrTypeObject(arg, pyTypeCheck)" )
1770
+ static void fastCheck (@ SuppressWarnings ("unused" ) Object arg ,
1771
+ @ SuppressWarnings ("unused" ) @ Shared @ Cached PyTypeCheck pyTypeCheck ) {
1772
+ }
1773
+
1774
+ @ Specialization (replaces = {"fastCheck" })
1775
+ static void fullcheck (Object arg ,
1776
+ @ Shared @ Cached PyTypeCheck pyTypeCheck ,
1749
1777
@ Cached PyTypeStgDictNode pyTypeStgDictNode ,
1750
- @ Cached IsTypeNode isTypeNode ,
1751
- @ Cached GetClassNode getClassNode ,
1752
- @ Cached GetNameNode getNameNode ,
1778
+ @ Cached FailedCastCheckNode failedCastCheckNode ,
1753
1779
@ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
1754
- cast_check_pointertype (ctype , raiseNode , pyTypeCheck , pyTypeStgDictNode , isTypeNode , getClassNode , getNameNode , codePointAtIndexNode );
1780
+ if (isPtrTypeObject (arg , pyTypeCheck )) {
1781
+ return ;
1782
+ }
1783
+ StgDictObject dict = pyTypeStgDictNode .execute (arg );
1784
+ if (dict != null && dict .proto != null ) {
1785
+ if (PGuards .isTruffleString (dict .proto )) {
1786
+ int code = codePointAtIndexNode .execute ((TruffleString ) dict .proto , 0 , TS_ENCODING );
1787
+ if (strchr (sPzUZXO , code )) {
1788
+ /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
1789
+ return ;
1790
+ }
1791
+ }
1792
+ }
1793
+ failedCastCheckNode .execute (arg );
1794
+ }
1795
+ }
1796
+
1797
+ @ ImportStatic (PGuards .class )
1798
+ @ GenerateUncached
1799
+ protected abstract static class CastFunctionNode extends Node {
1800
+
1801
+ abstract Object execute (Object ptr , Object src , Object ctype );
1802
+
1803
+ @ Specialization
1804
+ static Object l (long ptr , @ SuppressWarnings ("unused" ) long src , Object ctype ,
1805
+ @ Shared @ Cached CastCheckPtrTypeNode castCheckPtrTypeNode ,
1806
+ @ Shared @ Cached CallNode callNode ) {
1807
+ castCheckPtrTypeNode .execute (ctype );
1808
+ CDataObject result = (CDataObject ) callNode .execute (ctype );
1809
+ result .b_ptr = PtrValue .nativePointer (ptr );
1810
+ return result ;
1811
+ }
1812
+
1813
+ @ Specialization
1814
+ static Object nativeptr (PythonNativeVoidPtr ptr , @ SuppressWarnings ("unused" ) PythonNativeVoidPtr src , Object ctype ,
1815
+ @ Shared @ Cached CastCheckPtrTypeNode castCheckPtrTypeNode ,
1816
+ @ Shared @ Cached CallNode callNode ) {
1817
+ castCheckPtrTypeNode .execute (ctype );
1755
1818
CDataObject result = (CDataObject ) callNode .execute (ctype );
1756
1819
result .b_ptr = PtrValue .nativePointer (ptr .getPointerObject ());
1757
1820
return result ;
1758
1821
}
1759
1822
1760
1823
@ Specialization
1761
- static Object cast (CDataObject ptr , CDataObject src , Object ctype ,
1824
+ static Object cdata (CDataObject ptr , CDataObject src , Object ctype ,
1762
1825
@ Cached HashingStorageSetItem setItem ,
1763
1826
@ Cached PyTypeCheck pyTypeCheck ,
1764
1827
@ Cached PythonObjectFactory factory ,
1765
- @ Cached CallNode callNode ,
1766
- @ Cached PRaiseNode raiseNode ,
1767
- @ Cached PyTypeStgDictNode pyTypeStgDictNode ,
1768
- @ Cached IsTypeNode isTypeNode ,
1769
- @ Cached GetClassNode getClassNode ,
1770
- @ Cached GetNameNode getNameNode ,
1771
- @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
1772
- cast_check_pointertype (ctype , raiseNode , pyTypeCheck , pyTypeStgDictNode , isTypeNode , getClassNode , getNameNode , codePointAtIndexNode );
1828
+ @ Shared @ Cached CallNode callNode ,
1829
+ @ Shared @ Cached CastCheckPtrTypeNode castCheckPtrTypeNode ) {
1830
+ castCheckPtrTypeNode .execute (ctype );
1773
1831
CDataObject result = (CDataObject ) callNode .execute (ctype );
1774
1832
1775
1833
/*
@@ -1804,16 +1862,10 @@ static Object cast(CDataObject ptr, CDataObject src, Object ctype,
1804
1862
}
1805
1863
1806
1864
@ Specialization (guards = "!isCDataObject(src)" )
1807
- static Object cast (PtrValue ptr , @ SuppressWarnings ("unused" ) Object src , Object ctype ,
1808
- @ Cached PyTypeCheck pyTypeCheck ,
1809
- @ Cached CallNode callNode ,
1810
- @ Cached PRaiseNode raiseNode ,
1811
- @ Cached PyTypeStgDictNode pyTypeStgDictNode ,
1812
- @ Cached IsTypeNode isTypeNode ,
1813
- @ Cached GetClassNode getClassNode ,
1814
- @ Cached GetNameNode getNameNode ,
1815
- @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
1816
- cast_check_pointertype (ctype , raiseNode , pyTypeCheck , pyTypeStgDictNode , isTypeNode , getClassNode , getNameNode , codePointAtIndexNode );
1865
+ static Object ptr (PtrValue ptr , @ SuppressWarnings ("unused" ) Object src , Object ctype ,
1866
+ @ Shared @ Cached CastCheckPtrTypeNode castCheckPtrTypeNode ,
1867
+ @ Shared @ Cached CallNode callNode ) {
1868
+ castCheckPtrTypeNode .execute (ctype );
1817
1869
CDataObject result = (CDataObject ) callNode .execute (ctype );
1818
1870
1819
1871
/* Should we assert that result is a pointer type? */
@@ -1822,33 +1874,6 @@ static Object cast(PtrValue ptr, @SuppressWarnings("unused") Object src, Object
1822
1874
return result ;
1823
1875
}
1824
1876
1825
- static void cast_check_pointertype (Object arg ,
1826
- PRaiseNode raiseNode ,
1827
- PyTypeCheck pyTypeCheck ,
1828
- PyTypeStgDictNode pyTypeStgDictNode ,
1829
- IsTypeNode isTypeNode ,
1830
- GetClassNode getClassNode ,
1831
- GetNameNode getNameNode ,
1832
- TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
1833
- if (pyTypeCheck .isPyCPointerTypeObject (arg )) {
1834
- return ;
1835
- }
1836
- if (pyTypeCheck .isPyCFuncPtrTypeObject (arg )) {
1837
- return ;
1838
- }
1839
- StgDictObject dict = pyTypeStgDictNode .execute (arg );
1840
- if (dict != null && dict .proto != null ) {
1841
- if (PGuards .isTruffleString (dict .proto )) {
1842
- int code = codePointAtIndexNode .execute ((TruffleString ) dict .proto , 0 , TS_ENCODING );
1843
- if (strchr (sPzUZXO , code )) {
1844
- /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
1845
- return ;
1846
- }
1847
- }
1848
- }
1849
- Object clazz = isTypeNode .execute (arg ) ? arg : getClassNode .execute (arg );
1850
- throw raiseNode .raise (TypeError , CAST_ARGUMENT_2_MUST_BE_A_POINTER_TYPE_NOT_S , getNameNode .execute (clazz ));
1851
- }
1852
1877
}
1853
1878
1854
1879
@ ExportLibrary (InteropLibrary .class )
0 commit comments