diff --git a/rustler_codegen/src/nif.rs b/rustler_codegen/src/nif.rs index cd4cb098..354a5673 100644 --- a/rustler_codegen/src/nif.rs +++ b/rustler_codegen/src/nif.rs @@ -55,45 +55,46 @@ pub fn transcoder_decorator(nif_attributes: NifAttributes, fun: syn::ItemFn) -> } quote! { + #[no_mangle] + #[link_name = #erl_func_name] + unsafe extern "C" fn #name( + nif_env: rustler::codegen_runtime::NIF_ENV, + argc: rustler::codegen_runtime::c_int, + argv: *const rustler::codegen_runtime::NIF_TERM + ) -> rustler::codegen_runtime::NIF_TERM { + let lifetime = (); + let env = rustler::Env::new(&lifetime, nif_env); + + let terms = std::slice::from_raw_parts(argv, argc as usize) + .iter() + .map(|term| rustler::Term::new(env, *term)) + .collect::>(); + + fn wrapper<'a>( + env: rustler::Env<'a>, + args: &[rustler::Term<'a>] + ) -> rustler::codegen_runtime::NifReturned { + let result: std::thread::Result<_> = + std::panic::catch_unwind(move || { + #decoded_terms + #function + Ok(#name(#argument_names)) + }); + + rustler::codegen_runtime::handle_nif_result( + result, env + ) + } + wrapper(env, &terms).apply(env) + } + rustler::codegen_runtime::inventory::submit!( rustler::Nif { name: concat!(#erl_func_name, "\0").as_ptr() as *const rustler::codegen_runtime::c_char, arity: #arity, flags: #flags as rustler::codegen_runtime::c_uint, - raw_func: { - unsafe extern "C" fn nif_func( - nif_env: rustler::codegen_runtime::NIF_ENV, - argc: rustler::codegen_runtime::c_int, - argv: *const rustler::codegen_runtime::NIF_TERM - ) -> rustler::codegen_runtime::NIF_TERM { - let lifetime = (); - let env = rustler::Env::new(&lifetime, nif_env); - - let terms = std::slice::from_raw_parts(argv, argc as usize) - .iter() - .map(|term| rustler::Term::new(env, *term)) - .collect::>(); - - fn wrapper<'a>( - env: rustler::Env<'a>, - args: &[rustler::Term<'a>] - ) -> rustler::codegen_runtime::NifReturned { - let result: std::thread::Result<_> = - std::panic::catch_unwind(move || { - #decoded_terms - #function - Ok(#name(#argument_names)) - }); - - rustler::codegen_runtime::handle_nif_result( - result, env - ) - } - wrapper(env, &terms).apply(env) - } - nif_func - } + raw_func: #name, } ); }