Path: blob/main/crates/c-api-macros/src/lib.rs
1692 views
//! A set of convenience macros for our wasmtime-c-api crate.1//!2//! These are intended to mirror the macros in the `wasm.h` header file and3//! largely facilitate the `declare_ref` macro.4//!5//! > **⚠️ Warning ⚠️**: this crate is an internal-only crate for the Wasmtime6//! > project and is not intended for general use. APIs are not strictly7//! > reviewed for safety and usage outside of Wasmtime may have bugs. If8//! > you're interested in using this feel free to file an issue on the9//! > Wasmtime repository to start a discussion about doing so, but otherwise10//! > be aware that your usage of this crate is not supported.1112use proc_macro2::{Ident, TokenStream, TokenTree};13use quote::quote;1415fn extract_ident(input: proc_macro::TokenStream) -> Ident {16let input = TokenStream::from(input);17let i = match input.into_iter().next().unwrap() {18TokenTree::Ident(i) => i,19_ => panic!("expected an ident"),20};21let name = i.to_string();22assert!(name.ends_with("_t"));23return i;24}2526#[proc_macro]27pub fn declare_own(input: proc_macro::TokenStream) -> proc_macro::TokenStream {28let ty = extract_ident(input);29let name = ty.to_string();30let delete = quote::format_ident!("{}_delete", &name[..name.len() - 2]);31let docs = format!("Deletes the [`{name}`].");3233(quote! {34#[doc = #docs]35#[unsafe(no_mangle)]36pub extern fn #delete(_: Box<#ty>) {}37})38.into()39}4041#[proc_macro]42pub fn declare_ty(input: proc_macro::TokenStream) -> proc_macro::TokenStream {43let ty = extract_ident(input);44let name = ty.to_string();45let prefix = &name[..name.len() - 2];46let copy = quote::format_ident!("{}_copy", &prefix);47let docs = format!(48"Creates a new [`{name}`] which matches the provided one.\n\n\49The caller is responsible for deleting the returned value via [`{prefix}_delete`].\n\n\50"51);5253(quote! {54wasmtime_c_api_macros::declare_own!(#ty);5556#[doc = #docs]57#[unsafe(no_mangle)]58pub extern fn #copy(src: &#ty) -> Box<#ty> {59Box::new(src.clone())60}61})62.into()63}6465#[proc_macro]66pub fn declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream {67let ty = extract_ident(input);68let name = ty.to_string();69let prefix = &name[..name.len() - 2];70let same = quote::format_ident!("{}_same", prefix);71let same_docs = format!(72"Returns `true` if the given references are pointing to the same [`{name}`].\n\n\73This is not yet supported and aborts the process upon use."74);75let get_host_info = quote::format_ident!("{}_get_host_info", prefix);76let get_host_info_docs = format!(77"Returns the host information of the [`{name}`].\n\n\78This is not yet supported and always returns `NULL`."79);80let set_host_info = quote::format_ident!("{}_set_host_info", prefix);81let set_host_info_docs = format!(82"Sets the host information of the [`{name}`].\n\n\83This is not yet supported and aborts the process upon use."84);85let set_host_info_final = quote::format_ident!("{}_set_host_info_with_finalizer", prefix);86let set_host_info_final_docs = format!(87"Sets the host information finalizer of the [`{name}`].\n\n\88This is not yet supported and aborts the process upon use."89);90let as_ref = quote::format_ident!("{}_as_ref", prefix);91let as_ref_docs = format!(92"Returns the [`{name}`] as mutable reference.\n\n\93This is not yet supported and aborts the process upon use."94);95let as_ref_const = quote::format_ident!("{}_as_ref_const", prefix);96let as_ref_const_docs = format!(97"Returns the [`{name}`] as immutable reference.\n\n\98This is not yet supported and aborts the process upon use."99);100101(quote! {102wasmtime_c_api_macros::declare_ty!(#ty);103104#[doc = #same_docs]105#[unsafe(no_mangle)]106pub extern fn #same(_a: &#ty, _b: &#ty) -> bool {107eprintln!("`{}` is not implemented", stringify!(#same));108std::process::abort();109}110111#[doc = #get_host_info_docs]112#[unsafe(no_mangle)]113pub extern fn #get_host_info(a: &#ty) -> *mut std::os::raw::c_void {114std::ptr::null_mut()115}116117#[doc = #set_host_info_docs]118#[unsafe(no_mangle)]119pub extern fn #set_host_info(a: &#ty, info: *mut std::os::raw::c_void) {120eprintln!("`{}` is not implemented", stringify!(#set_host_info));121std::process::abort();122}123124#[doc = #set_host_info_final_docs]125#[unsafe(no_mangle)]126pub extern fn #set_host_info_final(127a: &#ty,128info: *mut std::os::raw::c_void,129finalizer: Option<extern "C" fn(*mut std::os::raw::c_void)>,130) {131eprintln!("`{}` is not implemented", stringify!(#set_host_info_final));132std::process::abort();133}134135#[doc = #as_ref_docs]136#[unsafe(no_mangle)]137pub extern fn #as_ref(a: &#ty) -> Box<crate::wasm_ref_t> {138eprintln!("`{}` is not implemented", stringify!(#as_ref));139std::process::abort();140}141142#[doc = #as_ref_const_docs]143#[unsafe(no_mangle)]144pub extern fn #as_ref_const(a: &#ty) -> Box<crate::wasm_ref_t> {145eprintln!("`{}` is not implemented", stringify!(#as_ref_const));146std::process::abort();147}148149// TODO: implement `wasm_ref_as_#name#`150// TODO: implement `wasm_ref_as_#name#_const`151})152.into()153}154155156