diff --git a/crates/wasi/src/lib.rs b/crates/wasi/src/lib.rs index b79e56e484..d4a6e3a0d1 100644 --- a/crates/wasi/src/lib.rs +++ b/crates/wasi/src/lib.rs @@ -7,6 +7,7 @@ pub use wasi_common::{WasiCtx, WasiCtxBuilder}; // Defines a `struct Wasi` with member fields and appropriate APIs for dealing // with all the various WASI exports. wasmtime_wiggle::define_struct_for_wiggle!({ + target: wasi_common::wasi, witx: ["../wasi-common/WASI/phases/snapshot/witx/wasi_snapshot_preview1.witx"], ctx: WasiCtx, instance: { diff --git a/crates/wiggle/wasmtime/macro/src/config.rs b/crates/wiggle/wasmtime/macro/src/config.rs index 6a414ff11b..f42f4121a0 100644 --- a/crates/wiggle/wasmtime/macro/src/config.rs +++ b/crates/wiggle/wasmtime/macro/src/config.rs @@ -4,13 +4,14 @@ use { braced, parse::{Parse, ParseStream}, punctuated::Punctuated, - Error, Ident, Result, Token, + Error, Ident, Path, Result, Token, }, wiggle_generate::config::{CtxConf, WitxConf}, }; #[derive(Debug, Clone)] pub struct Config { + pub target: TargetConf, pub witx: WitxConf, pub ctx: CtxConf, pub instance: InstanceConf, @@ -18,12 +19,14 @@ pub struct Config { #[derive(Debug, Clone)] pub enum ConfigField { + Target(TargetConf), Witx(WitxConf), Ctx(CtxConf), Instance(InstanceConf), } mod kw { + syn::custom_keyword!(target); syn::custom_keyword!(witx); syn::custom_keyword!(witx_literal); syn::custom_keyword!(ctx); @@ -35,7 +38,11 @@ mod kw { impl Parse for ConfigField { fn parse(input: ParseStream) -> Result { let lookahead = input.lookahead1(); - if lookahead.peek(kw::witx) { + if lookahead.peek(kw::target) { + input.parse::()?; + input.parse::()?; + Ok(ConfigField::Target(input.parse()?)) + } else if lookahead.peek(kw::witx) { input.parse::()?; input.parse::()?; Ok(ConfigField::Witx(WitxConf::Paths(input.parse()?))) @@ -59,11 +66,18 @@ impl Parse for ConfigField { impl Config { pub fn build(fields: impl Iterator, err_loc: Span) -> Result { + let mut target = None; let mut witx = None; let mut ctx = None; let mut instance = None; for f in fields { match f { + ConfigField::Target(c) => { + if target.is_some() { + return Err(Error::new(err_loc, "duplicate `target` field")); + } + target = Some(c); + } ConfigField::Witx(c) => { if witx.is_some() { return Err(Error::new(err_loc, "duplicate `witx` field")); @@ -85,6 +99,9 @@ impl Config { } } Ok(Config { + target: target + .take() + .ok_or_else(|| Error::new(err_loc, "`target` field required"))?, witx: witx .take() .ok_or_else(|| Error::new(err_loc, "`witx` field required"))?, @@ -117,6 +134,19 @@ impl Parse for Config { } } +#[derive(Debug, Clone)] +pub struct TargetConf { + pub path: Path, +} + +impl Parse for TargetConf { + fn parse(input: ParseStream) -> Result { + Ok(TargetConf { + path: input.parse()?, + }) + } +} + enum InstanceConfField { Name(Ident), Docs(String), diff --git a/crates/wiggle/wasmtime/macro/src/lib.rs b/crates/wiggle/wasmtime/macro/src/lib.rs index 35a083e0eb..7b520836dc 100644 --- a/crates/wiggle/wasmtime/macro/src/lib.rs +++ b/crates/wiggle/wasmtime/macro/src/lib.rs @@ -6,7 +6,7 @@ use wiggle_generate::Names; mod config; -use config::InstanceConf; +use config::{InstanceConf, TargetConf}; #[proc_macro] pub fn define_struct_for_wiggle(args: TokenStream) -> TokenStream { @@ -17,7 +17,7 @@ pub fn define_struct_for_wiggle(args: TokenStream) -> TokenStream { let doc = config.load_document(); let names = Names::new(&config.ctx.name, quote!(wasmtime_wiggle)); - generate(&doc, &names, &config.instance).into() + generate(&doc, &names, &config.target, &config.instance).into() } enum Abi { @@ -27,7 +27,12 @@ enum Abi { F64, } -fn generate(doc: &witx::Document, names: &Names, instance_conf: &InstanceConf) -> TokenStream2 { +fn generate( + doc: &witx::Document, + names: &Names, + target_conf: &TargetConf, + instance_conf: &InstanceConf, +) -> TokenStream2 { let mut fields = Vec::new(); let mut get_exports = Vec::new(); let mut ctor_externs = Vec::new(); @@ -35,6 +40,7 @@ fn generate(doc: &witx::Document, names: &Names, instance_conf: &InstanceConf) - let mut linker_add = Vec::new(); let runtime = names.runtime_mod(); + let target_path = &target_conf.path; for module in doc.modules() { let module_name = module.name.as_str(); @@ -223,7 +229,7 @@ fn generate(doc: &witx::Document, names: &Names, instance_conf: &InstanceConf) - // root of each function invocation is correct. let bc = #runtime::BorrowChecker::new(); let mem = #runtime::WasmtimeGuestMemory::new( mem, bc ); - wasi_common::wasi::#module_id::#name_ident( + #target_path::#module_id::#name_ident( &mut my_cx.borrow_mut(), &mem, #(#hostcall_args),*