Update to the next version of the witx crate
This commit updates to the 0.9 version of the witx crate implemented in WebAssembly/wasi#395. This new version drastically changes code generation and how we interface with the crate. The intention is to abstract the code generation aspects and allow code generators to implement much more low-level instructions to enable more flexible APIs in the future. Additionally a bunch of `*.witx` files were updated in the WASI repository. It's worth pointing out, however, that `wasi-common` does not change as a result of this change. The shape of the APIs that we need to implement are effectively the same and the only difference is that the shim functions generated by wiggle are a bit different.
This commit is contained in:
committed by
Andrew Brown
parent
aed6de32d4
commit
df9c725fa0
@@ -13,7 +13,7 @@ include = ["src/**/*", "LICENSE"]
|
||||
[dependencies]
|
||||
wasmtime = { path = "../../wasmtime", version = "0.23.0", default-features = false }
|
||||
wasmtime-wiggle-macro = { path = "./macro", version = "0.23.0" }
|
||||
witx = { path = "../../wasi-common/WASI/tools/witx", version = "0.8.7", optional = true }
|
||||
witx = { version = "0.9", path = "../../wasi-common/WASI/tools/witx", optional = true }
|
||||
wiggle = { path = "..", version = "0.23.0" }
|
||||
wiggle-borrow = { path = "../borrow", version = "0.23.0" }
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ proc-macro = true
|
||||
test = false
|
||||
|
||||
[dependencies]
|
||||
witx = { path = "../../../wasi-common/WASI/tools/witx", version = "0.8.7" }
|
||||
witx = { version = "0.9", path = "../../../wasi-common/WASI/tools/witx" }
|
||||
wiggle-generate = { path = "../../generate", version = "0.23.0" }
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0", features = ["full", "extra-traits"] }
|
||||
|
||||
@@ -144,7 +144,6 @@ impl Parse for TargetConf {
|
||||
enum ModuleConfField {
|
||||
Name(Ident),
|
||||
Docs(String),
|
||||
FunctionOverride(FunctionOverrideConf),
|
||||
}
|
||||
|
||||
impl Parse for ModuleConfField {
|
||||
@@ -159,10 +158,6 @@ impl Parse for ModuleConfField {
|
||||
input.parse::<Token![:]>()?;
|
||||
let docs: syn::LitStr = input.parse()?;
|
||||
Ok(ModuleConfField::Docs(docs.value()))
|
||||
} else if lookahead.peek(kw::function_override) {
|
||||
input.parse::<kw::function_override>()?;
|
||||
input.parse::<Token![:]>()?;
|
||||
Ok(ModuleConfField::FunctionOverride(input.parse()?))
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
@@ -173,14 +168,12 @@ impl Parse for ModuleConfField {
|
||||
pub struct ModuleConf {
|
||||
pub name: Ident,
|
||||
pub docs: Option<String>,
|
||||
pub function_override: FunctionOverrideConf,
|
||||
}
|
||||
|
||||
impl ModuleConf {
|
||||
fn build(fields: impl Iterator<Item = ModuleConfField>, err_loc: Span) -> Result<Self> {
|
||||
let mut name = None;
|
||||
let mut docs = None;
|
||||
let mut function_override = None;
|
||||
for f in fields {
|
||||
match f {
|
||||
ModuleConfField::Name(c) => {
|
||||
@@ -195,18 +188,11 @@ impl ModuleConf {
|
||||
}
|
||||
docs = Some(c);
|
||||
}
|
||||
ModuleConfField::FunctionOverride(c) => {
|
||||
if function_override.is_some() {
|
||||
return Err(Error::new(err_loc, "duplicate `function_override` field"));
|
||||
}
|
||||
function_override = Some(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(ModuleConf {
|
||||
name: name.ok_or_else(|| Error::new(err_loc, "`name` field required"))?,
|
||||
docs,
|
||||
function_override: function_override.unwrap_or_default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -248,42 +234,3 @@ impl Parse for ModulesConf {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct FunctionOverrideConf {
|
||||
pub funcs: Vec<FunctionOverrideField>,
|
||||
}
|
||||
impl FunctionOverrideConf {
|
||||
pub fn find(&self, name: &str) -> Option<&Ident> {
|
||||
self.funcs
|
||||
.iter()
|
||||
.find(|f| f.name == name)
|
||||
.map(|f| &f.replacement)
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for FunctionOverrideConf {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let contents;
|
||||
let _lbrace = braced!(contents in input);
|
||||
let fields: Punctuated<FunctionOverrideField, Token![,]> =
|
||||
contents.parse_terminated(FunctionOverrideField::parse)?;
|
||||
Ok(FunctionOverrideConf {
|
||||
funcs: fields.into_iter().collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FunctionOverrideField {
|
||||
pub name: String,
|
||||
pub replacement: Ident,
|
||||
}
|
||||
impl Parse for FunctionOverrideField {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let name = input.parse::<Ident>()?.to_string();
|
||||
input.parse::<Token![=>]>()?;
|
||||
let replacement = input.parse::<Ident>()?;
|
||||
Ok(FunctionOverrideField { name, replacement })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use proc_macro2::{Ident, Span, TokenStream as TokenStream2};
|
||||
use quote::quote;
|
||||
use syn::parse_macro_input;
|
||||
use wiggle_generate::Names;
|
||||
@@ -88,14 +88,9 @@ fn generate_module(
|
||||
let module_id = names.module(&module.name);
|
||||
let target_module = quote! { #target_path::#module_id };
|
||||
|
||||
let ctor_externs = module.funcs().map(|f| {
|
||||
if let Some(func_override) = module_conf.function_override.find(&f.name.as_str()) {
|
||||
let name_ident = names.func(&f.name);
|
||||
quote! { let #name_ident = wasmtime::Func::wrap(store, #func_override); }
|
||||
} else {
|
||||
generate_func(&f, names, &target_module)
|
||||
}
|
||||
});
|
||||
let ctor_externs = module
|
||||
.funcs()
|
||||
.map(|f| generate_func(&f, names, &target_module));
|
||||
|
||||
let type_name = module_conf.name.clone();
|
||||
let type_docs = module_conf
|
||||
@@ -158,23 +153,21 @@ fn generate_func(
|
||||
) -> TokenStream2 {
|
||||
let name_ident = names.func(&func.name);
|
||||
|
||||
let coretype = func.core_type();
|
||||
let (params, results) = func.wasm_signature();
|
||||
|
||||
let arg_decls = coretype.args.iter().map(|arg| {
|
||||
let name = names.func_core_arg(arg);
|
||||
let atom = names.atom_type(arg.repr());
|
||||
quote! { #name: #atom }
|
||||
let arg_names = (0..params.len())
|
||||
.map(|i| Ident::new(&format!("arg{}", i), Span::call_site()))
|
||||
.collect::<Vec<_>>();
|
||||
let arg_decls = params.iter().enumerate().map(|(i, ty)| {
|
||||
let name = &arg_names[i];
|
||||
let wasm = names.wasm_type(*ty);
|
||||
quote! { #name: #wasm }
|
||||
});
|
||||
let arg_names = coretype.args.iter().map(|arg| names.func_core_arg(arg));
|
||||
|
||||
let ret_ty = if let Some(ret) = &coretype.ret {
|
||||
let ret_ty = match ret.signifies {
|
||||
witx::CoreParamSignifies::Value(atom) => names.atom_type(atom),
|
||||
_ => unreachable!("coretype ret should always be passed by value"),
|
||||
};
|
||||
quote! { #ret_ty }
|
||||
} else {
|
||||
quote! {()}
|
||||
let ret_ty = match results.len() {
|
||||
0 => quote!(()),
|
||||
1 => names.wasm_type(results[0]),
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
|
||||
let runtime = names.runtime_mod();
|
||||
|
||||
Reference in New Issue
Block a user