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 extern crate proc_macro;
7
8 use proc_macro2::{Ident, TokenStream, TokenTree};
9 use quote::quote;
10
extract_ident(input: proc_macro::TokenStream) -> Ident11 fn extract_ident(input: proc_macro::TokenStream) -> Ident {
12 let input = TokenStream::from(input);
13 let i = match input.into_iter().next().unwrap() {
14 TokenTree::Ident(i) => i,
15 _ => panic!("expected an ident"),
16 };
17 let name = i.to_string();
18 assert!(name.ends_with("_t"));
19 return i;
20 }
21
22 #[proc_macro]
declare_own(input: proc_macro::TokenStream) -> proc_macro::TokenStream23 pub fn declare_own(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
24 let ty = extract_ident(input);
25 let name = ty.to_string();
26 let delete = quote::format_ident!("{}_delete", &name[..name.len() - 2]);
27
28 (quote! {
29 #[no_mangle]
30 pub extern fn #delete(_: Box<#ty>) {}
31 })
32 .into()
33 }
34
35 #[proc_macro]
declare_ty(input: proc_macro::TokenStream) -> proc_macro::TokenStream36 pub fn declare_ty(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
37 let ty = extract_ident(input);
38 let name = ty.to_string();
39 let copy = quote::format_ident!("{}_copy", &name[..name.len() - 2]);
40
41 (quote! {
42 wasmtime_c_api_macros::declare_own!(#ty);
43
44 #[no_mangle]
45 pub extern fn #copy(src: &#ty) -> Box<#ty> {
46 Box::new(src.clone())
47 }
48 })
49 .into()
50 }
51
52 #[proc_macro]
declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream53 pub fn declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
54 let ty = extract_ident(input);
55 let name = ty.to_string();
56 let prefix = &name[..name.len() - 2];
57 let copy = quote::format_ident!("{}_copy", prefix);
58 let same = quote::format_ident!("{}_same", prefix);
59 let get_host_info = quote::format_ident!("{}_get_host_info", prefix);
60 let set_host_info = quote::format_ident!("{}_set_host_info", prefix);
61 let set_host_info_final = quote::format_ident!("{}_set_host_info_with_finalizer", prefix);
62 let as_ref = quote::format_ident!("{}_as_ref", prefix);
63 let as_ref_const = quote::format_ident!("{}_as_ref_const", prefix);
64
65 (quote! {
66 wasmtime_c_api_macros::declare_own!(#ty);
67
68 #[no_mangle]
69 pub extern fn #copy(src: &#ty) -> Box<#ty> {
70 Box::new(src.clone())
71 }
72
73 #[no_mangle]
74 pub extern fn #same(a: &#ty, b: &#ty) -> bool {
75 a.externref().ptr_eq(&b.externref())
76 }
77
78 #[no_mangle]
79 pub extern fn #get_host_info(a: &#ty) -> *mut std::os::raw::c_void {
80 crate::r#ref::get_host_info(&a.externref())
81 }
82
83 #[no_mangle]
84 pub extern fn #set_host_info(a: &#ty, info: *mut std::os::raw::c_void) {
85 crate::r#ref::set_host_info(&a.externref(), info, None)
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 crate::r#ref::set_host_info(&a.externref(), info, finalizer)
95 }
96
97 #[no_mangle]
98 pub extern fn #as_ref(a: &#ty) -> Box<crate::wasm_ref_t> {
99 let r = Some(a.externref());
100 Box::new(crate::wasm_ref_t { r })
101 }
102
103 #[no_mangle]
104 pub extern fn #as_ref_const(a: &#ty) -> Box<crate::wasm_ref_t> {
105 #as_ref(a)
106 }
107
108 // TODO: implement `wasm_ref_as_#name#`
109 // TODO: implement `wasm_ref_as_#name#_const`
110 })
111 .into()
112 }
113