funcs get abi type definitions

This commit is contained in:
Pat Hickey
2020-01-20 14:55:06 -08:00
parent 9291495e57
commit b8feffe6e1
4 changed files with 65 additions and 11 deletions

View File

@@ -3,21 +3,53 @@ use quote::quote;
use crate::names::Names;
// FIXME need to template what arguments are required to an import function - some context
// struct (e.g. WasiCtx) should be provided at the invocation of the `gen` proc macro.
// Rather than pass in memory as a `&mut [u8]` as today, require a `GuestMemory<'a>` be
// passed in.
pub fn define_func(names: &Names, func: &witx::InterfaceFunc) -> TokenStream {
let ident = names.func(&func.name);
let mut args = TokenStream::new();
let mut args = quote!(wasi_ctx: &mut WasiCtx, memory: GuestMemory,);
let arg_signature = |param: &witx::InterfaceFuncParam| -> TokenStream {
let name = names.func_param(&param.name);
match param.tref.type_().passed_by() {
witx::TypePassedBy::Value(atom) => {
let atom = names.atom_type(atom);
quote!(#name: #atom,)
}
witx::TypePassedBy::Pointer => {
let atom = names.atom_type(witx::AtomType::I32);
quote!(#name: #atom,)
}
witx::TypePassedBy::PointerLengthPair => {
let atom = names.atom_type(witx::AtomType::I32);
let len_name = names.func_len_param(&param.name);
quote!(#name: #atom, #len_name, #atom,)
}
}
};
for param in func.params.iter() {
let name = names.func_param(&param.name);
let type_ = names.type_ref(&param.tref);
args.extend(quote!(#name: #type_,));
args.extend(arg_signature(param));
}
let mut rets = TokenStream::new();
for result in func.results.iter() {
let type_ = names.type_ref(&result.tref);
rets.extend(quote!(#type_,));
if let Some(arg_results) = func.results.get(1..) {
for result in arg_results {
args.extend(arg_signature(result))
}
}
quote!(pub fn #ident(#args) -> (#rets) { unimplemented!() })
let ret = if let Some(first_result) = func.results.get(0) {
match first_result.tref.type_().passed_by() {
witx::TypePassedBy::Value(atom) => names.atom_type(atom),
_ => unreachable!("first result should always be passed by value"),
}
} else if func.noreturn {
quote!(!)
} else {
quote!(())
};
quote!(pub fn #ident(#args) -> #ret { unimplemented!() })
}