rustmex_entrypoint/
lib.rs1use proc_macro::{TokenStream};
2
3use quote::quote;
4use syn::ItemFn;
5
6#[proc_macro_attribute]
7pub fn entrypoint(_attr: TokenStream, mut item: TokenStream) -> TokenStream {
8 let input: ItemFn = syn::parse(item.clone()).unwrap();
9 let name = input.sig.ident;
10
11 let gen = quote! {
12 #[no_mangle]
13 pub extern "C" fn mexFunction(nlhs: ::std::os::raw::c_int, lhs: *mut *mut ::rustmex::mxArray,
14 nrhs: ::std::os::raw::c_int, rhs: *const *const ::rustmex::mxArray) {
15
16 match std::panic::catch_unwind(|| {
19 let rhslice = unsafe { ::std::slice::from_raw_parts(rhs as *const &::rustmex::mxArray, nrhs as usize) };
20 let lhslice = unsafe { ::std::slice::from_raw_parts_mut(lhs as *mut Option<&mut ::rustmex::mxArray>, nlhs as usize) };
21
22 let lhslice_owned = unsafe { ::std::mem::transmute(lhslice) };
28 #name(lhslice_owned, rhslice)
29 }) {
30 Ok(Ok(_)) => return,
31 Ok(Err(e)) => ::rustmex::trigger_error!(e),
36 Err(_) => {
37 ::rustmex::trigger_error!(::rustmex::message::AdHoc(
38 "rustmex:panic",
39 "The MEX function you called paniced. Consider restarting your interpreter with an appropriate value of RUST_BACKTRACE (setenv does not seem to work)"
40 ));
41 }
42 }
43 }
44 };
45 let entrypoint: TokenStream = gen.into();
46 item.extend(entrypoint);
47 item
48}