make the missing memory error value configurable

This commit is contained in:
Pat Hickey
2020-06-23 15:26:17 -07:00
parent 62237de7ce
commit 49c62ee828
3 changed files with 47 additions and 5 deletions

View File

@@ -24,7 +24,9 @@ wasm modules. This structure exports all that various fields of the
wasi instance as fields which can be used to implement your own wasi instance as fields which can be used to implement your own
instantiation logic, if necessary. Additionally [`Wasi::get_export`] instantiation logic, if necessary. Additionally [`Wasi::get_export`]
can be used to do name-based resolution." can be used to do name-based resolution."
} },
// Error to return when caller module is missing memory export:
missing_memory: { wasi_common::wasi::Errno::Inval },
}); });
pub fn is_wasi_module(name: &str) -> bool { pub fn is_wasi_module(name: &str) -> bool {

View File

@@ -1,5 +1,5 @@
use { use {
proc_macro2::Span, proc_macro2::{Span, TokenStream},
syn::{ syn::{
braced, braced,
parse::{Parse, ParseStream}, parse::{Parse, ParseStream},
@@ -15,6 +15,7 @@ pub struct Config {
pub witx: WitxConf, pub witx: WitxConf,
pub ctx: CtxConf, pub ctx: CtxConf,
pub instance: InstanceConf, pub instance: InstanceConf,
pub missing_memory: MissingMemoryConf,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -23,6 +24,7 @@ pub enum ConfigField {
Witx(WitxConf), Witx(WitxConf),
Ctx(CtxConf), Ctx(CtxConf),
Instance(InstanceConf), Instance(InstanceConf),
MissingMemory(MissingMemoryConf),
} }
mod kw { mod kw {
@@ -33,6 +35,7 @@ mod kw {
syn::custom_keyword!(instance); syn::custom_keyword!(instance);
syn::custom_keyword!(name); syn::custom_keyword!(name);
syn::custom_keyword!(docs); syn::custom_keyword!(docs);
syn::custom_keyword!(missing_memory);
} }
impl Parse for ConfigField { impl Parse for ConfigField {
@@ -58,6 +61,10 @@ impl Parse for ConfigField {
input.parse::<kw::instance>()?; input.parse::<kw::instance>()?;
input.parse::<Token![:]>()?; input.parse::<Token![:]>()?;
Ok(ConfigField::Instance(input.parse()?)) Ok(ConfigField::Instance(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())
} }
@@ -70,6 +77,7 @@ impl Config {
let mut witx = None; let mut witx = None;
let mut ctx = None; let mut ctx = None;
let mut instance = None; let mut instance = None;
let mut missing_memory = None;
for f in fields { for f in fields {
match f { match f {
ConfigField::Target(c) => { ConfigField::Target(c) => {
@@ -96,6 +104,12 @@ impl Config {
} }
instance = Some(c); instance = 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 {
@@ -111,6 +125,9 @@ impl Config {
instance: instance instance: instance
.take() .take()
.ok_or_else(|| Error::new(err_loc, "`instance` field required"))?, .ok_or_else(|| Error::new(err_loc, "`instance` field required"))?,
missing_memory: missing_memory
.take()
.ok_or_else(|| Error::new(err_loc, "`missing_memory` field required"))?,
}) })
} }
@@ -214,3 +231,17 @@ impl Parse for InstanceConf {
Ok(InstanceConf::build(fields.into_iter(), input.span())?) Ok(InstanceConf::build(fields.into_iter(), input.span())?)
} }
} }
#[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()?,
})
}
}

View File

@@ -6,7 +6,7 @@ use wiggle_generate::Names;
mod config; mod config;
use config::{InstanceConf, TargetConf}; use config::{InstanceConf, MissingMemoryConf, TargetConf};
#[proc_macro] #[proc_macro]
pub fn define_wasmtime_integration(args: TokenStream) -> TokenStream { pub fn define_wasmtime_integration(args: TokenStream) -> TokenStream {
@@ -17,7 +17,14 @@ pub fn define_wasmtime_integration(args: TokenStream) -> TokenStream {
let doc = config.load_document(); let doc = config.load_document();
let names = Names::new(&config.ctx.name, quote!(wasmtime_wiggle)); let names = Names::new(&config.ctx.name, quote!(wasmtime_wiggle));
generate(&doc, &names, &config.target, &config.instance).into() generate(
&doc,
&names,
&config.target,
&config.instance,
&config.missing_memory,
)
.into()
} }
enum Abi { enum Abi {
@@ -32,6 +39,7 @@ fn generate(
names: &Names, names: &Names,
target_conf: &TargetConf, target_conf: &TargetConf,
instance_conf: &InstanceConf, instance_conf: &InstanceConf,
missing_mem_conf: &MissingMemoryConf,
) -> TokenStream2 { ) -> TokenStream2 {
let mut fields = Vec::new(); let mut fields = Vec::new();
let mut get_exports = Vec::new(); let mut get_exports = Vec::new();
@@ -41,6 +49,7 @@ fn generate(
let runtime = names.runtime_mod(); let runtime = names.runtime_mod();
let target_path = &target_conf.path; let target_path = &target_conf.path;
let missing_mem_err = &missing_mem_conf.err;
for module in doc.modules() { for module in doc.modules() {
let module_name = module.name.as_str(); let module_name = module.name.as_str();
@@ -205,7 +214,7 @@ fn generate(
Some(wasmtime::Extern::Memory(m)) => m, Some(wasmtime::Extern::Memory(m)) => m,
_ => { _ => {
log::warn!("callee does not export a memory as \"memory\""); log::warn!("callee does not export a memory as \"memory\"");
let e = wasi_common::wasi::Errno::Inval; let e = { #missing_mem_err };
#handle_early_error #handle_early_error
} }
}; };