169
169
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryClinicBuiltinNode ;
170
170
import com .oracle .graal .python .nodes .function .builtins .clinic .ArgumentClinicProvider ;
171
171
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 ;
173
173
import com .oracle .graal .python .nodes .util .CastToJavaStringNode ;
174
174
import com .oracle .graal .python .nodes .util .CastToTruffleStringNode ;
175
175
import com .oracle .graal .python .runtime .PythonContext ;
@@ -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
}
@@ -1729,43 +1734,96 @@ Object execute(Object[] arguments,
1729
1734
}
1730
1735
}
1731
1736
1732
- @ ImportStatic (PGuards .class )
1733
1737
@ 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 {
1735
1756
1736
1757
private static final char [] sPzUZXO = "sPzUZXO" .toCharArray ();
1737
1758
1738
- abstract Object execute (Object ptr , Object src , Object ctype );
1759
+ abstract void execute (Object arg );
1739
1760
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 ,
1745
1773
@ Cached PyTypeStgDictNode pyTypeStgDictNode ,
1746
- @ Cached IsTypeNode isTypeNode ,
1747
- @ Cached GetClassNode getClassNode ,
1748
- @ Cached GetNameNode getNameNode ,
1774
+ @ Cached FailedCastCheckNode failedCastCheckNode ,
1749
1775
@ 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 );
1751
1814
CDataObject result = (CDataObject ) callNode .execute (ctype );
1752
1815
result .b_ptr = PtrValue .nativePointer (ptr .getPointerObject ());
1753
1816
return result ;
1754
1817
}
1755
1818
1756
1819
@ Specialization
1757
- static Object cast (CDataObject ptr , CDataObject src , Object ctype ,
1820
+ static Object cdata (CDataObject ptr , CDataObject src , Object ctype ,
1758
1821
@ Cached HashingStorageSetItem setItem ,
1759
1822
@ Cached PyTypeCheck pyTypeCheck ,
1760
1823
@ 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 );
1769
1827
CDataObject result = (CDataObject ) callNode .execute (ctype );
1770
1828
1771
1829
/*
@@ -1800,16 +1858,10 @@ static Object cast(CDataObject ptr, CDataObject src, Object ctype,
1800
1858
}
1801
1859
1802
1860
@ 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 );
1813
1865
CDataObject result = (CDataObject ) callNode .execute (ctype );
1814
1866
1815
1867
/* Should we assert that result is a pointer type? */
@@ -1818,33 +1870,6 @@ static Object cast(PtrValue ptr, @SuppressWarnings("unused") Object src, Object
1818
1870
return result ;
1819
1871
}
1820
1872
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
- }
1848
1873
}
1849
1874
1850
1875
@ ExportLibrary (InteropLibrary .class )
0 commit comments