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 <alex@alexcrichton.com>
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2705,6 +2705,7 @@ name = "wiggle-runtime"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"witx",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ filetime = "0.2.7"
|
|||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
num = { version = "0.2.0", default-features = false }
|
num = { version = "0.2.0", default-features = false }
|
||||||
wig = { path = "wig", version = "0.12.0" }
|
wig = { path = "wig", version = "0.12.0" }
|
||||||
wiggle = { path = "../wiggle" }
|
wiggle = { path = "../wiggle", default-features = false }
|
||||||
wiggle-runtime = { path = "../wiggle/crates/runtime" }
|
wiggle-runtime = { path = "../wiggle/crates/runtime" }
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
@@ -34,3 +34,8 @@ cpu-time = "1.0"
|
|||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
maintenance = { status = "actively-developed" }
|
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"]
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ pub mod old;
|
|||||||
mod path;
|
mod path;
|
||||||
mod poll;
|
mod poll;
|
||||||
mod sandboxed_tty_writer;
|
mod sandboxed_tty_writer;
|
||||||
mod snapshots;
|
pub mod snapshots;
|
||||||
mod sys;
|
mod sys;
|
||||||
mod virtfs;
|
mod virtfs;
|
||||||
pub mod wasi;
|
pub mod wasi;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
mod wasi_snapshot_preview1;
|
pub mod wasi_snapshot_preview1;
|
||||||
|
|||||||
@@ -16,10 +16,22 @@ proc-macro = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wiggle-generate = { path = "crates/generate", version = "0.1.0" }
|
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" }
|
witx = { path = "../wasi-common/wig/WASI/tools/witx", version = "0.8.4" }
|
||||||
syn = { version = "1.0", features = ["full"] }
|
syn = { version = "1.0", features = ["full"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
wiggle-runtime = { path = "crates/runtime", version = "0.1.0" }
|
|
||||||
wiggle-test = { path = "crates/test", version = "0.1.0" }
|
wiggle-test = { path = "crates/test", version = "0.1.0" }
|
||||||
proptest = "0.9"
|
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"]
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use syn::{
|
|||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub witx: WitxConf,
|
pub witx: WitxConf,
|
||||||
pub ctx: CtxConf,
|
pub ctx: CtxConf,
|
||||||
|
pub emit_metadata: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -59,6 +60,7 @@ impl Config {
|
|||||||
ctx: ctx
|
ctx: ctx
|
||||||
.take()
|
.take()
|
||||||
.ok_or_else(|| Error::new(err_loc, "`ctx` field required"))?,
|
.ok_or_else(|| Error::new(err_loc, "`ctx` field required"))?,
|
||||||
|
emit_metadata: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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!(
|
quote!(
|
||||||
pub mod types {
|
pub mod types {
|
||||||
#(#types)*
|
#(#types)*
|
||||||
}
|
}
|
||||||
#(#modules)*
|
#(#modules)*
|
||||||
|
#metadata
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ include = ["src/**/*", "LICENSE"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
|
witx = { path = "../../../wasi-common/wig/WASI/tools/witx", version = "0.8.4", optional = true }
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
maintenance = { status = "actively-developed" }
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
wiggle_metadata = ['witx']
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ use std::slice;
|
|||||||
use std::str;
|
use std::str;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
#[cfg(feature = "wiggle_metadata")]
|
||||||
|
pub use witx;
|
||||||
|
|
||||||
mod borrow;
|
mod borrow;
|
||||||
mod error;
|
mod error;
|
||||||
mod guest_type;
|
mod guest_type;
|
||||||
|
|||||||
@@ -87,6 +87,12 @@ pub fn from_witx(args: TokenStream) -> TokenStream {
|
|||||||
config.witx.make_paths_relative_to(
|
config.witx.make_paths_relative_to(
|
||||||
std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR env var"),
|
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");
|
let doc = witx::load(&config.witx.paths).expect("loading witx");
|
||||||
TokenStream::from(wiggle_generate::generate(&doc, &config))
|
TokenStream::from(wiggle_generate::generate(&doc, &config))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,26 @@
|
|||||||
use wiggle_runtime::{GuestBorrows, GuestError, GuestErrorType, GuestPtr};
|
use wiggle_runtime::{GuestBorrows, GuestError, GuestErrorType, GuestPtr};
|
||||||
use wiggle_test::WasiCtx;
|
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!({
|
wiggle::from_witx!({
|
||||||
witx: ["tests/wasi.witx"],
|
witx: ["tests/wasi.witx"],
|
||||||
ctx: WasiCtx,
|
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<T> = std::result::Result<T, types::Errno>;
|
type Result<T> = std::result::Result<T, types::Errno>;
|
||||||
|
|
||||||
impl<'a> GuestErrorType<'a> for types::Errno {
|
impl<'a> GuestErrorType<'a> for types::Errno {
|
||||||
|
|||||||
Reference in New Issue
Block a user