Better to be loud that we don't support attaching arbitrary host info to `externref`s than to limp along and pretend we do support it. Supporting it properly won't reuse any of this code anyways.
115 lines
3.5 KiB
Rust
115 lines
3.5 KiB
Rust
//! A set of convenience macros for our wasmtime-c-api crate.
|
|
//!
|
|
//! These are intended to mirror the macros in the `wasm.h` header file and
|
|
//! largely facilitate the `declare_ref` macro.
|
|
|
|
extern crate proc_macro;
|
|
|
|
use proc_macro2::{Ident, TokenStream, TokenTree};
|
|
use quote::quote;
|
|
|
|
fn extract_ident(input: proc_macro::TokenStream) -> Ident {
|
|
let input = TokenStream::from(input);
|
|
let i = match input.into_iter().next().unwrap() {
|
|
TokenTree::Ident(i) => i,
|
|
_ => panic!("expected an ident"),
|
|
};
|
|
let name = i.to_string();
|
|
assert!(name.ends_with("_t"));
|
|
return i;
|
|
}
|
|
|
|
#[proc_macro]
|
|
pub fn declare_own(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|
let ty = extract_ident(input);
|
|
let name = ty.to_string();
|
|
let delete = quote::format_ident!("{}_delete", &name[..name.len() - 2]);
|
|
|
|
(quote! {
|
|
#[no_mangle]
|
|
pub extern fn #delete(_: Box<#ty>) {}
|
|
})
|
|
.into()
|
|
}
|
|
|
|
#[proc_macro]
|
|
pub fn declare_ty(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|
let ty = extract_ident(input);
|
|
let name = ty.to_string();
|
|
let copy = quote::format_ident!("{}_copy", &name[..name.len() - 2]);
|
|
|
|
(quote! {
|
|
wasmtime_c_api_macros::declare_own!(#ty);
|
|
|
|
#[no_mangle]
|
|
pub extern fn #copy(src: &#ty) -> Box<#ty> {
|
|
Box::new(src.clone())
|
|
}
|
|
})
|
|
.into()
|
|
}
|
|
|
|
#[proc_macro]
|
|
pub fn declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|
let ty = extract_ident(input);
|
|
let name = ty.to_string();
|
|
let prefix = &name[..name.len() - 2];
|
|
let copy = quote::format_ident!("{}_copy", prefix);
|
|
let same = quote::format_ident!("{}_same", prefix);
|
|
let get_host_info = quote::format_ident!("{}_get_host_info", prefix);
|
|
let set_host_info = quote::format_ident!("{}_set_host_info", prefix);
|
|
let set_host_info_final = quote::format_ident!("{}_set_host_info_with_finalizer", prefix);
|
|
let as_ref = quote::format_ident!("{}_as_ref", prefix);
|
|
let as_ref_const = quote::format_ident!("{}_as_ref_const", prefix);
|
|
|
|
(quote! {
|
|
wasmtime_c_api_macros::declare_own!(#ty);
|
|
|
|
#[no_mangle]
|
|
pub extern fn #copy(src: &#ty) -> Box<#ty> {
|
|
Box::new(src.clone())
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern fn #same(a: &#ty, b: &#ty) -> bool {
|
|
a.externref().ptr_eq(&b.externref())
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern fn #get_host_info(a: &#ty) -> *mut std::os::raw::c_void {
|
|
std::ptr::null_mut()
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern fn #set_host_info(a: &#ty, info: *mut std::os::raw::c_void) {
|
|
eprintln!("`{}` is not implemented", stringify!(#set_host_info));
|
|
std::process::abort();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern fn #set_host_info_final(
|
|
a: &#ty,
|
|
info: *mut std::os::raw::c_void,
|
|
finalizer: Option<extern "C" fn(*mut std::os::raw::c_void)>,
|
|
) {
|
|
eprintln!("`{}` is not implemented", stringify!(#set_host_info_final));
|
|
std::process::abort();
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern fn #as_ref(a: &#ty) -> Box<crate::wasm_ref_t> {
|
|
let r = Some(a.externref());
|
|
Box::new(crate::wasm_ref_t { r })
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern fn #as_ref_const(a: &#ty) -> Box<crate::wasm_ref_t> {
|
|
#as_ref(a)
|
|
}
|
|
|
|
// TODO: implement `wasm_ref_as_#name#`
|
|
// TODO: implement `wasm_ref_as_#name#_const`
|
|
})
|
|
.into()
|
|
}
|