1 //! A set of convenience macros for our wasmtime-c-api crate. 2 //! 3 //! These are intended to mirror the macros in the `wasm.h` header file and 4 //! largely facilitate the `declare_ref` macro. 5 6 use proc_macro2::{Ident, TokenStream, TokenTree}; 7 use quote::quote; 8 9 fn extract_ident(input: proc_macro::TokenStream) -> Ident { 10 let input = TokenStream::from(input); 11 let i = match input.into_iter().next().unwrap() { 12 TokenTree::Ident(i) => i, 13 _ => panic!("expected an ident"), 14 }; 15 let name = i.to_string(); 16 assert!(name.ends_with("_t")); 17 return i; 18 } 19 20 #[proc_macro] 21 pub fn declare_own(input: proc_macro::TokenStream) -> proc_macro::TokenStream { 22 let ty = extract_ident(input); 23 let name = ty.to_string(); 24 let delete = quote::format_ident!("{}_delete", &name[..name.len() - 2]); 25 26 (quote! { 27 #[no_mangle] 28 pub extern fn #delete(_: Box<#ty>) {} 29 }) 30 .into() 31 } 32 33 #[proc_macro] 34 pub fn declare_ty(input: proc_macro::TokenStream) -> proc_macro::TokenStream { 35 let ty = extract_ident(input); 36 let name = ty.to_string(); 37 let copy = quote::format_ident!("{}_copy", &name[..name.len() - 2]); 38 39 (quote! { 40 wasmtime_c_api_macros::declare_own!(#ty); 41 42 #[no_mangle] 43 pub extern fn #copy(src: &#ty) -> Box<#ty> { 44 Box::new(src.clone()) 45 } 46 }) 47 .into() 48 } 49 50 #[proc_macro] 51 pub fn declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream { 52 let ty = extract_ident(input); 53 let name = ty.to_string(); 54 let prefix = &name[..name.len() - 2]; 55 let copy = quote::format_ident!("{}_copy", prefix); 56 let same = quote::format_ident!("{}_same", prefix); 57 let get_host_info = quote::format_ident!("{}_get_host_info", prefix); 58 let set_host_info = quote::format_ident!("{}_set_host_info", prefix); 59 let set_host_info_final = quote::format_ident!("{}_set_host_info_with_finalizer", prefix); 60 let as_ref = quote::format_ident!("{}_as_ref", prefix); 61 let as_ref_const = quote::format_ident!("{}_as_ref_const", prefix); 62 63 (quote! { 64 wasmtime_c_api_macros::declare_own!(#ty); 65 66 #[no_mangle] 67 pub extern fn #copy(src: &#ty) -> Box<#ty> { 68 Box::new(src.clone()) 69 } 70 71 #[no_mangle] 72 pub extern fn #same(_a: &#ty, _b: &#ty) -> bool { 73 eprintln!("`{}` is not implemented", stringify!(#same)); 74 std::process::abort(); 75 } 76 77 #[no_mangle] 78 pub extern fn #get_host_info(a: &#ty) -> *mut std::os::raw::c_void { 79 std::ptr::null_mut() 80 } 81 82 #[no_mangle] 83 pub extern fn #set_host_info(a: &#ty, info: *mut std::os::raw::c_void) { 84 eprintln!("`{}` is not implemented", stringify!(#set_host_info)); 85 std::process::abort(); 86 } 87 88 #[no_mangle] 89 pub extern fn #set_host_info_final( 90 a: &#ty, 91 info: *mut std::os::raw::c_void, 92 finalizer: Option<extern "C" fn(*mut std::os::raw::c_void)>, 93 ) { 94 eprintln!("`{}` is not implemented", stringify!(#set_host_info_final)); 95 std::process::abort(); 96 } 97 98 #[no_mangle] 99 pub extern fn #as_ref(a: &#ty) -> Box<crate::wasm_ref_t> { 100 eprintln!("`{}` is not implemented", stringify!(#as_ref)); 101 std::process::abort(); 102 } 103 104 #[no_mangle] 105 pub extern fn #as_ref_const(a: &#ty) -> Box<crate::wasm_ref_t> { 106 eprintln!("`{}` is not implemented", stringify!(#as_ref_const)); 107 std::process::abort(); 108 } 109 110 // TODO: implement `wasm_ref_as_#name#` 111 // TODO: implement `wasm_ref_as_#name#_const` 112 }) 113 .into() 114 } 115