wiggle-wasmtime: get rid of "missing_memory" error code, we can Trap now

the missing memory behavior was always a silly thing, that we generate a
function for wasmtime which is Result<_, Trap> we can just Err(Trap)
when the memory export is missing.
This commit is contained in:
Pat Hickey
2021-01-05 17:28:03 -08:00
parent 6317290a1d
commit 46b1864c9e
2 changed files with 8 additions and 55 deletions

View File

@@ -1,5 +1,5 @@
use { use {
proc_macro2::{Span, TokenStream}, proc_macro2::Span,
std::collections::HashMap, std::collections::HashMap,
syn::{ syn::{
braced, braced,
@@ -16,7 +16,6 @@ pub struct Config {
pub witx: WitxConf, pub witx: WitxConf,
pub ctx: CtxConf, pub ctx: CtxConf,
pub modules: ModulesConf, pub modules: ModulesConf,
pub missing_memory: MissingMemoryConf,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -25,7 +24,6 @@ pub enum ConfigField {
Witx(WitxConf), Witx(WitxConf),
Ctx(CtxConf), Ctx(CtxConf),
Modules(ModulesConf), Modules(ModulesConf),
MissingMemory(MissingMemoryConf),
} }
mod kw { mod kw {
@@ -36,7 +34,6 @@ mod kw {
syn::custom_keyword!(modules); syn::custom_keyword!(modules);
syn::custom_keyword!(name); syn::custom_keyword!(name);
syn::custom_keyword!(docs); syn::custom_keyword!(docs);
syn::custom_keyword!(missing_memory);
syn::custom_keyword!(function_override); syn::custom_keyword!(function_override);
} }
@@ -63,10 +60,6 @@ impl Parse for ConfigField {
input.parse::<kw::modules>()?; input.parse::<kw::modules>()?;
input.parse::<Token![:]>()?; input.parse::<Token![:]>()?;
Ok(ConfigField::Modules(input.parse()?)) Ok(ConfigField::Modules(input.parse()?))
} else if lookahead.peek(kw::missing_memory) {
input.parse::<kw::missing_memory>()?;
input.parse::<Token![:]>()?;
Ok(ConfigField::MissingMemory(input.parse()?))
} else { } else {
Err(lookahead.error()) Err(lookahead.error())
} }
@@ -79,7 +72,6 @@ impl Config {
let mut witx = None; let mut witx = None;
let mut ctx = None; let mut ctx = None;
let mut modules = None; let mut modules = None;
let mut missing_memory = None;
for f in fields { for f in fields {
match f { match f {
ConfigField::Target(c) => { ConfigField::Target(c) => {
@@ -106,12 +98,6 @@ impl Config {
} }
modules = Some(c); modules = Some(c);
} }
ConfigField::MissingMemory(c) => {
if missing_memory.is_some() {
return Err(Error::new(err_loc, "duplicate `missing_memory` field"));
}
missing_memory = Some(c);
}
} }
} }
Ok(Config { Ok(Config {
@@ -119,8 +105,6 @@ impl Config {
witx: witx.ok_or_else(|| Error::new(err_loc, "`witx` field required"))?, witx: witx.ok_or_else(|| Error::new(err_loc, "`witx` field required"))?,
ctx: ctx.ok_or_else(|| Error::new(err_loc, "`ctx` field required"))?, ctx: ctx.ok_or_else(|| Error::new(err_loc, "`ctx` field required"))?,
modules: modules.ok_or_else(|| Error::new(err_loc, "`modules` field required"))?, modules: modules.ok_or_else(|| Error::new(err_loc, "`modules` field required"))?,
missing_memory: missing_memory
.ok_or_else(|| Error::new(err_loc, "`missing_memory` field required"))?,
}) })
} }
@@ -265,20 +249,6 @@ impl Parse for ModulesConf {
} }
} }
#[derive(Debug, Clone)]
pub struct MissingMemoryConf {
pub err: TokenStream,
}
impl Parse for MissingMemoryConf {
fn parse(input: ParseStream) -> Result<Self> {
let contents;
let _lbrace = braced!(contents in input);
Ok(MissingMemoryConf {
err: contents.parse()?,
})
}
}
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct FunctionOverrideConf { pub struct FunctionOverrideConf {
pub funcs: Vec<FunctionOverrideField>, pub funcs: Vec<FunctionOverrideField>,

View File

@@ -6,7 +6,7 @@ use wiggle_generate::Names;
mod config; mod config;
use config::{MissingMemoryConf, ModuleConf, TargetConf}; use config::{ModuleConf, TargetConf};
/// Define the structs required to integrate a Wiggle implementation with Wasmtime. /// Define the structs required to integrate a Wiggle implementation with Wasmtime.
/// ///
@@ -41,9 +41,6 @@ use config::{MissingMemoryConf, ModuleConf, TargetConf};
/// Example: /// Example:
/// `modules: { some_module => { name: SomeTypeName, docs: "Doc string for definition of /// `modules: { some_module => { name: SomeTypeName, docs: "Doc string for definition of
/// SomeTypeName here", function_override: { foo => my_own_foo } }`. /// SomeTypeName here", function_override: { foo => my_own_foo } }`.
/// * `missing_memory`: Describes the error value to return in case the calling module does not
/// export a Memory as `"memory"`. This value is given in braces, e.g. `missing_memory: {
/// wasi_common::wasi::Errno::Inval }`.
/// ///
#[proc_macro] #[proc_macro]
pub fn wasmtime_integration(args: TokenStream) -> TokenStream { pub fn wasmtime_integration(args: TokenStream) -> TokenStream {
@@ -55,13 +52,7 @@ pub fn wasmtime_integration(args: TokenStream) -> TokenStream {
let module = doc let module = doc
.module(&witx::Id::new(name)) .module(&witx::Id::new(name))
.unwrap_or_else(|| panic!("witx document did not contain module named '{}'", name)); .unwrap_or_else(|| panic!("witx document did not contain module named '{}'", name));
generate_module( generate_module(&module, &module_conf, &names, &config.target)
&module,
&module_conf,
&names,
&config.target,
&config.missing_memory,
)
}); });
quote!( #(#modules)* ).into() quote!( #(#modules)* ).into()
} }
@@ -71,7 +62,6 @@ fn generate_module(
module_conf: &ModuleConf, module_conf: &ModuleConf,
names: &Names, names: &Names,
target_conf: &TargetConf, target_conf: &TargetConf,
missing_mem_conf: &MissingMemoryConf,
) -> TokenStream2 { ) -> TokenStream2 {
let fields = module.funcs().map(|f| { let fields = module.funcs().map(|f| {
let name_ident = names.func(&f.name); let name_ident = names.func(&f.name);
@@ -103,7 +93,7 @@ fn generate_module(
let name_ident = names.func(&f.name); let name_ident = names.func(&f.name);
quote! { let #name_ident = wasmtime::Func::wrap(store, #func_override); } quote! { let #name_ident = wasmtime::Func::wrap(store, #func_override); }
} else { } else {
generate_func(&f, names, missing_mem_conf, &target_module) generate_func(&f, names, &target_module)
} }
}); });
@@ -165,10 +155,8 @@ contained in the `cx` parameter.",
fn generate_func( fn generate_func(
func: &witx::InterfaceFunc, func: &witx::InterfaceFunc,
names: &Names, names: &Names,
missing_mem_conf: &MissingMemoryConf,
target_module: &TokenStream2, target_module: &TokenStream2,
) -> TokenStream2 { ) -> TokenStream2 {
let missing_mem_err = &missing_mem_conf.err;
let name_ident = names.func(&func.name); let name_ident = names.func(&func.name);
let coretype = func.core_type(); let coretype = func.core_type();
@@ -180,17 +168,14 @@ fn generate_func(
}); });
let arg_names = coretype.args.iter().map(|arg| names.func_core_arg(arg)); let arg_names = coretype.args.iter().map(|arg| names.func_core_arg(arg));
let (ret_ty, handle_early_error) = if let Some(ret) = &coretype.ret { let ret_ty = if let Some(ret) = &coretype.ret {
let ret_ty = match ret.signifies { let ret_ty = match ret.signifies {
witx::CoreParamSignifies::Value(atom) => names.atom_type(atom), witx::CoreParamSignifies::Value(atom) => names.atom_type(atom),
_ => unreachable!("coretype ret should always be passed by value"), _ => unreachable!("coretype ret should always be passed by value"),
}; };
(quote! { #ret_ty }, quote! { return Ok(e.into()); }) quote! { #ret_ty }
} else { } else {
( quote! {()}
quote! {()},
quote! { panic!("unrecoverable error in {}: {}", stringify!(#name_ident), e) },
)
}; };
let runtime = names.runtime_mod(); let runtime = names.runtime_mod();
@@ -204,9 +189,7 @@ fn generate_func(
let mem = match caller.get_export("memory") { let mem = match caller.get_export("memory") {
Some(wasmtime::Extern::Memory(m)) => m, Some(wasmtime::Extern::Memory(m)) => m,
_ => { _ => {
wasmtime_wiggle::tracing::warn!("callee does not export a memory as \"memory\""); return Err(wasmtime::Trap::new("missing required memory export"));
let e = { #missing_mem_err };
#handle_early_error
} }
}; };
let mem = #runtime::WasmtimeGuestMemory::new(mem); let mem = #runtime::WasmtimeGuestMemory::new(mem);