@@ -70,94 +70,27 @@ pub(crate) fn build_method_def(vm: &VirtualMachine, ml: &PyMethodDef) -> PyRef<H
7070
7171 bitflags:: bitflags_match!( call_flags, {
7272 PyMethodFlags :: NOARGS => {
73- let f = unsafe { method. PyCFunction } ;
74- let callable = move |mut args: FuncArgs , vm: & VirtualMachine | {
75- let slf = take_self_arg( & mut args, flags) ;
76- let slf_ptr = slf
77- . as_ref( )
78- . map( |obj| obj. as_object( ) . as_raw( ) . cast_mut( ) )
79- . unwrap_or_default( ) ;
80- let arg_tuple = vm. ctx. new_tuple( args. args) ;
81- debug_assert!( arg_tuple. is_empty( ) , "Expected no arguments, but got some" ) ;
82- let ret_ptr = unsafe { f( slf_ptr, arg_tuple. as_object( ) . as_raw( ) . cast_mut( ) ) } ;
83- ret_ptr_to_pyresult( vm, ret_ptr)
73+ let callable = move |args: FuncArgs , vm: & VirtualMachine | unsafe {
74+ debug_assert!( args. args. len( ) <= 1 && args. kwargs. is_empty( ) , "Expected no arguments, but got some" ) ;
75+ call_function( vm, method, flags, args)
8476 } ;
8577 vm. ctx. new_method_def( name, callable, flags, doc)
8678 } ,
8779 PyMethodFlags :: VARARGS => {
88- let f = unsafe { method. PyCFunction } ;
89- let callable = move |mut args: FuncArgs , vm: & VirtualMachine | {
90- let slf = take_self_arg( & mut args, flags) ;
91- let slf_ptr = slf
92- . as_ref( )
93- . map( |obj| obj. as_object( ) . as_raw( ) . cast_mut( ) )
94- . unwrap_or_default( ) ;
95- let arg_tuple = vm. ctx. new_tuple( args. args) ;
96- let ret_ptr = unsafe { f( slf_ptr, arg_tuple. as_object( ) . as_raw( ) . cast_mut( ) ) } ;
97- ret_ptr_to_pyresult( vm, ret_ptr)
80+ let callable = move |args: FuncArgs , vm: & VirtualMachine | unsafe {
81+ call_function( vm, method, flags, args)
9882 } ;
9983 vm. ctx. new_method_def( name, callable, flags, doc)
10084 } ,
10185 PyMethodFlags :: VARARGS | PyMethodFlags :: KEYWORDS => {
102- let f = unsafe { method. PyCFunctionWithKeywords } ;
103- let callable = move |mut args: FuncArgs , vm: & VirtualMachine | {
104- let slf = take_self_arg( & mut args, flags) ;
105- let slf_ptr = slf
106- . as_ref( )
107- . map( |obj| obj. as_object( ) . as_raw( ) . cast_mut( ) )
108- . unwrap_or_default( ) ;
109- let arg_tuple = vm. ctx. new_tuple( args. args) ;
110- let kwargs = vm. ctx. new_dict( ) ;
111- for ( k, v) in args. kwargs {
112- kwargs. set_item( & * k, v, vm) ?;
113- }
114- let ret_ptr = unsafe {
115- f(
116- slf_ptr,
117- arg_tuple. as_object( ) . as_raw( ) . cast_mut( ) ,
118- kwargs. as_object( ) . as_raw( ) . cast_mut( ) ,
119- )
120- } ;
121- ret_ptr_to_pyresult( vm, ret_ptr)
86+ let callable = move | args: FuncArgs , vm: & VirtualMachine | unsafe {
87+ call_function_with_keywords( vm, method, flags, args)
12288 } ;
12389 vm. ctx. new_method_def( name, callable, flags, doc)
12490 } ,
12591 PyMethodFlags :: FASTCALL | PyMethodFlags :: KEYWORDS => {
126- let f = unsafe { method. PyCFunctionFastWithKeywords } ;
127- let callable = move |mut args: FuncArgs , vm: & VirtualMachine | {
128- let slf = take_self_arg( & mut args, flags) ;
129- let slf_ptr = slf
130- . as_ref( )
131- . map( |obj| obj. as_object( ) . as_raw( ) . cast_mut( ) )
132- . unwrap_or_default( ) ;
133- let nargs = args. args. len( ) ;
134- let mut fastcall_args = args. args;
135- let mut kwnames_tuple = None ;
136- if !args. kwargs. is_empty( ) {
137- let mut kwnames = Vec :: with_capacity( args. kwargs. len( ) ) ;
138- for ( k, v) in args. kwargs {
139- kwnames. push( vm. ctx. new_str( k) . into( ) ) ;
140- fastcall_args. push( v) ;
141- }
142- kwnames_tuple = Some ( vm. ctx. new_tuple( kwnames) ) ;
143- }
144- let fastcall_arg_ptrs = fastcall_args
145- . iter( )
146- . map( |obj| obj. as_object( ) . as_raw( ) . cast_mut( ) )
147- . collect:: <Vec <_>>( ) ;
148- let kwnames_ptr = kwnames_tuple
149- . as_ref( )
150- . map( |tuple| tuple. as_object( ) . as_raw( ) . cast_mut( ) )
151- . unwrap_or( core:: ptr:: null_mut( ) ) ;
152- let ret_ptr = unsafe {
153- f(
154- slf_ptr,
155- fastcall_arg_ptrs. as_ptr( ) ,
156- nargs as isize ,
157- kwnames_ptr,
158- )
159- } ;
160- ret_ptr_to_pyresult( vm, ret_ptr)
92+ let callable = move |args: FuncArgs , vm: & VirtualMachine | unsafe {
93+ call_fast_function_with_keywords( vm, method, flags, args)
16194 } ;
16295 vm. ctx. new_method_def( name, callable, flags, doc)
16396 } ,
@@ -176,11 +109,97 @@ pub(crate) fn build_method_def(vm: &VirtualMachine, ml: &PyMethodDef) -> PyRef<H
176109 vm. ctx. new_method_def( name, callable, flags, doc)
177110 } ,
178111 _ => {
179- todo!( "unsupported or invalid calling-convention flags" )
112+ todo!( "function {name} has unsupported or invalid calling-convention flags: {flags:?} " )
180113 } ,
181114 } )
182115}
183116
117+ unsafe fn call_function (
118+ vm : & VirtualMachine ,
119+ method : PyMethodPointer ,
120+ flags : PyMethodFlags ,
121+ mut args : FuncArgs ,
122+ ) -> PyResult {
123+ let f = unsafe { method. PyCFunction } ;
124+ let slf = take_self_arg ( & mut args, flags) ;
125+ let slf_ptr = slf
126+ . as_ref ( )
127+ . map ( |obj| obj. as_object ( ) . as_raw ( ) . cast_mut ( ) )
128+ . unwrap_or_default ( ) ;
129+ let arg_tuple = vm. ctx . new_tuple ( args. args ) ;
130+ let ret_ptr = unsafe { f ( slf_ptr, arg_tuple. as_object ( ) . as_raw ( ) . cast_mut ( ) ) } ;
131+ ret_ptr_to_pyresult ( vm, ret_ptr)
132+ }
133+
134+ unsafe fn call_function_with_keywords (
135+ vm : & VirtualMachine ,
136+ method : PyMethodPointer ,
137+ flags : PyMethodFlags ,
138+ mut args : FuncArgs ,
139+ ) -> PyResult {
140+ let f = unsafe { method. PyCFunctionWithKeywords } ;
141+ let slf = take_self_arg ( & mut args, flags) ;
142+ let slf_ptr = slf
143+ . as_ref ( )
144+ . map ( |obj| obj. as_object ( ) . as_raw ( ) . cast_mut ( ) )
145+ . unwrap_or_default ( ) ;
146+ let arg_tuple = vm. ctx . new_tuple ( args. args ) ;
147+ let kwargs = vm. ctx . new_dict ( ) ;
148+ for ( k, v) in args. kwargs {
149+ kwargs. set_item ( & * k, v, vm) ?;
150+ }
151+ let ret_ptr = unsafe {
152+ f (
153+ slf_ptr,
154+ arg_tuple. as_object ( ) . as_raw ( ) . cast_mut ( ) ,
155+ kwargs. as_object ( ) . as_raw ( ) . cast_mut ( ) ,
156+ )
157+ } ;
158+ ret_ptr_to_pyresult ( vm, ret_ptr)
159+ }
160+
161+ unsafe fn call_fast_function_with_keywords (
162+ vm : & VirtualMachine ,
163+ method : PyMethodPointer ,
164+ flags : PyMethodFlags ,
165+ mut args : FuncArgs ,
166+ ) -> PyResult {
167+ let f = unsafe { method. PyCFunctionFastWithKeywords } ;
168+ let slf = take_self_arg ( & mut args, flags) ;
169+ let slf_ptr = slf
170+ . as_ref ( )
171+ . map ( |obj| obj. as_object ( ) . as_raw ( ) . cast_mut ( ) )
172+ . unwrap_or_default ( ) ;
173+ let nargs = args. args . len ( ) ;
174+ let mut fastcall_args = args. args ;
175+ let mut kwnames_tuple = None ;
176+ if !args. kwargs . is_empty ( ) {
177+ let mut kwnames = Vec :: with_capacity ( args. kwargs . len ( ) ) ;
178+ for ( k, v) in args. kwargs {
179+ kwnames. push ( vm. ctx . new_str ( k) . into ( ) ) ;
180+ fastcall_args. push ( v) ;
181+ }
182+ kwnames_tuple = Some ( vm. ctx . new_tuple ( kwnames) ) ;
183+ }
184+ let fastcall_arg_ptrs = fastcall_args
185+ . iter ( )
186+ . map ( |obj| obj. as_object ( ) . as_raw ( ) . cast_mut ( ) )
187+ . collect :: < Vec < _ > > ( ) ;
188+ let kwnames_ptr = kwnames_tuple
189+ . as_ref ( )
190+ . map ( |tuple| tuple. as_object ( ) . as_raw ( ) . cast_mut ( ) )
191+ . unwrap_or ( core:: ptr:: null_mut ( ) ) ;
192+ let ret_ptr = unsafe {
193+ f (
194+ slf_ptr,
195+ fastcall_arg_ptrs. as_ptr ( ) ,
196+ nargs as isize ,
197+ kwnames_ptr,
198+ )
199+ } ;
200+ ret_ptr_to_pyresult ( vm, ret_ptr)
201+ }
202+
184203fn ret_ptr_to_pyresult ( vm : & VirtualMachine , ret_ptr : * mut PyObject ) -> PyResult {
185204 let ret_ptr = NonNull :: new ( ret_ptr) . ok_or_else ( || {
186205 vm. take_raised_exception ( )
0 commit comments