Skip to content

Commit 8265130

Browse files
authored
reduce codegen for extern "C" trampoline functions (#5586)
* reduce codegen for extern "C" trampoline functions * correct cfgs and inlining * add doc to warn against function pointer stability
1 parent 6aee027 commit 8265130

File tree

7 files changed

+193
-244
lines changed

7 files changed

+193
-244
lines changed

pyo3-macros-backend/src/method.rs

Lines changed: 13 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -911,76 +911,20 @@ impl<'a> FnSpec<'a> {
911911
FnType::FnStatic => quote! { .flags(#pyo3_path::ffi::METH_STATIC) },
912912
_ => quote! {},
913913
};
914-
match self.convention {
915-
CallingConvention::Noargs => quote! {
916-
#pyo3_path::impl_::pymethods::PyMethodDef::noargs(
917-
#python_name,
918-
{
919-
unsafe extern "C" fn trampoline(
920-
_slf: *mut #pyo3_path::ffi::PyObject,
921-
_args: *mut #pyo3_path::ffi::PyObject,
922-
) -> *mut #pyo3_path::ffi::PyObject
923-
{
924-
unsafe {
925-
#pyo3_path::impl_::trampoline::noargs(
926-
_slf,
927-
_args,
928-
#wrapper
929-
)
930-
}
931-
}
932-
trampoline
933-
},
934-
#doc,
935-
) #flags
936-
},
937-
CallingConvention::Fastcall => quote! {
938-
#pyo3_path::impl_::pymethods::PyMethodDef::fastcall_cfunction_with_keywords(
939-
#python_name,
940-
{
941-
unsafe extern "C" fn trampoline(
942-
_slf: *mut #pyo3_path::ffi::PyObject,
943-
_args: *const *mut #pyo3_path::ffi::PyObject,
944-
_nargs: #pyo3_path::ffi::Py_ssize_t,
945-
_kwnames: *mut #pyo3_path::ffi::PyObject
946-
) -> *mut #pyo3_path::ffi::PyObject
947-
{
948-
#pyo3_path::impl_::trampoline::fastcall_with_keywords(
949-
_slf,
950-
_args,
951-
_nargs,
952-
_kwnames,
953-
#wrapper
954-
)
955-
}
956-
trampoline
957-
},
958-
#doc,
959-
) #flags
960-
},
961-
CallingConvention::Varargs => quote! {
962-
#pyo3_path::impl_::pymethods::PyMethodDef::cfunction_with_keywords(
963-
#python_name,
964-
{
965-
unsafe extern "C" fn trampoline(
966-
_slf: *mut #pyo3_path::ffi::PyObject,
967-
_args: *mut #pyo3_path::ffi::PyObject,
968-
_kwargs: *mut #pyo3_path::ffi::PyObject,
969-
) -> *mut #pyo3_path::ffi::PyObject
970-
{
971-
#pyo3_path::impl_::trampoline::cfunction_with_keywords(
972-
_slf,
973-
_args,
974-
_kwargs,
975-
#wrapper
976-
)
977-
}
978-
trampoline
979-
},
980-
#doc,
981-
) #flags
982-
},
914+
let trampoline = match self.convention {
915+
CallingConvention::Noargs => Ident::new("noargs", Span::call_site()),
916+
CallingConvention::Fastcall => {
917+
Ident::new("fastcall_cfunction_with_keywords", Span::call_site())
918+
}
919+
CallingConvention::Varargs => Ident::new("cfunction_with_keywords", Span::call_site()),
983920
CallingConvention::TpNew => unreachable!("tp_new cannot get a methoddef"),
921+
};
922+
quote! {
923+
#pyo3_path::impl_::pymethods::PyMethodDef::#trampoline(
924+
#python_name,
925+
#pyo3_path::impl_::trampoline::get_trampoline_function!(#trampoline, #wrapper),
926+
#doc,
927+
) #flags
984928
}
985929
}
986930

pyo3-macros-backend/src/pymethod.rs

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -376,22 +376,8 @@ pub fn impl_py_method_def_new(
376376
#pyo3_path::ffi::PyType_Slot {
377377
slot: #pyo3_path::ffi::Py_tp_new,
378378
pfunc: {
379-
unsafe extern "C" fn trampoline(
380-
subtype: *mut #pyo3_path::ffi::PyTypeObject,
381-
args: *mut #pyo3_path::ffi::PyObject,
382-
kwargs: *mut #pyo3_path::ffi::PyObject,
383-
) -> *mut #pyo3_path::ffi::PyObject {
384-
385-
#text_signature_impl
386-
387-
#pyo3_path::impl_::trampoline::newfunc(
388-
subtype,
389-
args,
390-
kwargs,
391-
#cls::#wrapper_ident
392-
)
393-
}
394-
trampoline
379+
#text_signature_impl
380+
#pyo3_path::impl_::trampoline::get_trampoline_function!(newfunc, #cls::#wrapper_ident)
395381
} as #pyo3_path::ffi::newfunc as _
396382
}
397383
};
@@ -413,22 +399,7 @@ fn impl_call_slot(cls: &syn::Type, mut spec: FnSpec<'_>, ctx: &Ctx) -> Result<Me
413399
let slot_def = quote! {
414400
#pyo3_path::ffi::PyType_Slot {
415401
slot: #pyo3_path::ffi::Py_tp_call,
416-
pfunc: {
417-
unsafe extern "C" fn trampoline(
418-
slf: *mut #pyo3_path::ffi::PyObject,
419-
args: *mut #pyo3_path::ffi::PyObject,
420-
kwargs: *mut #pyo3_path::ffi::PyObject,
421-
) -> *mut #pyo3_path::ffi::PyObject
422-
{
423-
#pyo3_path::impl_::trampoline::ternaryfunc(
424-
slf,
425-
args,
426-
kwargs,
427-
#cls::#wrapper_ident
428-
)
429-
}
430-
trampoline
431-
} as #pyo3_path::ffi::ternaryfunc as _
402+
pfunc: #pyo3_path::impl_::trampoline::get_trampoline_function!(ternaryfunc, #cls::#wrapper_ident) as _
432403
}
433404
};
434405
Ok(MethodAndSlotDef {
@@ -1371,21 +1342,9 @@ impl SlotDef {
13711342
}
13721343
};
13731344
let slot_def = quote! {{
1374-
unsafe extern "C" fn trampoline(
1375-
_slf: *mut #pyo3_path::ffi::PyObject,
1376-
#(#arg_idents: #arg_types),*
1377-
) -> #ret_ty
1378-
{
1379-
#pyo3_path::impl_::trampoline:: #func_ty (
1380-
_slf,
1381-
#(#arg_idents,)*
1382-
#cls::#wrapper_ident
1383-
)
1384-
}
1385-
13861345
#pyo3_path::ffi::PyType_Slot {
13871346
slot: #pyo3_path::ffi::#slot,
1388-
pfunc: trampoline as #pyo3_path::ffi::#func_ty as _
1347+
pfunc: #pyo3_path::impl_::trampoline::get_trampoline_function!(#func_ty, #cls::#wrapper_ident) as #pyo3_path::ffi::#func_ty as _
13891348
}
13901349
}};
13911350
Ok(MethodAndSlotDef {

0 commit comments

Comments
 (0)