From bc1a11435e2643e30a104d45429b01fcdeea72f4 Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Wed, 25 Mar 2020 12:57:44 -0700 Subject: [PATCH] wiggle: emit a metadata module containing witx document (#1387) * wiggle: emit a metadata module containing witx document * wiggle: put metadata module behind a wiggle_metadata feature * wasi-common: add wiggle_metadata feature and optional witx dep * refactor according to alex's advice * wasi-common: make snapshots pub * wasi-common: i do need a wiggle_metadata feature to be available * Tweak features and such * wiggle: fix tests by passing metadata flag to wiggle-runtime * wiggle: need to move wiggle-runtime to a non-dev dependency so that the feature resolves for external users of the crates Co-authored-by: Alex Crichton --- Cargo.lock | 1 + crates/wasi-common/Cargo.toml | 7 ++++++- crates/wasi-common/src/lib.rs | 2 +- crates/wasi-common/src/snapshots/mod.rs | 2 +- crates/wiggle/Cargo.toml | 14 +++++++++++++- crates/wiggle/crates/generate/src/config.rs | 2 ++ crates/wiggle/crates/generate/src/lib.rs | 15 +++++++++++++++ crates/wiggle/crates/runtime/Cargo.toml | 4 ++++ crates/wiggle/crates/runtime/src/lib.rs | 3 +++ crates/wiggle/src/lib.rs | 6 ++++++ crates/wiggle/tests/wasi.rs | 15 +++++++++++++++ 11 files changed, 67 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab6376f1bc..2adc4dc339 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2705,6 +2705,7 @@ name = "wiggle-runtime" version = "0.1.0" dependencies = [ "thiserror", + "witx", ] [[package]] diff --git a/crates/wasi-common/Cargo.toml b/crates/wasi-common/Cargo.toml index a978e37ca5..88ac6248a0 100644 --- a/crates/wasi-common/Cargo.toml +++ b/crates/wasi-common/Cargo.toml @@ -21,7 +21,7 @@ filetime = "0.2.7" lazy_static = "1.4.0" num = { version = "0.2.0", default-features = false } wig = { path = "wig", version = "0.12.0" } -wiggle = { path = "../wiggle" } +wiggle = { path = "../wiggle", default-features = false } wiggle-runtime = { path = "../wiggle/crates/runtime" } [target.'cfg(unix)'.dependencies] @@ -34,3 +34,8 @@ cpu-time = "1.0" [badges] maintenance = { status = "actively-developed" } + +[features] +# Need to make the wiggle_metadata feature available to consumers of this +# crate if they want the snapshots to have metadata available. +wiggle_metadata = ["wiggle/wiggle_metadata", "wiggle-runtime/wiggle_metadata"] diff --git a/crates/wasi-common/src/lib.rs b/crates/wasi-common/src/lib.rs index 2ba471d02b..5e517fc6c4 100644 --- a/crates/wasi-common/src/lib.rs +++ b/crates/wasi-common/src/lib.rs @@ -31,7 +31,7 @@ pub mod old; mod path; mod poll; mod sandboxed_tty_writer; -mod snapshots; +pub mod snapshots; mod sys; mod virtfs; pub mod wasi; diff --git a/crates/wasi-common/src/snapshots/mod.rs b/crates/wasi-common/src/snapshots/mod.rs index cd093e1013..612db9df66 100644 --- a/crates/wasi-common/src/snapshots/mod.rs +++ b/crates/wasi-common/src/snapshots/mod.rs @@ -1 +1 @@ -mod wasi_snapshot_preview1; +pub mod wasi_snapshot_preview1; diff --git a/crates/wiggle/Cargo.toml b/crates/wiggle/Cargo.toml index 6337d4f0aa..5b27d8bf19 100644 --- a/crates/wiggle/Cargo.toml +++ b/crates/wiggle/Cargo.toml @@ -16,10 +16,22 @@ proc-macro = true [dependencies] wiggle-generate = { path = "crates/generate", version = "0.1.0" } +wiggle-runtime = { path = "crates/runtime", version = "0.1.0" } witx = { path = "../wasi-common/wig/WASI/tools/witx", version = "0.8.4" } syn = { version = "1.0", features = ["full"] } [dev-dependencies] -wiggle-runtime = { path = "crates/runtime", version = "0.1.0" } wiggle-test = { path = "crates/test", version = "0.1.0" } proptest = "0.9" + +[features] +# These features have no effect on the users of this crate. They are only +# necessary for testing. +# The wiggle proc-macro emits some code (inside `pub mod metadata`) guarded +# by the `wiggle_metadata` feature flag. We use this feature flag so that +# users of wiggle are not forced to take a direct dependency on the `witx` +# crate unless they want it. +wiggle_metadata = ["wiggle-runtime/wiggle_metadata"] +# In order to test that the contents of this metadata module meet +# expectations, we must have this feature enabled for the crate by default. +default = ["wiggle_metadata"] diff --git a/crates/wiggle/crates/generate/src/config.rs b/crates/wiggle/crates/generate/src/config.rs index 0d4ada6402..21b3bcec41 100644 --- a/crates/wiggle/crates/generate/src/config.rs +++ b/crates/wiggle/crates/generate/src/config.rs @@ -12,6 +12,7 @@ use syn::{ pub struct Config { pub witx: WitxConf, pub ctx: CtxConf, + pub emit_metadata: bool, } #[derive(Debug, Clone)] @@ -59,6 +60,7 @@ impl Config { ctx: ctx .take() .ok_or_else(|| Error::new(err_loc, "`ctx` field required"))?, + emit_metadata: false, }) } } diff --git a/crates/wiggle/crates/generate/src/lib.rs b/crates/wiggle/crates/generate/src/lib.rs index d253f2604e..e1e4f773df 100644 --- a/crates/wiggle/crates/generate/src/lib.rs +++ b/crates/wiggle/crates/generate/src/lib.rs @@ -35,10 +35,25 @@ pub fn generate(doc: &witx::Document, config: &Config) -> TokenStream { ) }); + let metadata = if config.emit_metadata { + let doc_text = &format!("{}", doc); + quote! { + pub mod metadata { + pub const DOC_TEXT: &str = #doc_text; + pub fn document() -> wiggle_runtime::witx::Document { + wiggle_runtime::witx::parse(DOC_TEXT).unwrap() + } + } + } + } else { + quote!() + }; + quote!( pub mod types { #(#types)* } #(#modules)* + #metadata ) } diff --git a/crates/wiggle/crates/runtime/Cargo.toml b/crates/wiggle/crates/runtime/Cargo.toml index 195380585f..24b8643baf 100644 --- a/crates/wiggle/crates/runtime/Cargo.toml +++ b/crates/wiggle/crates/runtime/Cargo.toml @@ -12,6 +12,10 @@ include = ["src/**/*", "LICENSE"] [dependencies] thiserror = "1" +witx = { path = "../../../wasi-common/wig/WASI/tools/witx", version = "0.8.4", optional = true } [badges] maintenance = { status = "actively-developed" } + +[features] +wiggle_metadata = ['witx'] diff --git a/crates/wiggle/crates/runtime/src/lib.rs b/crates/wiggle/crates/runtime/src/lib.rs index 11b8ff8608..92a913ffda 100644 --- a/crates/wiggle/crates/runtime/src/lib.rs +++ b/crates/wiggle/crates/runtime/src/lib.rs @@ -6,6 +6,9 @@ use std::slice; use std::str; use std::sync::Arc; +#[cfg(feature = "wiggle_metadata")] +pub use witx; + mod borrow; mod error; mod guest_type; diff --git a/crates/wiggle/src/lib.rs b/crates/wiggle/src/lib.rs index 977b85fc0f..16a149eb7d 100644 --- a/crates/wiggle/src/lib.rs +++ b/crates/wiggle/src/lib.rs @@ -87,6 +87,12 @@ pub fn from_witx(args: TokenStream) -> TokenStream { config.witx.make_paths_relative_to( std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR env var"), ); + + #[cfg(feature = "wiggle_metadata")] + { + config.emit_metadata = true; + } + let doc = witx::load(&config.witx.paths).expect("loading witx"); TokenStream::from(wiggle_generate::generate(&doc, &config)) } diff --git a/crates/wiggle/tests/wasi.rs b/crates/wiggle/tests/wasi.rs index df7be73a8e..505c9d7dff 100644 --- a/crates/wiggle/tests/wasi.rs +++ b/crates/wiggle/tests/wasi.rs @@ -1,11 +1,26 @@ use wiggle_runtime::{GuestBorrows, GuestError, GuestErrorType, GuestPtr}; use wiggle_test::WasiCtx; +// This test file exists to make sure that the entire `wasi.witx` file can be +// handled by wiggle, producing code that compiles correctly. +// The trait impls here are never executed, and just exist to validate that the +// witx is exposed with the type signatures that we expect. + wiggle::from_witx!({ witx: ["tests/wasi.witx"], ctx: WasiCtx, }); +// The only test in this file is to verify that the witx document provided by the +// proc macro in the `metadata` module is equal to the document on the disk. +#[test] +fn document_equivelant() { + let macro_doc = metadata::document(); + let disk_doc = witx::load(&["tests/wasi.witx"]).expect("load wasi.witx from disk"); + + assert_eq!(macro_doc, disk_doc); +} + type Result = std::result::Result; impl<'a> GuestErrorType<'a> for types::Errno {