factor the docs out as well

This commit is contained in:
Pat Hickey
2020-06-22 19:27:31 -07:00
parent 6adbae3007
commit cde32070fc
3 changed files with 102 additions and 36 deletions

View File

@@ -9,7 +9,16 @@ pub use wasi_common::{WasiCtx, WasiCtxBuilder};
wasmtime_wiggle::define_struct_for_wiggle!({
witx: ["../wasi-common/WASI/phases/snapshot/witx/wasi_snapshot_preview1.witx"],
ctx: WasiCtx,
instance: Wasi,
instance: {
name: Wasi,
docs: "An instantiated instance of the wasi exports.
This represents a wasi module which can be used to instantiate other
wasm modules. This structure exports all that various fields of the
wasi instance as fields which can be used to implement your own
instantiation logic, if necessary. Additionally [`Wasi::get_export`]
can be used to do name-based resolution."
}
});
pub fn is_wasi_module(name: &str) -> bool {

View File

@@ -13,14 +13,14 @@ use {
pub struct Config {
pub witx: WitxConf,
pub ctx: CtxConf,
pub instance_typename: InstanceTypenameConf,
pub instance: InstanceConf,
}
#[derive(Debug, Clone)]
pub enum ConfigField {
Witx(WitxConf),
Ctx(CtxConf),
InstanceTypename(InstanceTypenameConf),
Instance(InstanceConf),
}
mod kw {
@@ -28,6 +28,8 @@ mod kw {
syn::custom_keyword!(witx_literal);
syn::custom_keyword!(ctx);
syn::custom_keyword!(instance);
syn::custom_keyword!(name);
syn::custom_keyword!(docs);
}
impl Parse for ConfigField {
@@ -48,7 +50,7 @@ impl Parse for ConfigField {
} else if lookahead.peek(kw::instance) {
input.parse::<kw::instance>()?;
input.parse::<Token![:]>()?;
Ok(ConfigField::InstanceTypename(input.parse()?))
Ok(ConfigField::Instance(input.parse()?))
} else {
Err(lookahead.error())
}
@@ -59,7 +61,7 @@ impl Config {
pub fn build(fields: impl Iterator<Item = ConfigField>, err_loc: Span) -> Result<Self> {
let mut witx = None;
let mut ctx = None;
let mut instance_typename = None;
let mut instance = None;
for f in fields {
match f {
ConfigField::Witx(c) => {
@@ -74,11 +76,11 @@ impl Config {
}
ctx = Some(c);
}
ConfigField::InstanceTypename(c) => {
if instance_typename.is_some() {
ConfigField::Instance(c) => {
if instance.is_some() {
return Err(Error::new(err_loc, "duplicate `instance` field"));
}
instance_typename = Some(c);
instance = Some(c);
}
}
}
@@ -89,7 +91,7 @@ impl Config {
ctx: ctx
.take()
.ok_or_else(|| Error::new(err_loc, "`ctx` field required"))?,
instance_typename: instance_typename
instance: instance
.take()
.ok_or_else(|| Error::new(err_loc, "`instance` field required"))?,
})
@@ -115,15 +117,70 @@ impl Parse for Config {
}
}
#[derive(Debug, Clone)]
pub struct InstanceTypenameConf {
pub name: Ident,
enum InstanceConfField {
Name(Ident),
Docs(String),
}
impl Parse for InstanceTypenameConf {
impl Parse for InstanceConfField {
fn parse(input: ParseStream) -> Result<Self> {
Ok(InstanceTypenameConf {
name: input.parse()?,
let lookahead = input.lookahead1();
if lookahead.peek(kw::name) {
input.parse::<kw::name>()?;
input.parse::<Token![:]>()?;
Ok(InstanceConfField::Name(input.parse()?))
} else if lookahead.peek(kw::docs) {
input.parse::<kw::docs>()?;
input.parse::<Token![:]>()?;
let docs: syn::LitStr = input.parse()?;
Ok(InstanceConfField::Docs(docs.value()))
} else {
Err(lookahead.error())
}
}
}
#[derive(Debug, Clone)]
pub struct InstanceConf {
pub name: Ident,
pub docs: Option<String>,
}
impl InstanceConf {
fn build(fields: impl Iterator<Item = InstanceConfField>, err_loc: Span) -> Result<Self> {
let mut name = None;
let mut docs = None;
for f in fields {
match f {
InstanceConfField::Name(c) => {
if name.is_some() {
return Err(Error::new(err_loc, "duplicate `name` field"));
}
name = Some(c);
}
InstanceConfField::Docs(c) => {
if docs.is_some() {
return Err(Error::new(err_loc, "duplicate `docs` field"));
}
docs = Some(c);
}
}
}
Ok(InstanceConf {
name: name
.take()
.ok_or_else(|| Error::new(err_loc, "`name` field required"))?,
docs,
})
}
}
impl Parse for InstanceConf {
fn parse(input: ParseStream) -> Result<Self> {
let contents;
let _lbrace = braced!(contents in input);
let fields: Punctuated<InstanceConfField, Token![,]> =
contents.parse_terminated(InstanceConfField::parse)?;
Ok(InstanceConf::build(fields.into_iter(), input.span())?)
}
}

View File

@@ -6,7 +6,7 @@ use wiggle_generate::Names;
mod config;
use config::InstanceTypenameConf;
use config::InstanceConf;
#[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_typename).into()
generate(&doc, &names, &config.instance).into()
}
enum Abi {
@@ -27,11 +27,7 @@ enum Abi {
F64,
}
fn generate(
doc: &witx::Document,
names: &Names,
instance_typename: &InstanceTypenameConf,
) -> TokenStream2 {
fn generate(doc: &witx::Document, names: &Names, instance_conf: &InstanceConf) -> TokenStream2 {
let mut fields = Vec::new();
let mut get_exports = Vec::new();
let mut ctor_externs = Vec::new();
@@ -239,27 +235,31 @@ fn generate(
}
}
let inst_type = instance_typename.name.clone();
let inst_type = instance_conf.name.clone();
let inst_docs = if let Some(ref docs) = instance_conf.docs {
quote!( #[doc = #docs] )
} else {
quote!()
};
let constructor_docs = format!(
"Creates a new [`{}`] instance.
External values are allocated into the `store` provided and
configuration of the wasi instance itself should be all
contained in the `cx` parameter.",
instance_conf.name.to_string()
);
let ctx_type = names.ctx_type();
quote! {
/// An instantiated instance of the wasi exports.
///
/// This represents a wasi module which can be used to instantiate other
/// wasm modules. This structure exports all that various fields of the
/// wasi instance as fields which can be used to implement your own
/// instantiation logic, if necessary. Additionally [`#inst_type::get_export`]
/// can be used to do name-based resolution.
#inst_docs
pub struct #inst_type {
#(#fields,)*
}
impl #inst_type {
/// Creates a new [`#inst_type`] instance.
///
/// External values are allocated into the `store` provided and
/// configuration of the wasi instance itself should be all
/// contained in the `cx` parameter.
#[doc = #constructor_docs]
pub fn new(store: &wasmtime::Store, cx: #ctx_type) -> Self {
let cx = std::rc::Rc::new(std::cell::RefCell::new(cx));
#(#ctor_externs)*
@@ -281,7 +281,7 @@ fn generate(
}
}
/// Adds all wasi items to the specified `Linker`.
/// Adds all instance items to the specified `Linker`.
pub fn add_to_linker(&self, linker: &mut wasmtime::Linker) -> anyhow::Result<()> {
#(#linker_add)*
Ok(())