From e7f43b8d21ed4502e91957d93b634b444e173c75 Mon Sep 17 00:00:00 2001
From: Pat Hickey
Date: Thu, 16 Jan 2025 14:07:35 -0800
Subject: [PATCH] wasmtime-wasi: Split a new `IoView` trait off of `WasiView`
(#10016)
* split IoView trait off of WasiView
* move wasi-http over to split views
* config and keyvalue: no changes to libraries, just tests where WasiView used
* wasmtime-cli: fixes for IoView/WasiView split
* move rest of wasi-io impl to be on IoImpl
* wasi-http: linker with wasi IoImpl
* wasi-nn tests: IoView impl
---
crates/wasi-config/src/lib.rs | 6 +-
crates/wasi-config/tests/main.rs | 9 ++-
crates/wasi-http/src/http_impl.rs | 1 +
crates/wasi-http/src/lib.rs | 59 +++++++++-------
crates/wasi-http/src/types.rs | 45 +++++-------
crates/wasi-http/src/types_impl.rs | 2 +-
crates/wasi-http/tests/all/main.rs | 10 ++-
crates/wasi-keyvalue/src/lib.rs | 6 +-
crates/wasi-keyvalue/tests/main.rs | 7 +-
crates/wasi-nn/tests/exec/wit.rs | 9 +--
crates/wasi/src/bindings.rs | 36 ++++++----
crates/wasi/src/ctx.rs | 80 ++-------------------
crates/wasi/src/host/clocks.rs | 2 +-
crates/wasi/src/host/filesystem.rs | 2 +-
crates/wasi/src/host/instance_network.rs | 2 +-
crates/wasi/src/host/io.rs | 34 ++++-----
crates/wasi/src/host/network.rs | 2 +-
crates/wasi/src/host/tcp.rs | 2 +-
crates/wasi/src/host/tcp_create_socket.rs | 2 +-
crates/wasi/src/host/udp.rs | 2 +-
crates/wasi/src/host/udp_create_socket.rs | 2 +-
crates/wasi/src/ip_name_lookup.rs | 2 +-
crates/wasi/src/lib.rs | 41 +++++++----
crates/wasi/src/poll.rs | 24 +++----
crates/wasi/src/preview1.rs | 30 ++++----
crates/wasi/src/stdio.rs | 3 +-
crates/wasi/src/view.rs | 86 +++++++++++++++++++++++
crates/wasi/tests/all/api.rs | 7 +-
crates/wasi/tests/all/main.rs | 6 +-
examples/wasip2-async/main.rs | 9 ++-
examples/wasip2/main.rs | 9 ++-
src/commands/run.rs | 11 ++-
src/commands/serve.rs | 11 ++-
33 files changed, 309 insertions(+), 250 deletions(-)
create mode 100644 crates/wasi/src/view.rs
diff --git a/crates/wasi-config/src/lib.rs b/crates/wasi-config/src/lib.rs
index 8d6906dfde47..ec6f3bd595b0 100644
--- a/crates/wasi-config/src/lib.rs
+++ b/crates/wasi-config/src/lib.rs
@@ -17,7 +17,7 @@
//! component::{Linker, ResourceTable},
//! Config, Engine, Result, Store,
//! };
-//! use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiView};
+//! use wasmtime_wasi::{IoView, WasiCtx, WasiCtxBuilder, WasiView};
//! use wasmtime_wasi_config::{WasiConfig, WasiConfigVariables};
//!
//! #[tokio::main]
@@ -53,8 +53,10 @@
//! wasi_config_vars: WasiConfigVariables,
//! }
//!
-//! impl WasiView for Ctx {
+//! impl IoView for Ctx {
//! fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+//! }
+//! impl WasiView for Ctx {
//! fn ctx(&mut self) -> &mut WasiCtx { &mut self.wasi_ctx }
//! }
//! ```
diff --git a/crates/wasi-config/tests/main.rs b/crates/wasi-config/tests/main.rs
index 6bcb8ec77887..08619d30ec21 100644
--- a/crates/wasi-config/tests/main.rs
+++ b/crates/wasi-config/tests/main.rs
@@ -4,7 +4,9 @@ use wasmtime::{
component::{Component, Linker, ResourceTable},
Store,
};
-use wasmtime_wasi::{add_to_linker_async, bindings::Command, WasiCtx, WasiCtxBuilder, WasiView};
+use wasmtime_wasi::{
+ add_to_linker_async, bindings::Command, IoView, WasiCtx, WasiCtxBuilder, WasiView,
+};
use wasmtime_wasi_config::{WasiConfig, WasiConfigVariables};
struct Ctx {
@@ -13,11 +15,12 @@ struct Ctx {
wasi_config_vars: WasiConfigVariables,
}
-impl WasiView for Ctx {
+impl IoView for Ctx {
fn table(&mut self) -> &mut ResourceTable {
&mut self.table
}
-
+}
+impl WasiView for Ctx {
fn ctx(&mut self) -> &mut WasiCtx {
&mut self.wasi_ctx
}
diff --git a/crates/wasi-http/src/http_impl.rs b/crates/wasi-http/src/http_impl.rs
index 53f3bc33b2be..8850b63f29c6 100644
--- a/crates/wasi-http/src/http_impl.rs
+++ b/crates/wasi-http/src/http_impl.rs
@@ -14,6 +14,7 @@ use bytes::Bytes;
use http_body_util::{BodyExt, Empty};
use hyper::Method;
use wasmtime::component::Resource;
+use wasmtime_wasi::IoView;
impl outgoing_handler::Host for WasiHttpImpl
where
diff --git a/crates/wasi-http/src/lib.rs b/crates/wasi-http/src/lib.rs
index baf4bd6ba98d..9c57a6b6a974 100644
--- a/crates/wasi-http/src/lib.rs
+++ b/crates/wasi-http/src/lib.rs
@@ -71,7 +71,7 @@
//! use tokio::net::TcpListener;
//! use wasmtime::component::{Component, Linker, ResourceTable};
//! use wasmtime::{Config, Engine, Result, Store};
-//! use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiView};
+//! use wasmtime_wasi::{IoView, WasiCtx, WasiCtxBuilder, WasiView};
//! use wasmtime_wasi_http::bindings::ProxyPre;
//! use wasmtime_wasi_http::bindings::http::types::Scheme;
//! use wasmtime_wasi_http::body::HyperOutgoingBody;
@@ -193,23 +193,21 @@
//! http: WasiHttpCtx,
//! table: ResourceTable,
//! }
-//!
+//! impl IoView for MyClientState {
+//! fn table(&mut self) -> &mut ResourceTable {
+//! &mut self.table
+//! }
+//! }
//! impl WasiView for MyClientState {
//! fn ctx(&mut self) -> &mut WasiCtx {
//! &mut self.wasi
//! }
-//! fn table(&mut self) -> &mut ResourceTable {
-//! &mut self.table
-//! }
//! }
//!
//! impl WasiHttpView for MyClientState {
//! fn ctx(&mut self) -> &mut WasiHttpCtx {
//! &mut self.http
//! }
-//! fn table(&mut self) -> &mut ResourceTable {
-//! &mut self.table
-//! }
//! }
//! ```
@@ -236,7 +234,7 @@ pub use crate::types::{
WasiHttpCtx, WasiHttpImpl, WasiHttpView, DEFAULT_OUTGOING_BODY_BUFFER_CHUNKS,
DEFAULT_OUTGOING_BODY_CHUNK_SIZE,
};
-
+use wasmtime_wasi::IoImpl;
/// Add all of the `wasi:http/proxy` world's interfaces to a [`wasmtime::component::Linker`].
///
/// This function will add the `async` variant of all interfaces into the
@@ -251,7 +249,7 @@ pub use crate::types::{
/// ```
/// use wasmtime::{Engine, Result, Config};
/// use wasmtime::component::{ResourceTable, Linker};
-/// use wasmtime_wasi::{WasiCtx, WasiView};
+/// use wasmtime_wasi::{IoView, WasiCtx, WasiView};
/// use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView};
///
/// fn main() -> Result<()> {
@@ -272,25 +270,27 @@ pub use crate::types::{
/// table: ResourceTable,
/// }
///
+/// impl IoView for MyState {
+/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+/// }
/// impl WasiHttpView for MyState {
/// fn ctx(&mut self) -> &mut WasiHttpCtx { &mut self.http_ctx }
-/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
-/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// ```
pub fn add_to_linker_async(l: &mut wasmtime::component::Linker) -> anyhow::Result<()>
where
T: WasiHttpView + wasmtime_wasi::WasiView,
{
- let closure = type_annotate_wasi::(|t| wasmtime_wasi::WasiImpl(t));
+ let io_closure = type_annotate_io::(|t| wasmtime_wasi::IoImpl(t));
+ let closure = type_annotate_wasi::(|t| wasmtime_wasi::WasiImpl(wasmtime_wasi::IoImpl(t)));
wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?;
- wasmtime_wasi::bindings::io::poll::add_to_linker_get_host(l, closure)?;
- wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, closure)?;
- wasmtime_wasi::bindings::io::streams::add_to_linker_get_host(l, closure)?;
+ wasmtime_wasi::bindings::io::poll::add_to_linker_get_host(l, io_closure)?;
+ wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, io_closure)?;
+ wasmtime_wasi::bindings::io::streams::add_to_linker_get_host(l, io_closure)?;
wasmtime_wasi::bindings::cli::stdin::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::cli::stdout::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::cli::stderr::add_to_linker_get_host(l, closure)?;
@@ -313,6 +313,12 @@ where
{
val
}
+fn type_annotate_io(val: F) -> F
+where
+ F: Fn(&mut T) -> wasmtime_wasi::IoImpl<&mut T>,
+{
+ val
+}
/// A slimmed down version of [`add_to_linker_async`] which only adds
/// `wasi:http` interfaces to the linker.
@@ -325,7 +331,7 @@ pub fn add_only_http_to_linker_async(
where
T: WasiHttpView,
{
- let closure = type_annotate_http::(|t| WasiHttpImpl(t));
+ let closure = type_annotate_http::(|t| WasiHttpImpl(IoImpl(t)));
crate::bindings::http::outgoing_handler::add_to_linker_get_host(l, closure)?;
crate::bindings::http::types::add_to_linker_get_host(l, closure)?;
@@ -343,7 +349,7 @@ where
/// ```
/// use wasmtime::{Engine, Result, Config};
/// use wasmtime::component::{ResourceTable, Linker};
-/// use wasmtime_wasi::{WasiCtx, WasiView};
+/// use wasmtime_wasi::{IoView, WasiCtx, WasiView};
/// use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView};
///
/// fn main() -> Result<()> {
@@ -362,27 +368,28 @@ where
/// http_ctx: WasiHttpCtx,
/// table: ResourceTable,
/// }
-///
+/// impl IoView for MyState {
+/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+/// }
/// impl WasiHttpView for MyState {
/// fn ctx(&mut self) -> &mut WasiHttpCtx { &mut self.http_ctx }
-/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
-/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// ```
pub fn add_to_linker_sync(l: &mut wasmtime::component::Linker) -> anyhow::Result<()>
where
T: WasiHttpView + wasmtime_wasi::WasiView,
{
- let closure = type_annotate_wasi::(|t| wasmtime_wasi::WasiImpl(t));
+ let io_closure = type_annotate_io::(|t| wasmtime_wasi::IoImpl(t));
+ let closure = type_annotate_wasi::(|t| wasmtime_wasi::WasiImpl(wasmtime_wasi::IoImpl(t)));
wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?;
- wasmtime_wasi::bindings::sync::io::poll::add_to_linker_get_host(l, closure)?;
- wasmtime_wasi::bindings::sync::io::streams::add_to_linker_get_host(l, closure)?;
- wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, closure)?;
+ wasmtime_wasi::bindings::sync::io::poll::add_to_linker_get_host(l, io_closure)?;
+ wasmtime_wasi::bindings::sync::io::streams::add_to_linker_get_host(l, io_closure)?;
+ wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, io_closure)?;
wasmtime_wasi::bindings::cli::stdin::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::cli::stdout::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::cli::stderr::add_to_linker_get_host(l, closure)?;
@@ -402,7 +409,7 @@ pub fn add_only_http_to_linker_sync(l: &mut wasmtime::component::Linker) -
where
T: WasiHttpView,
{
- let closure = type_annotate_http::(|t| WasiHttpImpl(t));
+ let closure = type_annotate_http::(|t| WasiHttpImpl(IoImpl(t)));
crate::bindings::http::outgoing_handler::add_to_linker_get_host(l, closure)?;
crate::bindings::http::types::add_to_linker_get_host(l, closure)?;
diff --git a/crates/wasi-http/src/types.rs b/crates/wasi-http/src/types.rs
index bb2935f0b820..35bda46f3917 100644
--- a/crates/wasi-http/src/types.rs
+++ b/crates/wasi-http/src/types.rs
@@ -18,7 +18,7 @@ use std::time::Duration;
use tokio::net::TcpStream;
use tokio::time::timeout;
use wasmtime::component::{Resource, ResourceTable};
-use wasmtime_wasi::{runtime::AbortOnDropJoinHandle, Subscribe};
+use wasmtime_wasi::{runtime::AbortOnDropJoinHandle, IoImpl, IoView, Subscribe};
/// Capture the state necessary for use in the wasi-http API implementation.
#[derive(Debug)]
@@ -39,7 +39,7 @@ impl WasiHttpCtx {
///
/// ```
/// use wasmtime::component::ResourceTable;
-/// use wasmtime_wasi::{WasiCtx, WasiView, WasiCtxBuilder};
+/// use wasmtime_wasi::{IoView, WasiCtx, WasiView, WasiCtxBuilder};
/// use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView};
///
/// struct MyState {
@@ -48,14 +48,15 @@ impl WasiHttpCtx {
/// table: ResourceTable,
/// }
///
+/// impl IoView for MyState {
+/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+/// }
/// impl WasiHttpView for MyState {
/// fn ctx(&mut self) -> &mut WasiHttpCtx { &mut self.http_ctx }
-/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
///
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
-/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
///
/// impl MyState {
@@ -73,13 +74,10 @@ impl WasiHttpCtx {
/// }
/// }
/// ```
-pub trait WasiHttpView: Send {
+pub trait WasiHttpView: IoView {
/// Returns a mutable reference to the WASI HTTP context.
fn ctx(&mut self) -> &mut WasiHttpCtx;
- /// Returns a mutable reference to the WASI HTTP resource table.
- fn table(&mut self) -> &mut ResourceTable;
-
/// Create a new incoming request resource.
fn new_incoming_request(
&mut self,
@@ -150,10 +148,6 @@ impl WasiHttpView for &mut T {
T::ctx(self)
}
- fn table(&mut self) -> &mut ResourceTable {
- T::table(self)
- }
-
fn new_response_outparam(
&mut self,
result: tokio::sync::oneshot::Sender<
@@ -189,10 +183,6 @@ impl WasiHttpView for Box {
T::ctx(self)
}
- fn table(&mut self) -> &mut ResourceTable {
- T::table(self)
- }
-
fn new_response_outparam(
&mut self,
result: tokio::sync::oneshot::Sender<
@@ -236,15 +226,16 @@ impl WasiHttpView for Box {
/// [`add_to_linker_sync`](crate::add_to_linker_sync)
/// and doesn't need to be manually configured.
#[repr(transparent)]
-pub struct WasiHttpImpl(pub T);
+pub struct WasiHttpImpl(pub IoImpl);
+impl IoView for WasiHttpImpl {
+ fn table(&mut self) -> &mut ResourceTable {
+ T::table(&mut self.0 .0)
+ }
+}
impl WasiHttpView for WasiHttpImpl {
fn ctx(&mut self) -> &mut WasiHttpCtx {
- self.0.ctx()
- }
-
- fn table(&mut self) -> &mut ResourceTable {
- self.0.table()
+ self.0 .0.ctx()
}
fn new_response_outparam(
@@ -253,7 +244,7 @@ impl WasiHttpView for WasiHttpImpl {
Result, types::ErrorCode>,
>,
) -> wasmtime::Result> {
- self.0.new_response_outparam(result)
+ self.0 .0.new_response_outparam(result)
}
fn send_request(
@@ -261,19 +252,19 @@ impl WasiHttpView for WasiHttpImpl {
request: hyper::Request,
config: OutgoingRequestConfig,
) -> crate::HttpResult {
- self.0.send_request(request, config)
+ self.0 .0.send_request(request, config)
}
fn is_forbidden_header(&mut self, name: &HeaderName) -> bool {
- self.0.is_forbidden_header(name)
+ self.0 .0.is_forbidden_header(name)
}
fn outgoing_body_buffer_chunks(&mut self) -> usize {
- self.0.outgoing_body_buffer_chunks()
+ self.0 .0.outgoing_body_buffer_chunks()
}
fn outgoing_body_chunk_size(&mut self) -> usize {
- self.0.outgoing_body_chunk_size()
+ self.0 .0.outgoing_body_chunk_size()
}
}
diff --git a/crates/wasi-http/src/types_impl.rs b/crates/wasi-http/src/types_impl.rs
index 337c1a3c76f7..f3a83f85d6d7 100644
--- a/crates/wasi-http/src/types_impl.rs
+++ b/crates/wasi-http/src/types_impl.rs
@@ -16,7 +16,7 @@ use std::str::FromStr;
use wasmtime::component::{Resource, ResourceTable};
use wasmtime_wasi::{
bindings::io::streams::{InputStream, OutputStream},
- Pollable, ResourceTableError,
+ IoView, Pollable, ResourceTableError,
};
impl crate::bindings::http::types::Host for WasiHttpImpl
diff --git a/crates/wasi-http/tests/all/main.rs b/crates/wasi-http/tests/all/main.rs
index 418ba66d4c35..0f6c1d7cf432 100644
--- a/crates/wasi-http/tests/all/main.rs
+++ b/crates/wasi-http/tests/all/main.rs
@@ -11,7 +11,7 @@ use wasmtime::{
component::{Component, Linker, ResourceTable},
Config, Engine, Store,
};
-use wasmtime_wasi::{self, pipe::MemoryOutputPipe, WasiCtx, WasiCtxBuilder, WasiView};
+use wasmtime_wasi::{self, pipe::MemoryOutputPipe, IoView, WasiCtx, WasiCtxBuilder, WasiView};
use wasmtime_wasi_http::{
bindings::http::types::{ErrorCode, Scheme},
body::HyperOutgoingBody,
@@ -38,10 +38,12 @@ struct Ctx {
rejected_authority: Option,
}
-impl WasiView for Ctx {
+impl IoView for Ctx {
fn table(&mut self) -> &mut ResourceTable {
&mut self.table
}
+}
+impl WasiView for Ctx {
fn ctx(&mut self) -> &mut WasiCtx {
&mut self.wasi
}
@@ -52,10 +54,6 @@ impl WasiHttpView for Ctx {
&mut self.http
}
- fn table(&mut self) -> &mut ResourceTable {
- &mut self.table
- }
-
fn send_request(
&mut self,
request: hyper::Request,
diff --git a/crates/wasi-keyvalue/src/lib.rs b/crates/wasi-keyvalue/src/lib.rs
index 4d53a9acf20b..ce8d5b276984 100644
--- a/crates/wasi-keyvalue/src/lib.rs
+++ b/crates/wasi-keyvalue/src/lib.rs
@@ -20,7 +20,7 @@
//! component::{Linker, ResourceTable},
//! Config, Engine, Result, Store,
//! };
-//! use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiView};
+//! use wasmtime_wasi::{IoView, WasiCtx, WasiCtxBuilder, WasiView};
//! use wasmtime_wasi_keyvalue::{WasiKeyValue, WasiKeyValueCtx, WasiKeyValueCtxBuilder};
//!
//! #[tokio::main]
@@ -53,8 +53,10 @@
//! wasi_keyvalue_ctx: WasiKeyValueCtx,
//! }
//!
-//! impl WasiView for Ctx {
+//! impl IoView for Ctx {
//! fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+//! }
+//! impl WasiView for Ctx {
//! fn ctx(&mut self) -> &mut WasiCtx { &mut self.wasi_ctx }
//! }
//! ```
diff --git a/crates/wasi-keyvalue/tests/main.rs b/crates/wasi-keyvalue/tests/main.rs
index 6ae8eee18a56..5d0b6bf4a07e 100644
--- a/crates/wasi-keyvalue/tests/main.rs
+++ b/crates/wasi-keyvalue/tests/main.rs
@@ -4,7 +4,7 @@ use wasmtime::{
component::{Component, Linker, ResourceTable},
Store,
};
-use wasmtime_wasi::{bindings::Command, WasiCtx, WasiCtxBuilder, WasiView};
+use wasmtime_wasi::{bindings::Command, IoView, WasiCtx, WasiCtxBuilder, WasiView};
use wasmtime_wasi_keyvalue::{WasiKeyValue, WasiKeyValueCtx, WasiKeyValueCtxBuilder};
struct Ctx {
@@ -13,11 +13,12 @@ struct Ctx {
wasi_keyvalue_ctx: WasiKeyValueCtx,
}
-impl WasiView for Ctx {
+impl IoView for Ctx {
fn table(&mut self) -> &mut ResourceTable {
&mut self.table
}
-
+}
+impl WasiView for Ctx {
fn ctx(&mut self) -> &mut WasiCtx {
&mut self.wasi_ctx
}
diff --git a/crates/wasi-nn/tests/exec/wit.rs b/crates/wasi-nn/tests/exec/wit.rs
index 5f2d546d667d..21a756c4ddf8 100644
--- a/crates/wasi-nn/tests/exec/wit.rs
+++ b/crates/wasi-nn/tests/exec/wit.rs
@@ -62,12 +62,13 @@ impl Ctx {
}
}
+impl wasmtime_wasi::IoView for Ctx {
+ fn table(&mut self) -> &mut ResourceTable {
+ &mut self.table
+ }
+}
impl wasmtime_wasi::WasiView for Ctx {
fn ctx(&mut self) -> &mut WasiCtx {
&mut self.wasi
}
-
- fn table(&mut self) -> &mut ResourceTable {
- &mut self.table
- }
}
diff --git a/crates/wasi/src/bindings.rs b/crates/wasi/src/bindings.rs
index cefeec980ce3..7449b3a3f202 100644
--- a/crates/wasi/src/bindings.rs
+++ b/crates/wasi/src/bindings.rs
@@ -15,7 +15,7 @@
//! done using the `with` option to [`bindgen!`]:
//!
//! ```rust
-//! use wasmtime_wasi::{WasiCtx, ResourceTable, WasiView};
+//! use wasmtime_wasi::{IoView, WasiCtx, ResourceTable, WasiView};
//! use wasmtime::{Result, Engine, Config};
//! use wasmtime::component::Linker;
//!
@@ -53,8 +53,10 @@
//! }
//! }
//!
-//! impl WasiView for MyState {
+//! impl IoView for MyState {
//! fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+//! }
+//! impl WasiView for MyState {
//! fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
//! }
//!
@@ -84,7 +86,7 @@
/// done using the `with` option to `bindgen!`:
///
/// ```rust
-/// use wasmtime_wasi::{WasiCtx, ResourceTable, WasiView};
+/// use wasmtime_wasi::{IoView, WasiCtx, ResourceTable, WasiView};
/// use wasmtime::{Result, Engine};
/// use wasmtime::component::Linker;
///
@@ -124,8 +126,10 @@
/// }
/// }
///
-/// impl WasiView for MyState {
+/// impl IoView for MyState {
/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+/// }
+/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
/// }
///
@@ -201,7 +205,7 @@ pub mod sync {
/// ```no_run
/// use wasmtime::{Engine, Result, Store, Config};
/// use wasmtime::component::{ResourceTable, Linker, Component};
- /// use wasmtime_wasi::{WasiCtx, WasiView, WasiCtxBuilder};
+ /// use wasmtime_wasi::{IoView, WasiCtx, WasiView, WasiCtxBuilder};
/// use wasmtime_wasi::bindings::sync::Command;
///
/// // This example is an example shim of executing a component based on the
@@ -245,9 +249,11 @@ pub mod sync {
/// table: ResourceTable,
/// }
///
+ /// impl IoView for MyState {
+ /// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+ /// }
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
- /// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// ```
///
@@ -264,7 +270,7 @@ pub mod sync {
/// ```no_run
/// use wasmtime::{Engine, Result, Store, Config};
/// use wasmtime::component::{ResourceTable, Linker, Component};
- /// use wasmtime_wasi::{WasiCtx, WasiView, WasiCtxBuilder};
+ /// use wasmtime_wasi::{IoView, WasiCtx, WasiView, WasiCtxBuilder};
/// use wasmtime_wasi::bindings::sync::CommandPre;
///
/// // This example is an example shim of executing a component based on the
@@ -309,9 +315,11 @@ pub mod sync {
/// table: ResourceTable,
/// }
///
+ /// impl IoView for MyState {
+ /// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+ /// }
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
- /// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// ```
///
@@ -439,7 +447,7 @@ pub use self::async_io::LinkOptions;
/// ```no_run
/// use wasmtime::{Engine, Result, Store, Config};
/// use wasmtime::component::{ResourceTable, Linker, Component};
-/// use wasmtime_wasi::{WasiCtx, WasiView, WasiCtxBuilder};
+/// use wasmtime_wasi::{IoView, WasiCtx, WasiView, WasiCtxBuilder};
/// use wasmtime_wasi::bindings::Command;
///
/// // This example is an example shim of executing a component based on the
@@ -486,9 +494,11 @@ pub use self::async_io::LinkOptions;
/// table: ResourceTable,
/// }
///
+/// impl IoView for MyState {
+/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+/// }
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
-/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// ```
///
@@ -505,7 +515,7 @@ pub use self::async_io::Command;
/// ```no_run
/// use wasmtime::{Engine, Result, Store, Config};
/// use wasmtime::component::{ResourceTable, Linker, Component};
-/// use wasmtime_wasi::{WasiCtx, WasiView, WasiCtxBuilder};
+/// use wasmtime_wasi::{IoView, WasiCtx, WasiView, WasiCtxBuilder};
/// use wasmtime_wasi::bindings::CommandPre;
///
/// // This example is an example shim of executing a component based on the
@@ -553,9 +563,11 @@ pub use self::async_io::Command;
/// table: ResourceTable,
/// }
///
+/// impl IoView for MyState {
+/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+/// }
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
-/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// ```
///
diff --git a/crates/wasi/src/ctx.rs b/crates/wasi/src/ctx.rs
index d7a5c4156ae0..b86895712a9e 100644
--- a/crates/wasi/src/ctx.rs
+++ b/crates/wasi/src/ctx.rs
@@ -16,7 +16,6 @@ use std::path::Path;
use std::sync::Arc;
use std::{future::Future, pin::Pin};
use std::{mem, net::SocketAddr};
-use wasmtime::component::ResourceTable;
/// Builder-style structure used to create a [`WasiCtx`].
///
@@ -525,36 +524,23 @@ impl WasiCtxBuilder {
}
}
-/// A trait which provides access to internal WASI state.
-///
-/// This trait is the basis of implementation of all traits in this crate. All
-/// traits are implemented like:
-///
-/// ```
-/// # trait WasiView {}
-/// # mod bindings { pub mod wasi { pub trait Host {} } }
-/// impl bindings::wasi::Host for T {
-/// // ...
-/// }
-/// ```
-///
-/// For a [`Store`](wasmtime::Store) this trait will be implemented
-/// for the `T`. This also corresponds to the `T` in
-/// [`Linker`](wasmtime::component::Linker).
+/// A struct which provides access to internal WASI state.
///
/// # Example
///
/// ```
-/// use wasmtime_wasi::{WasiCtx, ResourceTable, WasiView, WasiCtxBuilder};
+/// use wasmtime_wasi::{WasiCtx, ResourceTable, WasiView, IoView, WasiCtxBuilder};
///
/// struct MyState {
/// ctx: WasiCtx,
/// table: ResourceTable,
/// }
///
+/// impl IoView for MyState {
+/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+/// }
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
-/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
///
/// impl MyState {
@@ -571,62 +557,6 @@ impl WasiCtxBuilder {
/// }
/// }
/// ```
-pub trait WasiView: Send {
- /// Yields mutable access to the internal resource management that this
- /// context contains.
- ///
- /// Embedders can add custom resources to this table as well to give
- /// resources to wasm as well.
- fn table(&mut self) -> &mut ResourceTable;
-
- /// Yields mutable access to the configuration used for this context.
- ///
- /// The returned type is created through [`WasiCtxBuilder`].
- fn ctx(&mut self) -> &mut WasiCtx;
-}
-
-impl WasiView for &mut T {
- fn table(&mut self) -> &mut ResourceTable {
- T::table(self)
- }
- fn ctx(&mut self) -> &mut WasiCtx {
- T::ctx(self)
- }
-}
-
-impl WasiView for Box {
- fn table(&mut self) -> &mut ResourceTable {
- T::table(self)
- }
- fn ctx(&mut self) -> &mut WasiCtx {
- T::ctx(self)
- }
-}
-
-/// A small newtype wrapper which serves as the basis for implementations of
-/// `Host` WASI traits in this crate.
-///
-/// This type is used as the basis for the implementation of all `Host` traits
-/// generated by `bindgen!` for WASI interfaces. This is used automatically with
-/// [`add_to_linker_sync`](crate::add_to_linker_sync) and
-/// [`add_to_linker_async`](crate::add_to_linker_async).
-///
-/// This type is otherwise provided if you're calling the `add_to_linker`
-/// functions generated by `bindgen!` from the [`bindings`
-/// module](crate::bindings). In this situation you'll want to create a value of
-/// this type in the closures added to a `Linker`.
-#[repr(transparent)]
-pub struct WasiImpl(pub T);
-
-impl WasiView for WasiImpl {
- fn table(&mut self) -> &mut ResourceTable {
- T::table(&mut self.0)
- }
- fn ctx(&mut self) -> &mut WasiCtx {
- T::ctx(&mut self.0)
- }
-}
-
/// Per-[`Store`] state which holds state necessary to implement WASI from this
/// crate.
///
diff --git a/crates/wasi/src/host/clocks.rs b/crates/wasi/src/host/clocks.rs
index e94ca98555ff..feefb9473b27 100644
--- a/crates/wasi/src/host/clocks.rs
+++ b/crates/wasi/src/host/clocks.rs
@@ -5,7 +5,7 @@ use crate::bindings::{
clocks::wall_clock::{self, Datetime},
};
use crate::poll::{subscribe, Subscribe};
-use crate::{Pollable, WasiImpl, WasiView};
+use crate::{IoView, Pollable, WasiImpl, WasiView};
use cap_std::time::SystemTime;
use std::time::Duration;
use wasmtime::component::Resource;
diff --git a/crates/wasi/src/host/filesystem.rs b/crates/wasi/src/host/filesystem.rs
index 2d31e5c53fc4..a8cfb91754f3 100644
--- a/crates/wasi/src/host/filesystem.rs
+++ b/crates/wasi/src/host/filesystem.rs
@@ -7,7 +7,7 @@ use crate::bindings::io::streams::{InputStream, OutputStream};
use crate::filesystem::{
Descriptor, Dir, File, FileInputStream, FileOutputStream, OpenMode, ReaddirIterator,
};
-use crate::{DirPerms, FilePerms, FsError, FsResult, WasiImpl, WasiView};
+use crate::{DirPerms, FilePerms, FsError, FsResult, IoView, WasiImpl, WasiView};
use anyhow::Context;
use wasmtime::component::Resource;
diff --git a/crates/wasi/src/host/instance_network.rs b/crates/wasi/src/host/instance_network.rs
index edf097d8679c..d6b06718a8d0 100644
--- a/crates/wasi/src/host/instance_network.rs
+++ b/crates/wasi/src/host/instance_network.rs
@@ -1,6 +1,6 @@
use crate::bindings::sockets::instance_network;
use crate::network::Network;
-use crate::{WasiImpl, WasiView};
+use crate::{IoView, WasiImpl, WasiView};
use wasmtime::component::Resource;
impl instance_network::Host for WasiImpl
diff --git a/crates/wasi/src/host/io.rs b/crates/wasi/src/host/io.rs
index 35a2e8e63aa9..5ad1a65e84da 100644
--- a/crates/wasi/src/host/io.rs
+++ b/crates/wasi/src/host/io.rs
@@ -2,15 +2,15 @@ use crate::{
bindings::io::error,
bindings::io::streams::{self, InputStream, OutputStream},
poll::subscribe,
- Pollable, StreamError, StreamResult, WasiImpl, WasiView,
+ IoImpl, IoView, Pollable, StreamError, StreamResult,
};
use wasmtime::component::Resource;
-impl error::Host for WasiImpl where T: WasiView {}
+impl error::Host for IoImpl where T: IoView {}
-impl streams::Host for WasiImpl
+impl streams::Host for IoImpl
where
- T: WasiView,
+ T: IoView,
{
fn convert_stream_error(&mut self, err: StreamError) -> anyhow::Result {
match err {
@@ -23,9 +23,9 @@ where
}
}
-impl error::HostError for WasiImpl
+impl error::HostError for IoImpl
where
- T: WasiView,
+ T: IoView,
{
fn drop(&mut self, err: Resource) -> anyhow::Result<()> {
self.table().delete(err)?;
@@ -37,9 +37,9 @@ where
}
}
-impl streams::HostOutputStream for WasiImpl
+impl streams::HostOutputStream for IoImpl
where
- T: WasiView,
+ T: IoView,
{
async fn drop(&mut self, stream: Resource) -> anyhow::Result<()> {
self.table().delete(stream)?.cancel().await;
@@ -170,9 +170,9 @@ where
}
}
-impl streams::HostInputStream for WasiImpl
+impl streams::HostInputStream for IoImpl
where
- T: WasiView,
+ T: IoView,
{
async fn drop(&mut self, stream: Resource) -> anyhow::Result<()> {
self.table().delete(stream)?.cancel().await;
@@ -227,7 +227,7 @@ pub mod sync {
bindings::sync::io::poll::Pollable,
bindings::sync::io::streams::{self, InputStream, OutputStream},
runtime::in_tokio,
- StreamError, StreamResult, WasiImpl, WasiView,
+ IoImpl, IoView, StreamError, StreamResult,
};
use wasmtime::component::Resource;
@@ -240,9 +240,9 @@ pub mod sync {
}
}
- impl streams::Host for WasiImpl
+ impl streams::Host for IoImpl
where
- T: WasiView,
+ T: IoView,
{
fn convert_stream_error(
&mut self,
@@ -252,9 +252,9 @@ pub mod sync {
}
}
- impl streams::HostOutputStream for WasiImpl
+ impl streams::HostOutputStream for IoImpl
where
- T: WasiView,
+ T: IoView,
{
fn drop(&mut self, stream: Resource) -> anyhow::Result<()> {
in_tokio(async { AsyncHostOutputStream::drop(self, stream).await })
@@ -332,9 +332,9 @@ pub mod sync {
}
}
- impl streams::HostInputStream for WasiImpl
+ impl streams::HostInputStream for IoImpl
where
- T: WasiView,
+ T: IoView,
{
fn drop(&mut self, stream: Resource) -> anyhow::Result<()> {
in_tokio(async { AsyncHostInputStream::drop(self, stream).await })
diff --git a/crates/wasi/src/host/network.rs b/crates/wasi/src/host/network.rs
index 110d4117502c..e7de7e92b656 100644
--- a/crates/wasi/src/host/network.rs
+++ b/crates/wasi/src/host/network.rs
@@ -3,7 +3,7 @@ use crate::bindings::sockets::network::{
Ipv6SocketAddress,
};
use crate::network::{from_ipv4_addr, from_ipv6_addr, to_ipv4_addr, to_ipv6_addr};
-use crate::{SocketError, WasiImpl, WasiView};
+use crate::{IoView, SocketError, WasiImpl, WasiView};
use anyhow::Error;
use rustix::io::Errno;
use std::io;
diff --git a/crates/wasi/src/host/tcp.rs b/crates/wasi/src/host/tcp.rs
index 160cb8a757c0..04bfafd7141a 100644
--- a/crates/wasi/src/host/tcp.rs
+++ b/crates/wasi/src/host/tcp.rs
@@ -7,7 +7,7 @@ use crate::{
},
network::SocketAddressFamily,
};
-use crate::{Pollable, SocketResult, WasiImpl, WasiView};
+use crate::{IoView, Pollable, SocketResult, WasiImpl, WasiView};
use std::net::SocketAddr;
use std::time::Duration;
use wasmtime::component::Resource;
diff --git a/crates/wasi/src/host/tcp_create_socket.rs b/crates/wasi/src/host/tcp_create_socket.rs
index eadacce05b58..4c846295f552 100644
--- a/crates/wasi/src/host/tcp_create_socket.rs
+++ b/crates/wasi/src/host/tcp_create_socket.rs
@@ -1,6 +1,6 @@
use crate::bindings::{sockets::network::IpAddressFamily, sockets::tcp_create_socket};
use crate::tcp::TcpSocket;
-use crate::{SocketResult, WasiImpl, WasiView};
+use crate::{IoView, SocketResult, WasiImpl, WasiView};
use wasmtime::component::Resource;
impl tcp_create_socket::Host for WasiImpl
diff --git a/crates/wasi/src/host/udp.rs b/crates/wasi/src/host/udp.rs
index 3dd73ff6ffe3..98f1a5644da6 100644
--- a/crates/wasi/src/host/udp.rs
+++ b/crates/wasi/src/host/udp.rs
@@ -8,7 +8,7 @@ use crate::{
udp::{IncomingDatagramStream, OutgoingDatagramStream, SendState, UdpState},
Subscribe,
};
-use crate::{Pollable, SocketError, SocketResult, WasiImpl, WasiView};
+use crate::{IoView, Pollable, SocketError, SocketResult, WasiImpl, WasiView};
use anyhow::anyhow;
use async_trait::async_trait;
use io_lifetimes::AsSocketlike;
diff --git a/crates/wasi/src/host/udp_create_socket.rs b/crates/wasi/src/host/udp_create_socket.rs
index f27b574b99ee..533b4d7d5c92 100644
--- a/crates/wasi/src/host/udp_create_socket.rs
+++ b/crates/wasi/src/host/udp_create_socket.rs
@@ -1,6 +1,6 @@
use crate::bindings::{sockets::network::IpAddressFamily, sockets::udp_create_socket};
use crate::udp::UdpSocket;
-use crate::{SocketResult, WasiImpl, WasiView};
+use crate::{IoView, SocketResult, WasiImpl, WasiView};
use wasmtime::component::Resource;
impl udp_create_socket::Host for WasiImpl
diff --git a/crates/wasi/src/ip_name_lookup.rs b/crates/wasi/src/ip_name_lookup.rs
index e013cefb01fc..8ed47b0d1e50 100644
--- a/crates/wasi/src/ip_name_lookup.rs
+++ b/crates/wasi/src/ip_name_lookup.rs
@@ -3,7 +3,7 @@ use crate::bindings::sockets::network::{ErrorCode, IpAddress, Network};
use crate::host::network::util;
use crate::poll::{subscribe, Pollable, Subscribe};
use crate::runtime::{spawn_blocking, AbortOnDropJoinHandle};
-use crate::{SocketError, WasiImpl, WasiView};
+use crate::{IoView, SocketError, WasiImpl, WasiView};
use anyhow::Result;
use std::mem;
use std::net::{Ipv6Addr, ToSocketAddrs};
diff --git a/crates/wasi/src/lib.rs b/crates/wasi/src/lib.rs
index a19c6c42ba6d..58375b784f70 100644
--- a/crates/wasi/src/lib.rs
+++ b/crates/wasi/src/lib.rs
@@ -205,10 +205,11 @@ mod stdio;
mod stream;
mod tcp;
mod udp;
+mod view;
mod write_stream;
pub use self::clocks::{HostMonotonicClock, HostWallClock};
-pub use self::ctx::{WasiCtx, WasiCtxBuilder, WasiImpl, WasiView};
+pub use self::ctx::{WasiCtx, WasiCtxBuilder};
pub use self::error::{I32Exit, TrappableError};
pub use self::filesystem::{DirPerms, FileInputStream, FilePerms, FsError, FsResult};
pub use self::network::{Network, SocketAddrUse, SocketError, SocketResult};
@@ -221,6 +222,7 @@ pub use self::stdio::{
pub use self::stream::{
HostInputStream, HostOutputStream, InputStream, OutputStream, StreamError, StreamResult,
};
+pub use self::view::{IoImpl, IoView, WasiImpl, WasiView};
#[doc(no_inline)]
pub use async_trait::async_trait;
#[doc(no_inline)]
@@ -248,7 +250,7 @@ pub use wasmtime::component::{ResourceTable, ResourceTableError};
/// ```
/// use wasmtime::{Engine, Result, Store, Config};
/// use wasmtime::component::{ResourceTable, Linker};
-/// use wasmtime_wasi::{WasiCtx, WasiView, WasiCtxBuilder};
+/// use wasmtime_wasi::{IoView, WasiCtx, WasiView, WasiCtxBuilder};
///
/// fn main() -> Result<()> {
/// let mut config = Config::new();
@@ -281,9 +283,11 @@ pub use wasmtime::component::{ResourceTable, ResourceTableError};
/// table: ResourceTable,
/// }
///
+/// impl IoView for MyState {
+/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+/// }
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
-/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// ```
pub fn add_to_linker_async(linker: &mut Linker) -> anyhow::Result<()> {
@@ -297,15 +301,16 @@ pub fn add_to_linker_with_options_async(
options: &crate::bindings::LinkOptions,
) -> anyhow::Result<()> {
let l = linker;
- let closure = type_annotate::(|t| WasiImpl(t));
+ let io_closure = io_type_annotate::(|t| IoImpl(t));
+ let closure = type_annotate::(|t| WasiImpl(IoImpl(t)));
crate::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?;
crate::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?;
crate::bindings::filesystem::types::add_to_linker_get_host(l, closure)?;
crate::bindings::filesystem::preopens::add_to_linker_get_host(l, closure)?;
- crate::bindings::io::error::add_to_linker_get_host(l, closure)?;
- crate::bindings::io::poll::add_to_linker_get_host(l, closure)?;
- crate::bindings::io::streams::add_to_linker_get_host(l, closure)?;
+ crate::bindings::io::error::add_to_linker_get_host(l, io_closure)?;
+ crate::bindings::io::poll::add_to_linker_get_host(l, io_closure)?;
+ crate::bindings::io::streams::add_to_linker_get_host(l, io_closure)?;
crate::bindings::random::random::add_to_linker_get_host(l, closure)?;
crate::bindings::random::insecure::add_to_linker_get_host(l, closure)?;
crate::bindings::random::insecure_seed::add_to_linker_get_host(l, closure)?;
@@ -347,7 +352,7 @@ pub fn add_to_linker_with_options_async(
/// ```
/// use wasmtime::{Engine, Result, Store, Config};
/// use wasmtime::component::{ResourceTable, Linker};
-/// use wasmtime_wasi::{WasiCtx, WasiView, WasiCtxBuilder};
+/// use wasmtime_wasi::{IoView, WasiCtx, WasiView, WasiCtxBuilder};
///
/// fn main() -> Result<()> {
/// let engine = Engine::default();
@@ -377,10 +382,11 @@ pub fn add_to_linker_with_options_async(
/// ctx: WasiCtx,
/// table: ResourceTable,
/// }
-///
+/// impl IoView for MyState {
+/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
+/// }
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
-/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// ```
pub fn add_to_linker_sync(
@@ -396,15 +402,16 @@ pub fn add_to_linker_with_options_sync(
options: &crate::bindings::sync::LinkOptions,
) -> anyhow::Result<()> {
let l = linker;
- let closure = type_annotate::(|t| WasiImpl(t));
+ let io_closure = io_type_annotate::(|t| IoImpl(t));
+ let closure = type_annotate::(|t| WasiImpl(IoImpl(t)));
crate::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?;
crate::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?;
crate::bindings::sync::filesystem::types::add_to_linker_get_host(l, closure)?;
crate::bindings::filesystem::preopens::add_to_linker_get_host(l, closure)?;
- crate::bindings::io::error::add_to_linker_get_host(l, closure)?;
- crate::bindings::sync::io::poll::add_to_linker_get_host(l, closure)?;
- crate::bindings::sync::io::streams::add_to_linker_get_host(l, closure)?;
+ crate::bindings::io::error::add_to_linker_get_host(l, io_closure)?;
+ crate::bindings::sync::io::poll::add_to_linker_get_host(l, io_closure)?;
+ crate::bindings::sync::io::streams::add_to_linker_get_host(l, io_closure)?;
crate::bindings::random::random::add_to_linker_get_host(l, closure)?;
crate::bindings::random::insecure::add_to_linker_get_host(l, closure)?;
crate::bindings::random::insecure_seed::add_to_linker_get_host(l, closure)?;
@@ -430,6 +437,12 @@ pub fn add_to_linker_with_options_sync(
// NB: workaround some rustc inference - a future refactoring may make this
// obsolete.
+fn io_type_annotate(val: F) -> F
+where
+ F: Fn(&mut T) -> IoImpl<&mut T>,
+{
+ val
+}
fn type_annotate(val: F) -> F
where
F: Fn(&mut T) -> WasiImpl<&mut T>,
diff --git a/crates/wasi/src/poll.rs b/crates/wasi/src/poll.rs
index ea494a1dcc85..0d774b9b5e30 100644
--- a/crates/wasi/src/poll.rs
+++ b/crates/wasi/src/poll.rs
@@ -1,4 +1,4 @@
-use crate::{bindings::io::poll, WasiImpl, WasiView};
+use crate::{bindings::io::poll, IoImpl, IoView};
use anyhow::{anyhow, Result};
use std::any::Any;
use std::collections::HashMap;
@@ -42,11 +42,11 @@ pub struct Pollable {
///
/// ```
/// use tokio::time::{self, Duration, Instant};
-/// use wasmtime_wasi::{WasiView, Subscribe, subscribe, Pollable, async_trait};
+/// use wasmtime_wasi::{IoView, Subscribe, subscribe, Pollable, async_trait};
/// use wasmtime::component::Resource;
/// use wasmtime::Result;
///
-/// fn sleep(cx: &mut dyn WasiView, dur: Duration) -> Result> {
+/// fn sleep(cx: &mut dyn IoView, dur: Duration) -> Result> {
/// let end = Instant::now() + dur;
/// let sleep = MySleep { end };
/// let sleep_resource = cx.table().push(sleep)?;
@@ -116,9 +116,9 @@ where
Ok(table.push_child(pollable, &resource)?)
}
-impl poll::Host for WasiImpl
+impl poll::Host for IoImpl
where
- T: WasiView,
+ T: IoView,
{
async fn poll(&mut self, pollables: Vec>) -> Result> {
type ReadylistIndex = u32;
@@ -177,9 +177,9 @@ where
}
}
-impl crate::bindings::io::poll::HostPollable for WasiImpl
+impl crate::bindings::io::poll::HostPollable for IoImpl
where
- T: WasiView,
+ T: IoView,
{
async fn block(&mut self, pollable: Resource) -> Result<()> {
let table = self.table();
@@ -212,23 +212,23 @@ pub mod sync {
bindings::io::poll as async_poll,
bindings::sync::io::poll::{self, Pollable},
runtime::in_tokio,
- WasiImpl, WasiView,
+ IoImpl, IoView,
};
use anyhow::Result;
use wasmtime::component::Resource;
- impl poll::Host for WasiImpl
+ impl poll::Host for IoImpl
where
- T: WasiView,
+ T: IoView,
{
fn poll(&mut self, pollables: Vec>) -> Result> {
in_tokio(async { async_poll::Host::poll(self, pollables).await })
}
}
- impl crate::bindings::sync::io::poll::HostPollable for WasiImpl
+ impl crate::bindings::sync::io::poll::HostPollable for IoImpl
where
- T: WasiView,
+ T: IoView,
{
fn ready(&mut self, pollable: Resource) -> Result {
in_tokio(async { async_poll::HostPollable::ready(self, pollable).await })
diff --git a/crates/wasi/src/preview1.rs b/crates/wasi/src/preview1.rs
index a4aec9b58110..838875d11342 100644
--- a/crates/wasi/src/preview1.rs
+++ b/crates/wasi/src/preview1.rs
@@ -73,7 +73,8 @@ use crate::bindings::{
io::streams,
};
use crate::{
- FsError, IsATTY, ResourceTable, StreamError, StreamResult, WasiCtx, WasiImpl, WasiView,
+ FsError, IoImpl, IoView, IsATTY, ResourceTable, StreamError, StreamResult, WasiCtx, WasiImpl,
+ WasiView,
};
use anyhow::{bail, Context};
use std::collections::{BTreeMap, HashSet};
@@ -153,14 +154,19 @@ impl WasiP1Ctx {
}
fn as_wasi_impl(&mut self) -> WasiImpl<&mut Self> {
- WasiImpl(self)
+ WasiImpl(IoImpl(self))
+ }
+ fn as_io_impl(&mut self) -> IoImpl<&mut Self> {
+ IoImpl(self)
}
}
-impl WasiView for WasiP1Ctx {
+impl IoView for WasiP1Ctx {
fn table(&mut self) -> &mut ResourceTable {
&mut self.table
}
+}
+impl WasiView for WasiP1Ctx {
fn ctx(&mut self) -> &mut WasiCtx {
&mut self.wasi
}
@@ -648,7 +654,7 @@ impl WasiP1Ctx {
drop(t);
let buf = first_non_empty_ciovec(memory, ciovs)?;
let n = BlockingMode::Blocking
- .write(memory, &mut self.as_wasi_impl(), stream, buf)
+ .write(memory, &mut self.as_io_impl(), stream, buf)
.await?
.try_into()?;
Ok(n)
@@ -1323,12 +1329,12 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
.ok_or(types::Errno::Badf)?;
match desc {
Descriptor::Stdin { stream, .. } => {
- streams::HostInputStream::drop(&mut self.as_wasi_impl(), stream)
+ streams::HostInputStream::drop(&mut self.as_io_impl(), stream)
.await
.context("failed to call `drop` on `input-stream`")
}
Descriptor::Stdout { stream, .. } | Descriptor::Stderr { stream, .. } => {
- streams::HostOutputStream::drop(&mut self.as_wasi_impl(), stream)
+ streams::HostOutputStream::drop(&mut self.as_io_impl(), stream)
.await
.context("failed to call `drop` on `output-stream`")
}
@@ -1679,7 +1685,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
drop(t);
let buf = first_non_empty_iovec(memory, iovs)?;
let read = BlockingMode::Blocking
- .read(&mut self.as_wasi_impl(), stream, buf.len().try_into()?)
+ .read(&mut self.as_io_impl(), stream, buf.len().try_into()?)
.await?;
if read.len() > buf.len().try_into()? {
return Err(types::Errno::Range.into());
@@ -1717,12 +1723,12 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
let stream = self.as_wasi_impl().read_via_stream(fd, offset)?;
let read = blocking_mode
.read(
- &mut self.as_wasi_impl(),
+ &mut self.as_io_impl(),
stream.borrowed(),
buf.len().try_into()?,
)
.await;
- streams::HostInputStream::drop(&mut self.as_wasi_impl(), stream)
+ streams::HostInputStream::drop(&mut self.as_io_impl(), stream)
.await
.map_err(|e| types::Error::trap(e))?;
(buf, read?)
@@ -2367,7 +2373,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
_ => return Err(types::Errno::Badf.into()),
}
};
- streams::HostInputStream::subscribe(&mut self.as_wasi_impl(), stream)
+ streams::HostInputStream::subscribe(&mut self.as_io_impl(), stream)
.context("failed to call `subscribe` on `input-stream`")
.map_err(types::Error::trap)?
}
@@ -2401,7 +2407,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
_ => return Err(types::Errno::Badf.into()),
}
};
- streams::HostOutputStream::subscribe(&mut self.as_wasi_impl(), stream)
+ streams::HostOutputStream::subscribe(&mut self.as_io_impl(), stream)
.context("failed to call `subscribe` on `output-stream`")
.map_err(types::Error::trap)?
}
@@ -2409,7 +2415,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
pollables.push(p);
}
let ready: HashSet<_> = self
- .as_wasi_impl()
+ .as_io_impl()
.poll(pollables)
.await
.context("failed to call `poll-oneoff`")
diff --git a/crates/wasi/src/stdio.rs b/crates/wasi/src/stdio.rs
index 4fb359f394fb..17ab5820db73 100644
--- a/crates/wasi/src/stdio.rs
+++ b/crates/wasi/src/stdio.rs
@@ -5,7 +5,8 @@ use crate::bindings::cli::{
use crate::bindings::io::streams;
use crate::pipe;
use crate::{
- HostInputStream, HostOutputStream, StreamError, StreamResult, Subscribe, WasiImpl, WasiView,
+ HostInputStream, HostOutputStream, IoView, StreamError, StreamResult, Subscribe, WasiImpl,
+ WasiView,
};
use bytes::Bytes;
use std::io::IsTerminal;
diff --git a/crates/wasi/src/view.rs b/crates/wasi/src/view.rs
new file mode 100644
index 000000000000..58375b1b60ab
--- /dev/null
+++ b/crates/wasi/src/view.rs
@@ -0,0 +1,86 @@
+use crate::ctx::WasiCtx;
+use wasmtime::component::ResourceTable;
+
+pub trait IoView: Send {
+ /// Yields mutable access to the internal resource management that this
+ /// context contains.
+ ///
+ /// Embedders can add custom resources to this table as well to give
+ /// resources to wasm as well.
+ fn table(&mut self) -> &mut ResourceTable;
+}
+
+pub trait WasiView: IoView {
+ /// Yields mutable access to the configuration used for this context.
+ ///
+ /// The returned type is created through [`WasiCtxBuilder`].
+ fn ctx(&mut self) -> &mut WasiCtx;
+}
+
+impl IoView for &mut T {
+ fn table(&mut self) -> &mut ResourceTable {
+ T::table(self)
+ }
+}
+impl WasiView for &mut T {
+ fn ctx(&mut self) -> &mut WasiCtx {
+ T::ctx(self)
+ }
+}
+
+impl IoView for Box {
+ fn table(&mut self) -> &mut ResourceTable {
+ T::table(self)
+ }
+}
+impl WasiView for Box {
+ fn ctx(&mut self) -> &mut WasiCtx {
+ T::ctx(self)
+ }
+}
+
+/// A small newtype wrapper which serves as the basis for implementations of
+/// `Host` WASI traits in this crate.
+///
+/// This type is used as the basis for the implementation of all `Host` traits
+/// generated by `bindgen!` for WASI interfaces. This is used automatically with
+/// [`add_to_linker_sync`](crate::add_to_linker_sync) and
+/// [`add_to_linker_async`](crate::add_to_linker_async).
+///
+/// This type is otherwise provided if you're calling the `add_to_linker`
+/// functions generated by `bindgen!` from the [`bindings`
+/// module](crate::bindings). In this situation you'll want to create a value of
+/// this type in the closures added to a `Linker`.
+#[repr(transparent)]
+pub struct IoImpl(pub T);
+impl IoView for IoImpl {
+ fn table(&mut self) -> &mut ResourceTable {
+ T::table(&mut self.0)
+ }
+}
+
+/// A small newtype wrapper which serves as the basis for implementations of
+/// `Host` WASI traits in this crate.
+///
+/// This type is used as the basis for the implementation of all `Host` traits
+/// generated by `bindgen!` for WASI interfaces. This is used automatically with
+/// [`add_to_linker_sync`](crate::add_to_linker_sync) and
+/// [`add_to_linker_async`](crate::add_to_linker_async).
+///
+/// This type is otherwise provided if you're calling the `add_to_linker`
+/// functions generated by `bindgen!` from the [`bindings`
+/// module](crate::bindings). In this situation you'll want to create a value of
+/// this type in the closures added to a `Linker`.
+#[repr(transparent)]
+pub struct WasiImpl(pub IoImpl);
+
+impl IoView for WasiImpl {
+ fn table(&mut self) -> &mut ResourceTable {
+ T::table(&mut self.0 .0)
+ }
+}
+impl WasiView for WasiImpl {
+ fn ctx(&mut self) -> &mut WasiCtx {
+ T::ctx(&mut self.0 .0)
+ }
+}
diff --git a/crates/wasi/tests/all/api.rs b/crates/wasi/tests/all/api.rs
index 39d68a5f71a7..ca5219988744 100644
--- a/crates/wasi/tests/all/api.rs
+++ b/crates/wasi/tests/all/api.rs
@@ -10,7 +10,8 @@ use wasmtime_wasi::bindings::Command;
use wasmtime_wasi::{
add_to_linker_async,
bindings::{clocks::wall_clock, filesystem::types as filesystem},
- DirPerms, FilePerms, HostMonotonicClock, HostWallClock, WasiCtx, WasiCtxBuilder, WasiView,
+ DirPerms, FilePerms, HostMonotonicClock, HostWallClock, IoView, WasiCtx, WasiCtxBuilder,
+ WasiView,
};
struct CommandCtx {
@@ -18,10 +19,12 @@ struct CommandCtx {
wasi: WasiCtx,
}
-impl WasiView for CommandCtx {
+impl IoView for CommandCtx {
fn table(&mut self) -> &mut ResourceTable {
&mut self.table
}
+}
+impl WasiView for CommandCtx {
fn ctx(&mut self) -> &mut WasiCtx {
&mut self.wasi
}
diff --git a/crates/wasi/tests/all/main.rs b/crates/wasi/tests/all/main.rs
index 19924d42c19a..9a7d0782ad83 100644
--- a/crates/wasi/tests/all/main.rs
+++ b/crates/wasi/tests/all/main.rs
@@ -6,7 +6,7 @@ use wasmtime::{
};
use wasmtime_wasi::preview1::WasiP1Ctx;
use wasmtime_wasi::{
- pipe::MemoryOutputPipe, DirPerms, FilePerms, WasiCtx, WasiCtxBuilder, WasiView,
+ pipe::MemoryOutputPipe, DirPerms, FilePerms, IoView, WasiCtx, WasiCtxBuilder, WasiView,
};
struct Ctx {
@@ -15,10 +15,12 @@ struct Ctx {
wasi: WasiP1Ctx,
}
-impl WasiView for Ctx {
+impl IoView for Ctx {
fn table(&mut self) -> &mut ResourceTable {
self.wasi.table()
}
+}
+impl WasiView for Ctx {
fn ctx(&mut self) -> &mut WasiCtx {
self.wasi.ctx()
}
diff --git a/examples/wasip2-async/main.rs b/examples/wasip2-async/main.rs
index 29877ac3c693..9289773c3de5 100644
--- a/examples/wasip2-async/main.rs
+++ b/examples/wasip2-async/main.rs
@@ -10,20 +10,23 @@ You can execute this example with:
use wasmtime::component::{Component, Linker, ResourceTable};
use wasmtime::*;
use wasmtime_wasi::bindings::Command;
-use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiView};
+use wasmtime_wasi::{IoView, WasiCtx, WasiCtxBuilder, WasiView};
pub struct ComponentRunStates {
- // These two are required basically as a standard way to enable the impl of WasiView
+ // These two are required basically as a standard way to enable the impl of IoView and
+ // WasiView.
// impl of WasiView is required by [`wasmtime_wasi::add_to_linker_sync`]
pub wasi_ctx: WasiCtx,
pub resource_table: ResourceTable,
// You can add other custom host states if needed
}
-impl WasiView for ComponentRunStates {
+impl IoView for ComponentRunStates {
fn table(&mut self) -> &mut ResourceTable {
&mut self.resource_table
}
+}
+impl WasiView for ComponentRunStates {
fn ctx(&mut self) -> &mut WasiCtx {
&mut self.wasi_ctx
}
diff --git a/examples/wasip2/main.rs b/examples/wasip2/main.rs
index cfcfcb543123..bda98b541d6c 100644
--- a/examples/wasip2/main.rs
+++ b/examples/wasip2/main.rs
@@ -9,20 +9,23 @@ You can execute this example with:
use wasmtime::component::{Component, Linker, ResourceTable};
use wasmtime::*;
use wasmtime_wasi::bindings::sync::Command;
-use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiView};
+use wasmtime_wasi::{IoView, WasiCtx, WasiCtxBuilder, WasiView};
pub struct ComponentRunStates {
- // These two are required basically as a standard way to enable the impl of WasiView
+ // These two are required basically as a standard way to enable the impl of IoView and
+ // WasiView.
// impl of WasiView is required by [`wasmtime_wasi::add_to_linker_sync`]
pub wasi_ctx: WasiCtx,
pub resource_table: ResourceTable,
// You can add other custom host states if needed
}
-impl WasiView for ComponentRunStates {
+impl IoView for ComponentRunStates {
fn table(&mut self) -> &mut ResourceTable {
&mut self.resource_table
}
+}
+impl WasiView for ComponentRunStates {
fn ctx(&mut self) -> &mut WasiCtx {
&mut self.wasi_ctx
}
diff --git a/src/commands/run.rs b/src/commands/run.rs
index e154ad50542c..bd45e2daa5c2 100644
--- a/src/commands/run.rs
+++ b/src/commands/run.rs
@@ -15,7 +15,7 @@ use std::sync::{Arc, Mutex};
use std::thread;
use wasi_common::sync::{ambient_authority, Dir, TcpListener, WasiCtxBuilder};
use wasmtime::{Engine, Func, Module, Store, StoreLimits, Val, ValType};
-use wasmtime_wasi::WasiView;
+use wasmtime_wasi::{IoView, WasiView};
#[cfg(feature = "wasi-nn")]
use wasmtime_wasi_nn::wit::WasiNnView;
@@ -945,11 +945,12 @@ impl Host {
}
}
-impl WasiView for Host {
+impl IoView for Host {
fn table(&mut self) -> &mut wasmtime::component::ResourceTable {
self.preview2_ctx().table()
}
-
+}
+impl WasiView for Host {
fn ctx(&mut self) -> &mut wasmtime_wasi::WasiCtx {
self.preview2_ctx().ctx()
}
@@ -962,10 +963,6 @@ impl wasmtime_wasi_http::types::WasiHttpView for Host {
Arc::get_mut(ctx).expect("wasmtime_wasi is not compatible with threads")
}
- fn table(&mut self) -> &mut wasmtime::component::ResourceTable {
- self.preview2_ctx().table()
- }
-
fn outgoing_body_buffer_chunks(&mut self) -> usize {
self.wasi_http_outgoing_body_buffer_chunks
.unwrap_or_else(|| DEFAULT_OUTGOING_BODY_BUFFER_CHUNKS)
diff --git a/src/commands/serve.rs b/src/commands/serve.rs
index 5f13d391feff..cd54a468a910 100644
--- a/src/commands/serve.rs
+++ b/src/commands/serve.rs
@@ -11,7 +11,7 @@ use std::{
};
use wasmtime::component::Linker;
use wasmtime::{Engine, Store, StoreLimits};
-use wasmtime_wasi::{StreamError, StreamResult, WasiCtx, WasiCtxBuilder, WasiView};
+use wasmtime_wasi::{IoView, StreamError, StreamResult, WasiCtx, WasiCtxBuilder, WasiView};
use wasmtime_wasi_http::bindings::http::types::Scheme;
use wasmtime_wasi_http::bindings::ProxyPre;
use wasmtime_wasi_http::io::TokioIo;
@@ -46,21 +46,18 @@ struct Host {
wasi_keyvalue: Option,
}
-impl WasiView for Host {
+impl IoView for Host {
fn table(&mut self) -> &mut wasmtime::component::ResourceTable {
&mut self.table
}
-
+}
+impl WasiView for Host {
fn ctx(&mut self) -> &mut WasiCtx {
&mut self.ctx
}
}
impl WasiHttpView for Host {
- fn table(&mut self) -> &mut wasmtime::component::ResourceTable {
- &mut self.table
- }
-
fn ctx(&mut self) -> &mut WasiHttpCtx {
&mut self.http
}