1 //! This crate defines macros to easily define and use functions with a 2 //! versioned suffix, to facilitate using multiple versions of the same 3 //! crate that generate assembly. 4 //! 5 //! > **⚠️ Warning ⚠️**: this crate is an internal-only crate for the Wasmtime 6 //! > project and is not intended for general use. APIs are not strictly 7 //! > reviewed for safety and usage outside of Wasmtime may have bugs. If 8 //! > you're interested in using this feel free to file an issue on the 9 //! > Wasmtime repository to start a discussion about doing so, but otherwise 10 //! > be aware that your usage of this crate is not supported. 11 12 use quote::ToTokens; 13 14 const VERSION: &str = env!("CARGO_PKG_VERSION"); 15 16 fn version(value: impl std::fmt::Display) -> String { 17 format!("{}_{}", value, VERSION.replace('.', "_")) 18 } 19 20 fn versioned_lit_str(value: impl std::fmt::Display) -> syn::LitStr { 21 syn::LitStr::new(version(value).as_str(), proc_macro2::Span::call_site()) 22 } 23 24 #[proc_macro_attribute] 25 pub fn versioned_export( 26 _attr: proc_macro::TokenStream, 27 item: proc_macro::TokenStream, 28 ) -> proc_macro::TokenStream { 29 let mut function = syn::parse_macro_input!(item as syn::ItemFn); 30 31 let export_name = versioned_lit_str(&function.sig.ident); 32 function 33 .attrs 34 .push(syn::parse_quote! { #[unsafe(export_name = #export_name)] }); 35 36 function.to_token_stream().into() 37 } 38 39 #[proc_macro_attribute] 40 pub fn versioned_link( 41 _attr: proc_macro::TokenStream, 42 item: proc_macro::TokenStream, 43 ) -> proc_macro::TokenStream { 44 let mut function = syn::parse_macro_input!(item as syn::ForeignItemFn); 45 46 let link_name = versioned_lit_str(&function.sig.ident); 47 function 48 .attrs 49 .push(syn::parse_quote! { #[link_name = #link_name] }); 50 51 function.to_token_stream().into() 52 } 53 54 #[proc_macro] 55 pub fn versioned_stringify_ident(item: proc_macro::TokenStream) -> proc_macro::TokenStream { 56 let ident = syn::parse_macro_input!(item as syn::Ident); 57 58 versioned_lit_str(ident).to_token_stream().into() 59 } 60 61 #[proc_macro] 62 pub fn versioned_suffix(item: proc_macro::TokenStream) -> proc_macro::TokenStream { 63 if !item.is_empty() { 64 return syn::Error::new( 65 proc_macro2::Span::call_site(), 66 "`versioned_suffix!` accepts no input", 67 ) 68 .to_compile_error() 69 .into(); 70 }; 71 72 versioned_lit_str("").to_token_stream().into() 73 } 74