Browse Source

only wasi_cap_std_sync and wasi_tokio need to define WasiCtxBuilders (#2917)

* wasmtime-wasi: re-exporting this WasiCtxBuilder was shadowing the right one

wasi-common's WasiCtxBuilder is really only useful wasi_cap_std_sync and
wasi_tokio to implement their own Builder on top of.

This re-export of wasi-common's is 1. not useful and 2. shadow's the
re-export of the right one in sync::*.

* wasi-common: eliminate WasiCtxBuilder, make the builder methods on WasiCtx instead

* delete wasi-common::WasiCtxBuilder altogether

just put those methods directly on &mut WasiCtx.

As a bonus, the sync and tokio WasiCtxBuilder::build functions
are no longer fallible!

* bench fixes

* more test fixes
pull/2923/head
Pat Hickey 4 years ago
committed by GitHub
parent
commit
0f5bdc6497
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      benches/instantiation.rs
  2. 2
      crates/bench-api/src/lib.rs
  3. 2
      crates/c-api/src/wasi.rs
  4. 2
      crates/misc/rust/macro/src/lib.rs
  5. 2
      crates/test-programs/tests/wasm_tests/runtime/cap_std_sync.rs
  6. 2
      crates/test-programs/tests/wasm_tests/runtime/tokio.rs
  7. 68
      crates/wasi-common/cap-std-sync/src/lib.rs
  8. 70
      crates/wasi-common/src/ctx.rs
  9. 2
      crates/wasi-common/src/lib.rs
  10. 10
      crates/wasi-common/src/pipe.rs
  11. 74
      crates/wasi-common/tokio/src/lib.rs
  12. 2
      crates/wasi/src/lib.rs
  13. 2
      crates/wasmtime/src/lib.rs
  14. 2
      examples/linking.rs
  15. 2
      examples/tokio/main.rs
  16. 2
      examples/wasi/main.rs
  17. 2
      src/commands/run.rs
  18. 2
      tests/all/host_funcs.rs
  19. 2
      tests/all/traps.rs

2
benches/instantiation.rs

@ -11,7 +11,7 @@ fn instantiate(module: &Module) -> Result<Instance> {
// As we don't actually invoke Wasm code in this benchmark, we still add
// the WASI context to the store as it is considered part of getting a
// module that depends on WASI "ready to run".
Wasi::set_context(&store, WasiCtxBuilder::new().build()?)
Wasi::set_context(&store, WasiCtxBuilder::new().build())
.map_err(|_| anyhow::anyhow!("wasi set_context failed"))?;
let linker = Linker::new(&store);

2
crates/bench-api/src/lib.rs

@ -222,7 +222,7 @@ impl BenchState {
cx = cx.env("WASM_BENCH_USE_SMALL_WORKLOAD", &val)?;
}
Wasi::new(linker.store(), cx.build()?).add_to_linker(&mut linker)?;
Wasi::new(linker.store(), cx.build()).add_to_linker(&mut linker)?;
#[cfg(feature = "wasi-nn")]
{

2
crates/c-api/src/wasi.rs

@ -254,7 +254,7 @@ fn create_wasi_ctx(config: wasi_config_t) -> Result<Rc<RefCell<WasiCtx>>> {
for (dir, path) in config.preopens {
builder = builder.preopened_dir(dir, path)?;
}
Ok(Rc::new(RefCell::new(builder.build()?)))
Ok(Rc::new(RefCell::new(builder.build())))
}
#[repr(C)]

2
crates/misc/rust/macro/src/lib.rs

@ -61,7 +61,7 @@ fn generate_load(item: &syn::ItemTrait) -> syn::Result<TokenStream> {
let mut imports: Vec<Extern> = Vec::new();
if let Some(module_name) = data.find_wasi_module_name() {
let wasi_cx = #root::wasmtime_wasi::WasiCtxBuilder::new().build()?;
let wasi_cx = #root::wasmtime_wasi::WasiCtxBuilder::new().build();
let wasi = #root::wasmtime_wasi::Wasi::new(&store, wasi_cx);
for i in module.imports().iter() {
if i.module() != module_name {

2
crates/test-programs/tests/wasm_tests/runtime/cap_std_sync.rs

@ -53,7 +53,7 @@ fn run(
// cap-std-sync does not yet support the sync family of fdflags
builder = builder.env("NO_FDFLAGS_SYNC_SUPPORT", "1")?;
let wasi = Wasi::new(&store, builder.build()?);
let wasi = Wasi::new(&store, builder.build());
let mut linker = Linker::new(&store);

2
crates/test-programs/tests/wasm_tests/runtime/tokio.rs

@ -62,7 +62,7 @@ fn run(
// does not.
builder = builder.env("NO_FDFLAGS_SYNC_SUPPORT", "1")?;
Wasi::set_context(&store, builder.build()?)
Wasi::set_context(&store, builder.build())
.map_err(|_| anyhow::anyhow!("wasi set_context failed"))?;
let module =

68
crates/wasi-common/cap-std-sync/src/lib.rs

@ -47,61 +47,60 @@ use std::path::Path;
use std::rc::Rc;
use wasi_common::{table::Table, Error, WasiCtx, WasiFile};
pub struct WasiCtxBuilder(wasi_common::WasiCtxBuilder);
pub struct WasiCtxBuilder(WasiCtx);
impl WasiCtxBuilder {
pub fn new() -> Self {
WasiCtxBuilder(WasiCtx::builder(
WasiCtxBuilder(WasiCtx::new(
random_ctx(),
clocks_ctx(),
sched_ctx(),
Rc::new(RefCell::new(Table::new())),
))
}
pub fn env(self, var: &str, value: &str) -> Result<Self, wasi_common::StringArrayError> {
let s = self.0.env(var, value)?;
Ok(WasiCtxBuilder(s))
pub fn env(mut self, var: &str, value: &str) -> Result<Self, wasi_common::StringArrayError> {
self.0.push_env(var, value)?;
Ok(self)
}
pub fn envs(self, env: &[(String, String)]) -> Result<Self, wasi_common::StringArrayError> {
let mut s = self;
pub fn envs(mut self, env: &[(String, String)]) -> Result<Self, wasi_common::StringArrayError> {
for (k, v) in env {
s = s.env(k, v)?;
self.0.push_env(k, v)?;
}
Ok(s)
Ok(self)
}
pub fn inherit_env(self) -> Result<Self, wasi_common::StringArrayError> {
let mut s = self.0;
pub fn inherit_env(mut self) -> Result<Self, wasi_common::StringArrayError> {
for (key, value) in std::env::vars() {
s = s.env(&key, &value)?;
self.0.push_env(&key, &value)?;
}
Ok(WasiCtxBuilder(s))
Ok(self)
}
pub fn arg(self, arg: &str) -> Result<Self, wasi_common::StringArrayError> {
let s = self.0.arg(arg)?;
Ok(WasiCtxBuilder(s))
pub fn arg(mut self, arg: &str) -> Result<Self, wasi_common::StringArrayError> {
self.0.push_arg(arg)?;
Ok(self)
}
pub fn args(self, arg: &[String]) -> Result<Self, wasi_common::StringArrayError> {
let mut s = self;
pub fn args(mut self, arg: &[String]) -> Result<Self, wasi_common::StringArrayError> {
for a in arg {
s = s.arg(&a)?;
self.0.push_arg(&a)?;
}
Ok(s)
Ok(self)
}
pub fn inherit_args(self) -> Result<Self, wasi_common::StringArrayError> {
let mut s = self.0;
pub fn inherit_args(mut self) -> Result<Self, wasi_common::StringArrayError> {
for arg in std::env::args() {
s = s.arg(&arg)?;
self.0.push_arg(&arg)?;
}
Ok(WasiCtxBuilder(s))
Ok(self)
}
pub fn stdin(self, f: Box<dyn WasiFile>) -> Self {
WasiCtxBuilder(self.0.stdin(f))
pub fn stdin(mut self, f: Box<dyn WasiFile>) -> Self {
self.0.set_stdin(f);
self
}
pub fn stdout(self, f: Box<dyn WasiFile>) -> Self {
WasiCtxBuilder(self.0.stdout(f))
pub fn stdout(mut self, f: Box<dyn WasiFile>) -> Self {
self.0.set_stdout(f);
self
}
pub fn stderr(self, f: Box<dyn WasiFile>) -> Self {
WasiCtxBuilder(self.0.stderr(f))
pub fn stderr(mut self, f: Box<dyn WasiFile>) -> Self {
self.0.set_stderr(f);
self
}
pub fn inherit_stdin(self) -> Self {
self.stdin(Box::new(crate::stdio::stdin()))
@ -115,12 +114,13 @@ impl WasiCtxBuilder {
pub fn inherit_stdio(self) -> Self {
self.inherit_stdin().inherit_stdout().inherit_stderr()
}
pub fn preopened_dir(self, dir: Dir, guest_path: impl AsRef<Path>) -> Result<Self, Error> {
pub fn preopened_dir(mut self, dir: Dir, guest_path: impl AsRef<Path>) -> Result<Self, Error> {
let dir = Box::new(crate::dir::Dir::from_cap_std(dir));
Ok(WasiCtxBuilder(self.0.preopened_dir(dir, guest_path)?))
self.0.push_preopened_dir(dir, guest_path)?;
Ok(self)
}
pub fn build(self) -> Result<WasiCtx, Error> {
self.0.build()
pub fn build(self) -> WasiCtx {
self.0
}
}

70
crates/wasi-common/src/ctx.rs

@ -20,20 +20,24 @@ pub struct WasiCtx {
}
impl WasiCtx {
pub fn builder(
pub fn new(
random: RefCell<Box<dyn RngCore>>,
clocks: WasiClocks,
sched: Box<dyn WasiSched>,
table: Rc<RefCell<Table>>,
) -> WasiCtxBuilder {
WasiCtxBuilder(WasiCtx {
) -> Self {
let mut s = WasiCtx {
args: StringArray::new(),
env: StringArray::new(),
random,
clocks,
sched,
table,
})
};
s.set_stdin(Box::new(crate::pipe::ReadPipe::new(std::io::empty())));
s.set_stdout(Box::new(crate::pipe::WritePipe::new(std::io::sink())));
s.set_stderr(Box::new(crate::pipe::WritePipe::new(std::io::sink())));
s
}
pub fn insert_file(&self, fd: u32, file: Box<dyn WasiFile>, caps: FileCaps) {
@ -58,67 +62,41 @@ impl WasiCtx {
pub fn table(&self) -> RefMut<Table> {
self.table.borrow_mut()
}
}
pub struct WasiCtxBuilder(WasiCtx);
impl WasiCtxBuilder {
pub fn build(self) -> Result<WasiCtx, Error> {
use crate::file::TableFileExt;
// Default to an empty readpipe for stdin:
if self.0.table().get_file(0).is_err() {
let stdin = crate::pipe::ReadPipe::new(std::io::empty());
self.0.insert_file(0, Box::new(stdin), FileCaps::all());
}
// Default to a sink writepipe for stdout, stderr:
for stdio_write in &[1, 2] {
if self.0.table().get_file(*stdio_write).is_err() {
let output_file = crate::pipe::WritePipe::new(std::io::sink());
self.0
.insert_file(*stdio_write, Box::new(output_file), FileCaps::all());
}
}
Ok(self.0)
}
pub fn arg(mut self, arg: &str) -> Result<Self, StringArrayError> {
self.0.args.push(arg.to_owned())?;
Ok(self)
pub fn push_arg(&mut self, arg: &str) -> Result<(), StringArrayError> {
self.args.push(arg.to_owned())
}
pub fn env(mut self, var: &str, value: &str) -> Result<Self, StringArrayError> {
self.0.env.push(format!("{}={}", var, value))?;
Ok(self)
pub fn push_env(&mut self, var: &str, value: &str) -> Result<(), StringArrayError> {
self.env.push(format!("{}={}", var, value))?;
Ok(())
}
pub fn stdin(self, f: Box<dyn WasiFile>) -> Self {
self.0.insert_file(0, f, FileCaps::all());
self
pub fn set_stdin(&mut self, f: Box<dyn WasiFile>) {
self.insert_file(0, f, FileCaps::all());
}
pub fn stdout(self, f: Box<dyn WasiFile>) -> Self {
self.0.insert_file(1, f, FileCaps::all());
self
pub fn set_stdout(&mut self, f: Box<dyn WasiFile>) {
self.insert_file(1, f, FileCaps::all());
}
pub fn stderr(self, f: Box<dyn WasiFile>) -> Self {
self.0.insert_file(2, f, FileCaps::all());
self
pub fn set_stderr(&mut self, f: Box<dyn WasiFile>) {
self.insert_file(2, f, FileCaps::all());
}
pub fn preopened_dir(
self,
pub fn push_preopened_dir(
&mut self,
dir: Box<dyn WasiDir>,
path: impl AsRef<Path>,
) -> Result<Self, Error> {
) -> Result<(), Error> {
let caps = DirCaps::all();
let file_caps = FileCaps::all();
self.0.table().push(Box::new(DirEntry::new(
self.table().push(Box::new(DirEntry::new(
caps,
file_caps,
Some(path.as_ref().to_owned()),
dir,
)))?;
Ok(self)
Ok(())
}
}

2
crates/wasi-common/src/lib.rs

@ -64,7 +64,7 @@ pub mod table;
pub use cap_rand::RngCore;
pub use clocks::{SystemTimeSpec, WasiClocks, WasiMonotonicClock, WasiSystemClock};
pub use ctx::{WasiCtx, WasiCtxBuilder};
pub use ctx::WasiCtx;
pub use dir::WasiDir;
pub use error::{Context, Error, ErrorExt, ErrorKind};
pub use file::WasiFile;

10
crates/wasi-common/src/pipe.rs

@ -32,9 +32,8 @@ use std::sync::{Arc, RwLock};
/// let clocks = todo!();
/// let sched = todo!();
/// let table = Rc::new(RefCell::new(Table::new()));
/// let ctx = WasiCtx::builder(random, clocks, sched, table)
/// .stdin(Box::new(stdin.clone()))
/// .build();
/// let mut ctx = WasiCtx::new(random, clocks, sched, table);
/// ctx.set_stdin(Box::new(stdin.clone()));
/// ```
#[derive(Debug)]
pub struct ReadPipe<R: Read> {
@ -203,9 +202,8 @@ impl<R: Read + Any + Send + Sync> WasiFile for ReadPipe<R> {
/// let clocks = todo!();
/// let sched = todo!();
/// let table = Rc::new(RefCell::new(Table::new()));
/// let ctx = WasiCtx::builder(random, clocks, sched, table)
/// .stdout(Box::new(stdout.clone()))
/// .build();
/// let mut ctx = WasiCtx::new(random, clocks, sched, table);
/// ctx.set_stdout(Box::new(stdout.clone()));
/// // use ctx in an instance, then make sure it is dropped:
/// drop(ctx);
/// let contents: Vec<u8> = stdout.try_into_inner().expect("sole remaining reference to WritePipe").into_inner();

74
crates/wasi-common/tokio/src/lib.rs

@ -8,68 +8,67 @@ use std::future::Future;
use std::path::Path;
use std::rc::Rc;
pub use wasi_cap_std_sync::{clocks_ctx, random_ctx};
use wasi_common::{Error, Table, WasiCtx};
use wasi_common::{Error, Table, WasiCtx, WasiFile};
pub use dir::Dir;
pub use file::File;
use crate::sched::sched_ctx;
pub struct WasiCtxBuilder(wasi_common::WasiCtxBuilder);
pub struct WasiCtxBuilder(WasiCtx);
impl WasiCtxBuilder {
pub fn new() -> Self {
WasiCtxBuilder(WasiCtx::builder(
WasiCtxBuilder(WasiCtx::new(
random_ctx(),
clocks_ctx(),
sched_ctx(),
Rc::new(RefCell::new(Table::new())),
))
}
pub fn env(self, var: &str, value: &str) -> Result<Self, wasi_common::StringArrayError> {
let s = self.0.env(var, value)?;
Ok(WasiCtxBuilder(s))
pub fn env(mut self, var: &str, value: &str) -> Result<Self, wasi_common::StringArrayError> {
self.0.push_env(var, value)?;
Ok(self)
}
pub fn envs(self, env: &[(String, String)]) -> Result<Self, wasi_common::StringArrayError> {
let mut s = self;
pub fn envs(mut self, env: &[(String, String)]) -> Result<Self, wasi_common::StringArrayError> {
for (k, v) in env {
s = s.env(k, v)?;
self.0.push_env(k, v)?;
}
Ok(s)
Ok(self)
}
pub fn inherit_env(self) -> Result<Self, wasi_common::StringArrayError> {
let mut s = self.0;
pub fn inherit_env(mut self) -> Result<Self, wasi_common::StringArrayError> {
for (key, value) in std::env::vars() {
s = s.env(&key, &value)?;
self.0.push_env(&key, &value)?;
}
Ok(WasiCtxBuilder(s))
Ok(self)
}
pub fn arg(self, arg: &str) -> Result<Self, wasi_common::StringArrayError> {
let s = self.0.arg(arg)?;
Ok(WasiCtxBuilder(s))
pub fn arg(mut self, arg: &str) -> Result<Self, wasi_common::StringArrayError> {
self.0.push_arg(arg)?;
Ok(self)
}
pub fn args(self, arg: &[String]) -> Result<Self, wasi_common::StringArrayError> {
let mut s = self;
pub fn args(mut self, arg: &[String]) -> Result<Self, wasi_common::StringArrayError> {
for a in arg {
s = s.arg(&a)?;
self.0.push_arg(&a)?;
}
Ok(s)
Ok(self)
}
pub fn inherit_args(self) -> Result<Self, wasi_common::StringArrayError> {
let mut s = self.0;
pub fn inherit_args(mut self) -> Result<Self, wasi_common::StringArrayError> {
for arg in std::env::args() {
s = s.arg(&arg)?;
self.0.push_arg(&arg)?;
}
Ok(WasiCtxBuilder(s))
Ok(self)
}
pub fn stdin(self, f: Box<dyn wasi_common::WasiFile>) -> Self {
WasiCtxBuilder(self.0.stdin(f))
pub fn stdin(mut self, f: Box<dyn WasiFile>) -> Self {
self.0.set_stdin(f);
self
}
pub fn stdout(self, f: Box<dyn wasi_common::WasiFile>) -> Self {
WasiCtxBuilder(self.0.stdout(f))
pub fn stdout(mut self, f: Box<dyn WasiFile>) -> Self {
self.0.set_stdout(f);
self
}
pub fn stderr(self, f: Box<dyn wasi_common::WasiFile>) -> Self {
WasiCtxBuilder(self.0.stderr(f))
pub fn stderr(mut self, f: Box<dyn WasiFile>) -> Self {
self.0.set_stderr(f);
self
}
pub fn inherit_stdin(self) -> Self {
self.stdin(Box::new(crate::stdio::stdin()))
@ -84,15 +83,16 @@ impl WasiCtxBuilder {
self.inherit_stdin().inherit_stdout().inherit_stderr()
}
pub fn preopened_dir(
self,
mut self,
dir: cap_std::fs::Dir,
guest_path: impl AsRef<Path>,
) -> Result<Self, wasi_common::Error> {
let dir = Box::new(Dir::from_cap_std(dir));
Ok(WasiCtxBuilder(self.0.preopened_dir(dir, guest_path)?))
) -> Result<Self, Error> {
let dir = Box::new(crate::dir::Dir::from_cap_std(dir));
self.0.push_preopened_dir(dir, guest_path)?;
Ok(self)
}
pub fn build(self) -> Result<WasiCtx, wasi_common::Error> {
self.0.build()
pub fn build(self) -> WasiCtx {
self.0
}
}

2
crates/wasi/src/lib.rs

@ -7,7 +7,7 @@
//! Individual snapshots are available through
//! `wasmtime_wasi::snapshots::preview_{0, 1}::Wasi::new(&Store, Rc<RefCell<WasiCtx>>)`.
pub use wasi_common::{Error, WasiCtx, WasiCtxBuilder, WasiDir, WasiFile};
pub use wasi_common::{Error, WasiCtx, WasiDir, WasiFile};
/// Re-export the commonly used wasi-cap-std-sync crate here. This saves
/// consumers of this library from having to keep additional dependencies

2
crates/wasmtime/src/lib.rs

@ -202,7 +202,7 @@
//! // Create an instance of `Wasi` which contains a `WasiCtx`. Note that
//! // `WasiCtx` provides a number of ways to configure what the target program
//! // will have access to.
//! let wasi = Wasi::new(&store, WasiCtxBuilder::new().inherit_stdio().build()?);
//! let wasi = Wasi::new(&store, WasiCtxBuilder::new().inherit_stdio().build());
//! wasi.add_to_linker(&mut linker)?;
//!
//! // Instantiate our module with the imports we've created, and run it.

2
examples/linking.rs

@ -18,7 +18,7 @@ fn main() -> Result<()> {
WasiCtxBuilder::new()
.inherit_stdio()
.inherit_args()?
.build()?,
.build(),
);
wasi.add_to_linker(&mut linker)?;

2
examples/tokio/main.rs

@ -146,7 +146,7 @@ async fn _run_wasm(inputs: Inputs) -> Result<(), Error> {
.inherit_stdout()
// Set an environment variable so the wasm knows its name.
.env("NAME", &inputs.name)?
.build()?,
.build(),
)
.map_err(|_| anyhow!("setting wasi context"))?;

2
examples/wasi/main.rs

@ -27,7 +27,7 @@ fn main() -> Result<()> {
WasiCtxBuilder::new()
.inherit_stdio()
.inherit_args()?
.build()?
.build()
)
.is_ok());

2
src/commands/run.rs

@ -371,7 +371,7 @@ fn populate_with_wasi(
}
if wasi_modules.wasi_common {
Wasi::new(linker.store(), builder.build()?).add_to_linker(linker)?;
Wasi::new(linker.store(), builder.build()).add_to_linker(linker)?;
}
if wasi_modules.wasi_nn {

2
tests/all/host_funcs.rs

@ -757,7 +757,7 @@ fn wasi_imports() -> Result<()> {
let engine = Engine::new(&config)?;
let module = Module::new(&engine, wasm)?;
let store = Store::new(&engine);
assert!(Wasi::set_context(&store, WasiCtxBuilder::new().build()?).is_ok());
assert!(Wasi::set_context(&store, WasiCtxBuilder::new().build()).is_ok());
let linker = Linker::new(&store);
let instance = linker.instantiate(&module)?;

2
tests/all/traps.rs

@ -500,7 +500,7 @@ fn parse_dwarf_info() -> Result<()> {
&store,
wasmtime_wasi::sync::WasiCtxBuilder::new()
.inherit_stdio()
.build()?,
.build(),
)
.add_to_linker(&mut linker)?;
linker.module("", &module)?;

Loading…
Cancel
Save