wasmtime_c_api_macros/
lib.rs1use proc_macro2::{Ident, TokenStream, TokenTree};
7use quote::quote;
8
9fn 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]
21pub 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 let docs = format!("Deletes the [`{name}`].");
26
27 (quote! {
28 #[doc = #docs]
29 #[unsafe(no_mangle)]
30 pub extern fn #delete(_: Box<#ty>) {}
31 })
32 .into()
33}
34
35#[proc_macro]
36pub fn declare_ty(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
37 let ty = extract_ident(input);
38 let name = ty.to_string();
39 let prefix = &name[..name.len() - 2];
40 let copy = quote::format_ident!("{}_copy", &prefix);
41 let docs = format!(
42 "Creates a new [`{name}`] which matches the provided one.\n\n\
43 The caller is responsible for deleting the returned value via [`{prefix}_delete`].\n\n\
44 "
45 );
46
47 (quote! {
48 wasmtime_c_api_macros::declare_own!(#ty);
49
50 #[doc = #docs]
51 #[unsafe(no_mangle)]
52 pub extern fn #copy(src: &#ty) -> Box<#ty> {
53 Box::new(src.clone())
54 }
55 })
56 .into()
57}
58
59#[proc_macro]
60pub fn declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
61 let ty = extract_ident(input);
62 let name = ty.to_string();
63 let prefix = &name[..name.len() - 2];
64 let same = quote::format_ident!("{}_same", prefix);
65 let same_docs = format!(
66 "Returns `true` if the given references are pointing to the same [`{name}`].\n\n\
67 This is not yet supported and aborts the process upon use."
68 );
69 let get_host_info = quote::format_ident!("{}_get_host_info", prefix);
70 let get_host_info_docs = format!(
71 "Returns the host information of the [`{name}`].\n\n\
72 This is not yet supported and always returns `NULL`."
73 );
74 let set_host_info = quote::format_ident!("{}_set_host_info", prefix);
75 let set_host_info_docs = format!(
76 "Sets the host information of the [`{name}`].\n\n\
77 This is not yet supported and aborts the process upon use."
78 );
79 let set_host_info_final = quote::format_ident!("{}_set_host_info_with_finalizer", prefix);
80 let set_host_info_final_docs = format!(
81 "Sets the host information finalizer of the [`{name}`].\n\n\
82 This is not yet supported and aborts the process upon use."
83 );
84 let as_ref = quote::format_ident!("{}_as_ref", prefix);
85 let as_ref_docs = format!(
86 "Returns the [`{name}`] as mutable reference.\n\n\
87 This is not yet supported and aborts the process upon use."
88 );
89 let as_ref_const = quote::format_ident!("{}_as_ref_const", prefix);
90 let as_ref_const_docs = format!(
91 "Returns the [`{name}`] as immutable reference.\n\n\
92 This is not yet supported and aborts the process upon use."
93 );
94
95 (quote! {
96 wasmtime_c_api_macros::declare_ty!(#ty);
97
98 #[doc = #same_docs]
99 #[unsafe(no_mangle)]
100 pub extern fn #same(_a: &#ty, _b: &#ty) -> bool {
101 eprintln!("`{}` is not implemented", stringify!(#same));
102 std::process::abort();
103 }
104
105 #[doc = #get_host_info_docs]
106 #[unsafe(no_mangle)]
107 pub extern fn #get_host_info(a: &#ty) -> *mut std::os::raw::c_void {
108 std::ptr::null_mut()
109 }
110
111 #[doc = #set_host_info_docs]
112 #[unsafe(no_mangle)]
113 pub extern fn #set_host_info(a: &#ty, info: *mut std::os::raw::c_void) {
114 eprintln!("`{}` is not implemented", stringify!(#set_host_info));
115 std::process::abort();
116 }
117
118 #[doc = #set_host_info_final_docs]
119 #[unsafe(no_mangle)]
120 pub extern fn #set_host_info_final(
121 a: &#ty,
122 info: *mut std::os::raw::c_void,
123 finalizer: Option<extern "C" fn(*mut std::os::raw::c_void)>,
124 ) {
125 eprintln!("`{}` is not implemented", stringify!(#set_host_info_final));
126 std::process::abort();
127 }
128
129 #[doc = #as_ref_docs]
130 #[unsafe(no_mangle)]
131 pub extern fn #as_ref(a: &#ty) -> Box<crate::wasm_ref_t> {
132 eprintln!("`{}` is not implemented", stringify!(#as_ref));
133 std::process::abort();
134 }
135
136 #[doc = #as_ref_const_docs]
137 #[unsafe(no_mangle)]
138 pub extern fn #as_ref_const(a: &#ty) -> Box<crate::wasm_ref_t> {
139 eprintln!("`{}` is not implemented", stringify!(#as_ref_const));
140 std::process::abort();
141 }
142
143 })
146 .into()
147}