Generate C fn name prefixed with __wasi_
@@ -2,7 +2,7 @@ extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
-use syn::{FnArg, ArgCaptured, Pat, PatIdent};
+use syn::{FnArg, ArgCaptured, Pat, PatIdent, TypeReference, Type, Token};
use std::collections::HashMap;
#[proc_macro_attribute]
@@ -10,8 +10,52 @@ pub fn wasi_common_cbindgen(attr: TokenStream, function: TokenStream) -> TokenSt
assert!(attr.is_empty());
let function = syn::parse_macro_input!(function as syn::ItemFn);
+
+ // generate C fn name prefixed with __wasi_
+ let ident = &function.ident;
+ let concatenated = format!("__wasi_{}", ident);
+ let c_fn_ident = syn::Ident::new(&concatenated, ident.span());
+
+ // capture signature
+ let mut arg_ident = Vec::new();
+ let mut arg_type = Vec::new();
+ for input in &function.decl.inputs {
+ match input {
+ FnArg::Captured(ArgCaptured {
+ pat: Pat::Ident(pat @ PatIdent { .. }),
+ colon_token: _,
+ ty,
+ }) => {
+ // parse arg identifier
+ let ident = &pat.ident;
+ arg_ident.push(quote!(#ident));
+ // parse arg type
+ if let Type::Reference(ty @ TypeReference { .. }) = &ty {
+ // if we're here, then we found a &-ref
+ // so substitute it for *mut since we're exporting to C
+ let elem = &ty.elem;
+ arg_type.push(quote!(*mut #elem));
+ } else {
+ arg_type.push(quote!(#ty));
+ }
+ }
+ _ => {}
+ }
+ }
+
+ println!("{:#?}", arg_ident);
+ println!("{:#?}", arg_type);
+
let result = quote! {
#function
+
+ pub unsafe extern "C" fn #c_fn_ident(
+ #(
+ #arg_ident: #arg_type,
+ )*
+ ) {
+
+ }
};
result.into()
