diff --git a/ci/vendor-wit.sh b/ci/vendor-wit.sh index 252fb9a863e5..acf495d40dd2 100755 --- a/ci/vendor-wit.sh +++ b/ci/vendor-wit.sh @@ -36,7 +36,7 @@ make_vendor() { cache_dir=$(mktemp -d) -make_vendor "wasi" " +make_vendor "wasi/src/p2" " cli@v0.2.3 clocks@v0.2.3 filesystem@v0.2.3 @@ -45,7 +45,7 @@ make_vendor "wasi" " sockets@v0.2.3 " -make_vendor "wasi-http" " +make_vendor "wasi-http/src/p2" " cli@v0.2.3 clocks@v0.2.3 filesystem@v0.2.3 @@ -55,9 +55,9 @@ make_vendor "wasi-http" " http@v0.2.3 " -make_vendor "wasi-config" "config@f4d699b" +make_vendor "wasi-config/src/p2" "config@f4d699b" -make_vendor "wasi-keyvalue" "keyvalue@219ea36" +make_vendor "wasi-keyvalue/src/p2" "keyvalue@219ea36" rm -rf $cache_dir diff --git a/crates/test-programs/src/bin/api_reactor.rs b/crates/test-programs/src/bin/api_reactor.rs index 360c96fab61b..3f8b420b6e6b 100644 --- a/crates/test-programs/src/bin/api_reactor.rs +++ b/crates/test-programs/src/bin/api_reactor.rs @@ -2,7 +2,7 @@ use std::sync::{Mutex, MutexGuard}; wit_bindgen::generate!({ world: "test-reactor", - path: "../wasi/wit", + path: "../wasi/src/p2/wit", generate_all, }); diff --git a/crates/test-programs/src/lib.rs b/crates/test-programs/src/lib.rs index 49301621dbd0..d232954d98ea 100644 --- a/crates/test-programs/src/lib.rs +++ b/crates/test-programs/src/lib.rs @@ -15,9 +15,9 @@ wit_bindgen::generate!({ } ", path: [ - "../wasi-http/wit", - "../wasi-config/wit", - "../wasi-keyvalue/wit", + "../wasi-http/src/p2/wit", + "../wasi-config/src/p2/wit", + "../wasi-keyvalue/src/p2/wit", ], world: "wasmtime:test/test", features: ["cli-exit-with-code"], @@ -26,7 +26,7 @@ wit_bindgen::generate!({ pub mod proxy { wit_bindgen::generate!({ - path: "../wasi-http/wit", + path: "../wasi-http/src/p2/wit", world: "wasi:http/proxy", default_bindings_module: "test_programs::proxy", pub_export_macro: true, diff --git a/crates/wasi-config/src/lib.rs b/crates/wasi-config/src/lib.rs index ec6f3bd595b0..ffee81248225 100644 --- a/crates/wasi-config/src/lib.rs +++ b/crates/wasi-config/src/lib.rs @@ -67,17 +67,11 @@ #![deny(missing_docs)] -use anyhow::Result; use std::collections::HashMap; -mod gen_ { - wasmtime::component::bindgen!({ - path: "wit", - world: "wasi:config/imports", - trappable_imports: true, - }); -} -use self::gen_::wasi::config::store as generated; +pub mod p2; +#[doc(inline)] +pub use p2::*; /// Capture the state necessary for use in the `wasi-config` API implementation. #[derive(Default)] @@ -123,27 +117,3 @@ impl<'a> WasiConfig<'a> { Self { vars } } } - -impl generated::Host for WasiConfig<'_> { - fn get(&mut self, key: String) -> Result, generated::Error>> { - Ok(Ok(self.vars.0.get(&key).map(|s| s.to_owned()))) - } - - fn get_all(&mut self) -> Result, generated::Error>> { - Ok(Ok(self - .vars - .0 - .iter() - .map(|(k, v)| (k.to_string(), v.to_string())) - .collect())) - } -} - -/// Add all the `wasi-config` world's interfaces to a [`wasmtime::component::Linker`]. -pub fn add_to_linker( - l: &mut wasmtime::component::Linker, - f: impl Fn(&mut T) -> WasiConfig<'_> + Send + Sync + Copy + 'static, -) -> Result<()> { - generated::add_to_linker_get_host(l, f)?; - Ok(()) -} diff --git a/crates/wasi-config/src/p2/mod.rs b/crates/wasi-config/src/p2/mod.rs new file mode 100644 index 000000000000..4d2bfb38f41a --- /dev/null +++ b/crates/wasi-config/src/p2/mod.rs @@ -0,0 +1,36 @@ +//! Implementation of wasip2 version of `wasi:config` package + +mod gen_ { + wasmtime::component::bindgen!({ + path: "src/p2/wit", + world: "wasi:config/imports", + trappable_imports: true, + }); +} +use self::gen_::wasi::config::store as generated; + +use crate::WasiConfig; + +impl generated::Host for WasiConfig<'_> { + fn get(&mut self, key: String) -> anyhow::Result, generated::Error>> { + Ok(Ok(self.vars.0.get(&key).map(|s| s.to_owned()))) + } + + fn get_all(&mut self) -> anyhow::Result, generated::Error>> { + Ok(Ok(self + .vars + .0 + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect())) + } +} + +/// Add all the `wasi-config` world's interfaces to a [`wasmtime::component::Linker`]. +pub fn add_to_linker( + l: &mut wasmtime::component::Linker, + f: impl Fn(&mut T) -> WasiConfig<'_> + Send + Sync + Copy + 'static, +) -> anyhow::Result<()> { + generated::add_to_linker_get_host(l, f)?; + Ok(()) +} diff --git a/crates/wasi-config/wit/deps/config/store.wit b/crates/wasi-config/src/p2/wit/deps/config/store.wit similarity index 100% rename from crates/wasi-config/wit/deps/config/store.wit rename to crates/wasi-config/src/p2/wit/deps/config/store.wit diff --git a/crates/wasi-config/wit/deps/config/world.wit b/crates/wasi-config/src/p2/wit/deps/config/world.wit similarity index 100% rename from crates/wasi-config/wit/deps/config/world.wit rename to crates/wasi-config/src/p2/wit/deps/config/world.wit diff --git a/crates/wasi-config/wit/world.wit b/crates/wasi-config/src/p2/wit/world.wit similarity index 100% rename from crates/wasi-config/wit/world.wit rename to crates/wasi-config/src/p2/wit/world.wit diff --git a/crates/wasi-http/src/body.rs b/crates/wasi-http/src/body.rs index 96c783964746..285e6b1cca02 100644 --- a/crates/wasi-http/src/body.rs +++ b/crates/wasi-http/src/body.rs @@ -1,6 +1,6 @@ //! Implementation of the `wasi:http/types` interface's various body types. -use crate::{bindings::http::types, types::FieldMap}; +use crate::{p2::bindings::http::types, types::FieldMap}; use anyhow::anyhow; use bytes::Bytes; use http_body::{Body, Frame}; diff --git a/crates/wasi-http/src/error.rs b/crates/wasi-http/src/error.rs index 1c60a4b0771e..a19e22dc6226 100644 --- a/crates/wasi-http/src/error.rs +++ b/crates/wasi-http/src/error.rs @@ -1,4 +1,4 @@ -use crate::bindings::http::types::ErrorCode; +use crate::p2::bindings::http::types::ErrorCode; use std::error::Error; use std::fmt; use wasmtime_wasi::ResourceTableError; diff --git a/crates/wasi-http/src/lib.rs b/crates/wasi-http/src/lib.rs index 9c57a6b6a974..b579e0dba024 100644 --- a/crates/wasi-http/src/lib.rs +++ b/crates/wasi-http/src/lib.rs @@ -1,28 +1,9 @@ //! # Wasmtime's WASI HTTP Implementation //! -//! This crate is Wasmtime's host implementation of the `wasi:http` package as -//! part of WASIp2. This crate's implementation is primarily built on top of +//! This crate is Wasmtime's host implementation of the `wasi:http` package. +//! This crate's implementation is primarily built on top of //! [`hyper`] and [`tokio`]. //! -//! # WASI HTTP Interfaces -//! -//! This crate contains implementations of the following interfaces: -//! -//! * [`wasi:http/incoming-handler`] -//! * [`wasi:http/outgoing-handler`] -//! * [`wasi:http/types`] -//! -//! The crate also contains an implementation of the [`wasi:http/proxy`] world. -//! -//! [`wasi:http/proxy`]: crate::bindings::Proxy -//! [`wasi:http/outgoing-handler`]: crate::bindings::http::outgoing_handler::Host -//! [`wasi:http/types`]: crate::bindings::http::types::Host -//! [`wasi:http/incoming-handler`]: crate::bindings::exports::wasi::http::incoming_handler::Guest -//! -//! This crate is very similar to [`wasmtime-wasi`] in the it uses the -//! `bindgen!` macro in Wasmtime to generate bindings to interfaces. Bindings -//! are located in the [`bindings`] module. -//! //! # The `WasiHttpView` trait //! //! All `bindgen!`-generated `Host` traits are implemented in terms of a @@ -55,7 +36,7 @@ //! no others. This is useful when working with //! [`wasmtime_wasi::add_to_linker_async`] for example. //! * Add individual interfaces such as with the -//! [`bindings::http::outgoing_handler::add_to_linker_get_host`] function. +//! [`p2::bindings::http::outgoing_handler::add_to_linker_get_host`] function. //! 3. Use [`ProxyPre`](bindings::ProxyPre) to pre-instantiate a component //! before serving requests. //! 4. When serving requests use @@ -217,15 +198,12 @@ #![expect(clippy::allow_attributes_without_reason, reason = "crate not migrated")] mod error; -mod http_impl; -mod types_impl; pub mod body; pub mod io; +pub mod p2; pub mod types; -pub mod bindings; - pub use crate::error::{ http_request_error, hyper_request_error, hyper_response_error, HttpError, HttpResult, }; @@ -234,70 +212,8 @@ 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 -/// `Linker` provided. By `async` this means that this function is only -/// compatible with [`Config::async_support(true)`][async]. For embeddings with -/// async support disabled see [`add_to_linker_sync`] instead. -/// -/// [async]: wasmtime::Config::async_support -/// -/// # Example -/// -/// ``` -/// use wasmtime::{Engine, Result, Config}; -/// use wasmtime::component::{ResourceTable, Linker}; -/// use wasmtime_wasi::{IoView, WasiCtx, WasiView}; -/// use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView}; -/// -/// fn main() -> Result<()> { -/// let mut config = Config::new(); -/// config.async_support(true); -/// let engine = Engine::new(&config)?; -/// -/// let mut linker = Linker::::new(&engine); -/// wasmtime_wasi_http::add_to_linker_async(&mut linker)?; -/// // ... add any further functionality to `linker` if desired ... -/// -/// Ok(()) -/// } -/// -/// struct MyState { -/// ctx: WasiCtx, -/// 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 } -/// } -/// impl WasiView for MyState { -/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx } -/// } -/// ``` -pub fn add_to_linker_async(l: &mut wasmtime::component::Linker) -> anyhow::Result<()> -where - T: WasiHttpView + wasmtime_wasi::WasiView, -{ - 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, 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)?; - wasmtime_wasi::bindings::random::random::add_to_linker_get_host(l, closure)?; - - add_only_http_to_linker_async(l) -} +#[doc(inline)] +pub use p2::*; // NB: workaround some rustc inference - a future refactoring may make this // obsolete. @@ -319,100 +235,3 @@ where { val } - -/// A slimmed down version of [`add_to_linker_async`] which only adds -/// `wasi:http` interfaces to the linker. -/// -/// This is useful when using [`wasmtime_wasi::add_to_linker_async`] for -/// example to avoid re-adding the same interfaces twice. -pub fn add_only_http_to_linker_async( - l: &mut wasmtime::component::Linker, -) -> anyhow::Result<()> -where - T: WasiHttpView, -{ - 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)?; - - Ok(()) -} - -/// Add all of the `wasi:http/proxy` world's interfaces to a [`wasmtime::component::Linker`]. -/// -/// This function will add the `sync` variant of all interfaces into the -/// `Linker` provided. For embeddings with async support see -/// [`add_to_linker_async`] instead. -/// -/// # Example -/// -/// ``` -/// use wasmtime::{Engine, Result, Config}; -/// use wasmtime::component::{ResourceTable, Linker}; -/// use wasmtime_wasi::{IoView, WasiCtx, WasiView}; -/// use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView}; -/// -/// fn main() -> Result<()> { -/// let config = Config::default(); -/// let engine = Engine::new(&config)?; -/// -/// let mut linker = Linker::::new(&engine); -/// wasmtime_wasi_http::add_to_linker_sync(&mut linker)?; -/// // ... add any further functionality to `linker` if desired ... -/// -/// Ok(()) -/// } -/// -/// struct MyState { -/// ctx: WasiCtx, -/// 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 } -/// } -/// impl WasiView for MyState { -/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx } -/// } -/// ``` -pub fn add_to_linker_sync(l: &mut wasmtime::component::Linker) -> anyhow::Result<()> -where - T: WasiHttpView + wasmtime_wasi::WasiView, -{ - 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, 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)?; - wasmtime_wasi::bindings::random::random::add_to_linker_get_host(l, closure)?; - - add_only_http_to_linker_sync(l)?; - - Ok(()) -} - -/// A slimmed down version of [`add_to_linker_sync`] which only adds -/// `wasi:http` interfaces to the linker. -/// -/// This is useful when using [`wasmtime_wasi::add_to_linker_sync`] for -/// example to avoid re-adding the same interfaces twice. -pub fn add_only_http_to_linker_sync(l: &mut wasmtime::component::Linker) -> anyhow::Result<()> -where - T: WasiHttpView, -{ - 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)?; - - Ok(()) -} diff --git a/crates/wasi-http/src/bindings.rs b/crates/wasi-http/src/p2/bindings.rs similarity index 95% rename from crates/wasi-http/src/bindings.rs rename to crates/wasi-http/src/p2/bindings.rs index 00054e5a644b..5953662157f7 100644 --- a/crates/wasi-http/src/bindings.rs +++ b/crates/wasi-http/src/p2/bindings.rs @@ -6,7 +6,7 @@ mod generated { use crate::types; wasmtime::component::bindgen!({ - path: "wit", + path: "src/p2/wit", world: "wasi:http/proxy", tracing: true, // Flag this as "possibly async" which will cause the exports to be @@ -55,11 +55,12 @@ pub mod sync { mod generated { #![allow(missing_docs)] wasmtime::component::bindgen!({ + path: "src/p2/wit", world: "wasi:http/proxy", tracing: true, async: false, with: { - "wasi:http": crate::bindings::http, // http is in this crate + "wasi:http": crate::p2::bindings::http, // http is in this crate "wasi:io": wasmtime_wasi::bindings::sync::io, // io is sync "wasi": wasmtime_wasi::bindings, // everything else }, diff --git a/crates/wasi-http/src/http_impl.rs b/crates/wasi-http/src/p2/http_impl.rs similarity index 99% rename from crates/wasi-http/src/http_impl.rs rename to crates/wasi-http/src/p2/http_impl.rs index 8850b63f29c6..3f8746041f8f 100644 --- a/crates/wasi-http/src/http_impl.rs +++ b/crates/wasi-http/src/p2/http_impl.rs @@ -1,12 +1,12 @@ //! Implementation of the `wasi:http/outgoing-handler` interface. use crate::{ - bindings::http::{ + error::internal_error, + http_request_error, + p2::bindings::http::{ outgoing_handler, types::{self, Scheme}, }, - error::internal_error, - http_request_error, types::{HostFutureIncomingResponse, HostOutgoingRequest, OutgoingRequestConfig}, WasiHttpImpl, WasiHttpView, }; diff --git a/crates/wasi-http/src/p2/mod.rs b/crates/wasi-http/src/p2/mod.rs new file mode 100644 index 000000000000..98ee6d8fb7ac --- /dev/null +++ b/crates/wasi-http/src/p2/mod.rs @@ -0,0 +1,189 @@ +//! Implementation of wasip2 version of `wasi:http` package +//! +//! # WASI HTTP Interfaces +//! +//! This module contains implementations of the following interfaces: +//! +//! * [`wasi:http/incoming-handler`] +//! * [`wasi:http/outgoing-handler`] +//! * [`wasi:http/types`] +//! +//! The module also contains an implementation of the [`wasi:http/proxy`] world. +//! +//! [`wasi:http/proxy`]: crate::p2::bindings::Proxy +//! [`wasi:http/outgoing-handler`]: crate::p2::bindings::http::outgoing_handler::Host +//! [`wasi:http/types`]: crate::p2::bindings::http::types::Host +//! [`wasi:http/incoming-handler`]: crate::p2::bindings::exports::wasi::http::incoming_handler::Guest +//! +//! This module is very similar to [`wasmtime-wasi`] in the it uses the +//! `bindgen!` macro in Wasmtime to generate bindings to interfaces. Bindings +//! are located in the [`bindings`] submodule. + +mod http_impl; +mod types_impl; + +pub mod bindings; + +use crate::types::{WasiHttpImpl, WasiHttpView}; +use crate::{type_annotate_http, type_annotate_io, type_annotate_wasi}; +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 +/// `Linker` provided. By `async` this means that this function is only +/// compatible with [`Config::async_support(true)`][async]. For embeddings with +/// async support disabled see [`add_to_linker_sync`] instead. +/// +/// [async]: wasmtime::Config::async_support +/// +/// # Example +/// +/// ``` +/// use wasmtime::{Engine, Result, Config}; +/// use wasmtime::component::{ResourceTable, Linker}; +/// use wasmtime_wasi::{IoView, WasiCtx, WasiView}; +/// use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView}; +/// +/// fn main() -> Result<()> { +/// let mut config = Config::new(); +/// config.async_support(true); +/// let engine = Engine::new(&config)?; +/// +/// let mut linker = Linker::::new(&engine); +/// wasmtime_wasi_http::add_to_linker_async(&mut linker)?; +/// // ... add any further functionality to `linker` if desired ... +/// +/// Ok(()) +/// } +/// +/// struct MyState { +/// ctx: WasiCtx, +/// 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 } +/// } +/// impl WasiView for MyState { +/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx } +/// } +/// ``` +pub fn add_to_linker_async(l: &mut wasmtime::component::Linker) -> anyhow::Result<()> +where + T: WasiHttpView + wasmtime_wasi::WasiView, +{ + 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, 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)?; + wasmtime_wasi::bindings::random::random::add_to_linker_get_host(l, closure)?; + + add_only_http_to_linker_async(l) +} + +/// A slimmed down version of [`add_to_linker_async`] which only adds +/// `wasi:http` interfaces to the linker. +/// +/// This is useful when using [`wasmtime_wasi::add_to_linker_async`] for +/// example to avoid re-adding the same interfaces twice. +pub fn add_only_http_to_linker_async( + l: &mut wasmtime::component::Linker, +) -> anyhow::Result<()> +where + T: WasiHttpView, +{ + let closure = type_annotate_http::(|t| WasiHttpImpl(IoImpl(t))); + self::bindings::http::outgoing_handler::add_to_linker_get_host(l, closure)?; + self::bindings::http::types::add_to_linker_get_host(l, closure)?; + + Ok(()) +} + +/// Add all of the `wasi:http/proxy` world's interfaces to a [`wasmtime::component::Linker`]. +/// +/// This function will add the `sync` variant of all interfaces into the +/// `Linker` provided. For embeddings with async support see +/// [`add_to_linker_async`] instead. +/// +/// # Example +/// +/// ``` +/// use wasmtime::{Engine, Result, Config}; +/// use wasmtime::component::{ResourceTable, Linker}; +/// use wasmtime_wasi::{IoView, WasiCtx, WasiView}; +/// use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView}; +/// +/// fn main() -> Result<()> { +/// let config = Config::default(); +/// let engine = Engine::new(&config)?; +/// +/// let mut linker = Linker::::new(&engine); +/// wasmtime_wasi_http::add_to_linker_sync(&mut linker)?; +/// // ... add any further functionality to `linker` if desired ... +/// +/// Ok(()) +/// } +/// +/// struct MyState { +/// ctx: WasiCtx, +/// 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 } +/// } +/// impl WasiView for MyState { +/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx } +/// } +/// ``` +pub fn add_to_linker_sync(l: &mut wasmtime::component::Linker) -> anyhow::Result<()> +where + T: WasiHttpView + wasmtime_wasi::WasiView, +{ + 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, 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)?; + wasmtime_wasi::bindings::random::random::add_to_linker_get_host(l, closure)?; + + add_only_http_to_linker_sync(l)?; + + Ok(()) +} + +/// A slimmed down version of [`add_to_linker_sync`] which only adds +/// `wasi:http` interfaces to the linker. +/// +/// This is useful when using [`wasmtime_wasi::add_to_linker_sync`] for +/// example to avoid re-adding the same interfaces twice. +pub fn add_only_http_to_linker_sync(l: &mut wasmtime::component::Linker) -> anyhow::Result<()> +where + T: WasiHttpView, +{ + let closure = type_annotate_http::(|t| WasiHttpImpl(IoImpl(t))); + + self::bindings::http::outgoing_handler::add_to_linker_get_host(l, closure)?; + self::bindings::http::types::add_to_linker_get_host(l, closure)?; + + Ok(()) +} diff --git a/crates/wasi-http/src/types_impl.rs b/crates/wasi-http/src/p2/types_impl.rs similarity index 99% rename from crates/wasi-http/src/types_impl.rs rename to crates/wasi-http/src/p2/types_impl.rs index f3a83f85d6d7..6121f84234ea 100644 --- a/crates/wasi-http/src/types_impl.rs +++ b/crates/wasi-http/src/p2/types_impl.rs @@ -1,8 +1,8 @@ //! Implementation for the `wasi:http/types` interface. use crate::{ - bindings::http::types::{self, Headers, Method, Scheme, StatusCode, Trailers}, body::{HostFutureTrailers, HostIncomingBody, HostOutgoingBody, StreamContext}, + p2::bindings::http::types::{self, Headers, Method, Scheme, StatusCode, Trailers}, types::{ is_forbidden_header, remove_forbidden_headers, FieldMap, HostFields, HostFutureIncomingResponse, HostIncomingRequest, HostIncomingResponse, HostOutgoingRequest, @@ -15,7 +15,7 @@ use std::any::Any; use std::str::FromStr; use wasmtime::component::{Resource, ResourceTable}; use wasmtime_wasi::{ - bindings::io::streams::{InputStream, OutputStream}, + p2::bindings::io::streams::{InputStream, OutputStream}, IoView, Pollable, ResourceTableError, }; diff --git a/crates/wasi-http/wit/deps/cli/command.wit b/crates/wasi-http/src/p2/wit/deps/cli/command.wit similarity index 100% rename from crates/wasi-http/wit/deps/cli/command.wit rename to crates/wasi-http/src/p2/wit/deps/cli/command.wit diff --git a/crates/wasi-http/wit/deps/cli/environment.wit b/crates/wasi-http/src/p2/wit/deps/cli/environment.wit similarity index 100% rename from crates/wasi-http/wit/deps/cli/environment.wit rename to crates/wasi-http/src/p2/wit/deps/cli/environment.wit diff --git a/crates/wasi-http/wit/deps/cli/exit.wit b/crates/wasi-http/src/p2/wit/deps/cli/exit.wit similarity index 100% rename from crates/wasi-http/wit/deps/cli/exit.wit rename to crates/wasi-http/src/p2/wit/deps/cli/exit.wit diff --git a/crates/wasi-http/wit/deps/cli/imports.wit b/crates/wasi-http/src/p2/wit/deps/cli/imports.wit similarity index 100% rename from crates/wasi-http/wit/deps/cli/imports.wit rename to crates/wasi-http/src/p2/wit/deps/cli/imports.wit diff --git a/crates/wasi-http/wit/deps/cli/run.wit b/crates/wasi-http/src/p2/wit/deps/cli/run.wit similarity index 100% rename from crates/wasi-http/wit/deps/cli/run.wit rename to crates/wasi-http/src/p2/wit/deps/cli/run.wit diff --git a/crates/wasi-http/wit/deps/cli/stdio.wit b/crates/wasi-http/src/p2/wit/deps/cli/stdio.wit similarity index 100% rename from crates/wasi-http/wit/deps/cli/stdio.wit rename to crates/wasi-http/src/p2/wit/deps/cli/stdio.wit diff --git a/crates/wasi-http/wit/deps/cli/terminal.wit b/crates/wasi-http/src/p2/wit/deps/cli/terminal.wit similarity index 100% rename from crates/wasi-http/wit/deps/cli/terminal.wit rename to crates/wasi-http/src/p2/wit/deps/cli/terminal.wit diff --git a/crates/wasi-http/wit/deps/clocks/monotonic-clock.wit b/crates/wasi-http/src/p2/wit/deps/clocks/monotonic-clock.wit similarity index 100% rename from crates/wasi-http/wit/deps/clocks/monotonic-clock.wit rename to crates/wasi-http/src/p2/wit/deps/clocks/monotonic-clock.wit diff --git a/crates/wasi-http/wit/deps/clocks/timezone.wit b/crates/wasi-http/src/p2/wit/deps/clocks/timezone.wit similarity index 100% rename from crates/wasi-http/wit/deps/clocks/timezone.wit rename to crates/wasi-http/src/p2/wit/deps/clocks/timezone.wit diff --git a/crates/wasi-http/wit/deps/clocks/wall-clock.wit b/crates/wasi-http/src/p2/wit/deps/clocks/wall-clock.wit similarity index 100% rename from crates/wasi-http/wit/deps/clocks/wall-clock.wit rename to crates/wasi-http/src/p2/wit/deps/clocks/wall-clock.wit diff --git a/crates/wasi-http/wit/deps/clocks/world.wit b/crates/wasi-http/src/p2/wit/deps/clocks/world.wit similarity index 100% rename from crates/wasi-http/wit/deps/clocks/world.wit rename to crates/wasi-http/src/p2/wit/deps/clocks/world.wit diff --git a/crates/wasi-http/wit/deps/filesystem/preopens.wit b/crates/wasi-http/src/p2/wit/deps/filesystem/preopens.wit similarity index 100% rename from crates/wasi-http/wit/deps/filesystem/preopens.wit rename to crates/wasi-http/src/p2/wit/deps/filesystem/preopens.wit diff --git a/crates/wasi-http/wit/deps/filesystem/types.wit b/crates/wasi-http/src/p2/wit/deps/filesystem/types.wit similarity index 100% rename from crates/wasi-http/wit/deps/filesystem/types.wit rename to crates/wasi-http/src/p2/wit/deps/filesystem/types.wit diff --git a/crates/wasi-http/wit/deps/filesystem/world.wit b/crates/wasi-http/src/p2/wit/deps/filesystem/world.wit similarity index 100% rename from crates/wasi-http/wit/deps/filesystem/world.wit rename to crates/wasi-http/src/p2/wit/deps/filesystem/world.wit diff --git a/crates/wasi-http/wit/deps/http/handler.wit b/crates/wasi-http/src/p2/wit/deps/http/handler.wit similarity index 100% rename from crates/wasi-http/wit/deps/http/handler.wit rename to crates/wasi-http/src/p2/wit/deps/http/handler.wit diff --git a/crates/wasi-http/wit/deps/http/proxy.wit b/crates/wasi-http/src/p2/wit/deps/http/proxy.wit similarity index 100% rename from crates/wasi-http/wit/deps/http/proxy.wit rename to crates/wasi-http/src/p2/wit/deps/http/proxy.wit diff --git a/crates/wasi-http/wit/deps/http/types.wit b/crates/wasi-http/src/p2/wit/deps/http/types.wit similarity index 100% rename from crates/wasi-http/wit/deps/http/types.wit rename to crates/wasi-http/src/p2/wit/deps/http/types.wit diff --git a/crates/wasi-http/wit/deps/io/error.wit b/crates/wasi-http/src/p2/wit/deps/io/error.wit similarity index 100% rename from crates/wasi-http/wit/deps/io/error.wit rename to crates/wasi-http/src/p2/wit/deps/io/error.wit diff --git a/crates/wasi-http/wit/deps/io/poll.wit b/crates/wasi-http/src/p2/wit/deps/io/poll.wit similarity index 100% rename from crates/wasi-http/wit/deps/io/poll.wit rename to crates/wasi-http/src/p2/wit/deps/io/poll.wit diff --git a/crates/wasi-http/wit/deps/io/streams.wit b/crates/wasi-http/src/p2/wit/deps/io/streams.wit similarity index 100% rename from crates/wasi-http/wit/deps/io/streams.wit rename to crates/wasi-http/src/p2/wit/deps/io/streams.wit diff --git a/crates/wasi-http/wit/deps/io/world.wit b/crates/wasi-http/src/p2/wit/deps/io/world.wit similarity index 100% rename from crates/wasi-http/wit/deps/io/world.wit rename to crates/wasi-http/src/p2/wit/deps/io/world.wit diff --git a/crates/wasi-http/wit/deps/random/insecure-seed.wit b/crates/wasi-http/src/p2/wit/deps/random/insecure-seed.wit similarity index 100% rename from crates/wasi-http/wit/deps/random/insecure-seed.wit rename to crates/wasi-http/src/p2/wit/deps/random/insecure-seed.wit diff --git a/crates/wasi-http/wit/deps/random/insecure.wit b/crates/wasi-http/src/p2/wit/deps/random/insecure.wit similarity index 100% rename from crates/wasi-http/wit/deps/random/insecure.wit rename to crates/wasi-http/src/p2/wit/deps/random/insecure.wit diff --git a/crates/wasi-http/wit/deps/random/random.wit b/crates/wasi-http/src/p2/wit/deps/random/random.wit similarity index 100% rename from crates/wasi-http/wit/deps/random/random.wit rename to crates/wasi-http/src/p2/wit/deps/random/random.wit diff --git a/crates/wasi-http/wit/deps/random/world.wit b/crates/wasi-http/src/p2/wit/deps/random/world.wit similarity index 100% rename from crates/wasi-http/wit/deps/random/world.wit rename to crates/wasi-http/src/p2/wit/deps/random/world.wit diff --git a/crates/wasi-http/wit/deps/sockets/instance-network.wit b/crates/wasi-http/src/p2/wit/deps/sockets/instance-network.wit similarity index 100% rename from crates/wasi-http/wit/deps/sockets/instance-network.wit rename to crates/wasi-http/src/p2/wit/deps/sockets/instance-network.wit diff --git a/crates/wasi-http/wit/deps/sockets/ip-name-lookup.wit b/crates/wasi-http/src/p2/wit/deps/sockets/ip-name-lookup.wit similarity index 100% rename from crates/wasi-http/wit/deps/sockets/ip-name-lookup.wit rename to crates/wasi-http/src/p2/wit/deps/sockets/ip-name-lookup.wit diff --git a/crates/wasi-http/wit/deps/sockets/network.wit b/crates/wasi-http/src/p2/wit/deps/sockets/network.wit similarity index 100% rename from crates/wasi-http/wit/deps/sockets/network.wit rename to crates/wasi-http/src/p2/wit/deps/sockets/network.wit diff --git a/crates/wasi-http/wit/deps/sockets/tcp-create-socket.wit b/crates/wasi-http/src/p2/wit/deps/sockets/tcp-create-socket.wit similarity index 100% rename from crates/wasi-http/wit/deps/sockets/tcp-create-socket.wit rename to crates/wasi-http/src/p2/wit/deps/sockets/tcp-create-socket.wit diff --git a/crates/wasi-http/wit/deps/sockets/tcp.wit b/crates/wasi-http/src/p2/wit/deps/sockets/tcp.wit similarity index 100% rename from crates/wasi-http/wit/deps/sockets/tcp.wit rename to crates/wasi-http/src/p2/wit/deps/sockets/tcp.wit diff --git a/crates/wasi-http/wit/deps/sockets/udp-create-socket.wit b/crates/wasi-http/src/p2/wit/deps/sockets/udp-create-socket.wit similarity index 100% rename from crates/wasi-http/wit/deps/sockets/udp-create-socket.wit rename to crates/wasi-http/src/p2/wit/deps/sockets/udp-create-socket.wit diff --git a/crates/wasi-http/wit/deps/sockets/udp.wit b/crates/wasi-http/src/p2/wit/deps/sockets/udp.wit similarity index 100% rename from crates/wasi-http/wit/deps/sockets/udp.wit rename to crates/wasi-http/src/p2/wit/deps/sockets/udp.wit diff --git a/crates/wasi-http/wit/deps/sockets/world.wit b/crates/wasi-http/src/p2/wit/deps/sockets/world.wit similarity index 100% rename from crates/wasi-http/wit/deps/sockets/world.wit rename to crates/wasi-http/src/p2/wit/deps/sockets/world.wit diff --git a/crates/wasi-http/wit/world.wit b/crates/wasi-http/src/p2/wit/world.wit similarity index 100% rename from crates/wasi-http/wit/world.wit rename to crates/wasi-http/src/p2/wit/world.wit diff --git a/crates/wasi-keyvalue/src/lib.rs b/crates/wasi-keyvalue/src/lib.rs index ce8d5b276984..b86acf656f46 100644 --- a/crates/wasi-keyvalue/src/lib.rs +++ b/crates/wasi-keyvalue/src/lib.rs @@ -67,24 +67,12 @@ #![deny(missing_docs)] -mod generated { - wasmtime::component::bindgen!({ - path: "wit", - world: "wasi:keyvalue/imports", - trappable_imports: true, - with: { - "wasi:keyvalue/store/bucket": crate::Bucket, - }, - trappable_error_type: { - "wasi:keyvalue/store/error" => crate::Error, - }, - }); -} - -use self::generated::wasi::keyvalue; -use anyhow::Result; use std::collections::HashMap; -use wasmtime::component::{Resource, ResourceTable, ResourceTableError}; +use wasmtime::component::{ResourceTable, ResourceTableError}; + +pub mod p2; +#[doc(inline)] +pub use p2::*; #[doc(hidden)] pub enum Error { @@ -162,138 +150,3 @@ impl<'a> WasiKeyValue<'a> { Self { ctx, table } } } - -impl keyvalue::store::Host for WasiKeyValue<'_> { - fn open(&mut self, identifier: String) -> Result, Error> { - match identifier.as_str() { - "" => Ok(self.table.push(Bucket { - in_memory_data: self.ctx.in_memory_data.clone(), - })?), - _ => Err(Error::NoSuchStore), - } - } - - fn convert_error(&mut self, err: Error) -> Result { - match err { - Error::NoSuchStore => Ok(keyvalue::store::Error::NoSuchStore), - Error::AccessDenied => Ok(keyvalue::store::Error::AccessDenied), - Error::Other(e) => Ok(keyvalue::store::Error::Other(e)), - } - } -} - -impl keyvalue::store::HostBucket for WasiKeyValue<'_> { - fn get(&mut self, bucket: Resource, key: String) -> Result>, Error> { - let bucket = self.table.get_mut(&bucket)?; - Ok(bucket.in_memory_data.get(&key).cloned()) - } - - fn set(&mut self, bucket: Resource, key: String, value: Vec) -> Result<(), Error> { - let bucket = self.table.get_mut(&bucket)?; - bucket.in_memory_data.insert(key, value); - Ok(()) - } - - fn delete(&mut self, bucket: Resource, key: String) -> Result<(), Error> { - let bucket = self.table.get_mut(&bucket)?; - bucket.in_memory_data.remove(&key); - Ok(()) - } - - fn exists(&mut self, bucket: Resource, key: String) -> Result { - let bucket = self.table.get_mut(&bucket)?; - Ok(bucket.in_memory_data.contains_key(&key)) - } - - fn list_keys( - &mut self, - bucket: Resource, - cursor: Option, - ) -> Result { - let bucket = self.table.get_mut(&bucket)?; - let keys: Vec = bucket.in_memory_data.keys().cloned().collect(); - let cursor = cursor.unwrap_or(0) as usize; - let keys_slice = &keys[cursor..]; - Ok(keyvalue::store::KeyResponse { - keys: keys_slice.to_vec(), - cursor: None, - }) - } - - fn drop(&mut self, bucket: Resource) -> Result<()> { - self.table.delete(bucket)?; - Ok(()) - } -} - -impl keyvalue::atomics::Host for WasiKeyValue<'_> { - fn increment( - &mut self, - bucket: Resource, - key: String, - delta: u64, - ) -> Result { - let bucket = self.table.get_mut(&bucket)?; - let value = bucket - .in_memory_data - .entry(key.clone()) - .or_insert("0".to_string().into_bytes()); - let current_value = String::from_utf8(value.clone()) - .map_err(|e| Error::Other(e.to_string()))? - .parse::() - .map_err(|e| Error::Other(e.to_string()))?; - let new_value = current_value + delta; - *value = new_value.to_string().into_bytes(); - Ok(new_value) - } -} - -impl keyvalue::batch::Host for WasiKeyValue<'_> { - fn get_many( - &mut self, - bucket: Resource, - keys: Vec, - ) -> Result)>>, Error> { - let bucket = self.table.get_mut(&bucket)?; - Ok(keys - .into_iter() - .map(|key| { - bucket - .in_memory_data - .get(&key) - .map(|value| (key.clone(), value.clone())) - }) - .collect()) - } - - fn set_many( - &mut self, - bucket: Resource, - key_values: Vec<(String, Vec)>, - ) -> Result<(), Error> { - let bucket = self.table.get_mut(&bucket)?; - for (key, value) in key_values { - bucket.in_memory_data.insert(key, value); - } - Ok(()) - } - - fn delete_many(&mut self, bucket: Resource, keys: Vec) -> Result<(), Error> { - let bucket = self.table.get_mut(&bucket)?; - for key in keys { - bucket.in_memory_data.remove(&key); - } - Ok(()) - } -} - -/// Add all the `wasi-keyvalue` world's interfaces to a [`wasmtime::component::Linker`]. -pub fn add_to_linker( - l: &mut wasmtime::component::Linker, - f: impl Fn(&mut T) -> WasiKeyValue<'_> + Send + Sync + Copy + 'static, -) -> Result<()> { - keyvalue::store::add_to_linker_get_host(l, f)?; - keyvalue::atomics::add_to_linker_get_host(l, f)?; - keyvalue::batch::add_to_linker_get_host(l, f)?; - Ok(()) -} diff --git a/crates/wasi-keyvalue/src/p2/mod.rs b/crates/wasi-keyvalue/src/p2/mod.rs new file mode 100644 index 000000000000..5ead357be277 --- /dev/null +++ b/crates/wasi-keyvalue/src/p2/mod.rs @@ -0,0 +1,157 @@ +//! Implementation of wasip2 version of `wasi:keyvalue` package + +mod generated { + wasmtime::component::bindgen!({ + path: "src/p2/wit", + world: "wasi:keyvalue/imports", + trappable_imports: true, + with: { + "wasi:keyvalue/store/bucket": crate::Bucket, + }, + trappable_error_type: { + "wasi:keyvalue/store/error" => crate::Error, + }, + }); +} + +use self::generated::wasi::keyvalue; + +use anyhow::Result; +use wasmtime::component::Resource; + +use crate::{Bucket, Error, WasiKeyValue}; + +impl keyvalue::store::Host for WasiKeyValue<'_> { + fn open(&mut self, identifier: String) -> Result, Error> { + match identifier.as_str() { + "" => Ok(self.table.push(Bucket { + in_memory_data: self.ctx.in_memory_data.clone(), + })?), + _ => Err(Error::NoSuchStore), + } + } + + fn convert_error(&mut self, err: Error) -> Result { + match err { + Error::NoSuchStore => Ok(keyvalue::store::Error::NoSuchStore), + Error::AccessDenied => Ok(keyvalue::store::Error::AccessDenied), + Error::Other(e) => Ok(keyvalue::store::Error::Other(e)), + } + } +} + +impl keyvalue::store::HostBucket for WasiKeyValue<'_> { + fn get(&mut self, bucket: Resource, key: String) -> Result>, Error> { + let bucket = self.table.get_mut(&bucket)?; + Ok(bucket.in_memory_data.get(&key).cloned()) + } + + fn set(&mut self, bucket: Resource, key: String, value: Vec) -> Result<(), Error> { + let bucket = self.table.get_mut(&bucket)?; + bucket.in_memory_data.insert(key, value); + Ok(()) + } + + fn delete(&mut self, bucket: Resource, key: String) -> Result<(), Error> { + let bucket = self.table.get_mut(&bucket)?; + bucket.in_memory_data.remove(&key); + Ok(()) + } + + fn exists(&mut self, bucket: Resource, key: String) -> Result { + let bucket = self.table.get_mut(&bucket)?; + Ok(bucket.in_memory_data.contains_key(&key)) + } + + fn list_keys( + &mut self, + bucket: Resource, + cursor: Option, + ) -> Result { + let bucket = self.table.get_mut(&bucket)?; + let keys: Vec = bucket.in_memory_data.keys().cloned().collect(); + let cursor = cursor.unwrap_or(0) as usize; + let keys_slice = &keys[cursor..]; + Ok(keyvalue::store::KeyResponse { + keys: keys_slice.to_vec(), + cursor: None, + }) + } + + fn drop(&mut self, bucket: Resource) -> Result<()> { + self.table.delete(bucket)?; + Ok(()) + } +} + +impl keyvalue::atomics::Host for WasiKeyValue<'_> { + fn increment( + &mut self, + bucket: Resource, + key: String, + delta: u64, + ) -> Result { + let bucket = self.table.get_mut(&bucket)?; + let value = bucket + .in_memory_data + .entry(key.clone()) + .or_insert("0".to_string().into_bytes()); + let current_value = String::from_utf8(value.clone()) + .map_err(|e| Error::Other(e.to_string()))? + .parse::() + .map_err(|e| Error::Other(e.to_string()))?; + let new_value = current_value + delta; + *value = new_value.to_string().into_bytes(); + Ok(new_value) + } +} + +impl keyvalue::batch::Host for WasiKeyValue<'_> { + fn get_many( + &mut self, + bucket: Resource, + keys: Vec, + ) -> Result)>>, Error> { + let bucket = self.table.get_mut(&bucket)?; + Ok(keys + .into_iter() + .map(|key| { + bucket + .in_memory_data + .get(&key) + .map(|value| (key.clone(), value.clone())) + }) + .collect()) + } + + fn set_many( + &mut self, + bucket: Resource, + key_values: Vec<(String, Vec)>, + ) -> Result<(), Error> { + let bucket = self.table.get_mut(&bucket)?; + for (key, value) in key_values { + bucket.in_memory_data.insert(key, value); + } + Ok(()) + } + + fn delete_many(&mut self, bucket: Resource, keys: Vec) -> Result<(), Error> { + let bucket = self.table.get_mut(&bucket)?; + for key in keys { + bucket.in_memory_data.remove(&key); + } + Ok(()) + } +} + +/// Add all the `wasi-keyvalue` world's interfaces to a [`wasmtime::component::Linker`]. +pub fn add_to_linker( + l: &mut wasmtime::component::Linker, + f: impl Fn(&mut T) -> WasiKeyValue<'_> + Send + Sync + Copy + 'static, +) -> Result<()> { + keyvalue::store::add_to_linker_get_host(l, f)?; + keyvalue::atomics::add_to_linker_get_host(l, f)?; + keyvalue::batch::add_to_linker_get_host(l, f)?; + Ok(()) +} diff --git a/crates/wasi-keyvalue/wit/deps/keyvalue/atomic.wit b/crates/wasi-keyvalue/src/p2/wit/deps/keyvalue/atomic.wit similarity index 100% rename from crates/wasi-keyvalue/wit/deps/keyvalue/atomic.wit rename to crates/wasi-keyvalue/src/p2/wit/deps/keyvalue/atomic.wit diff --git a/crates/wasi-keyvalue/wit/deps/keyvalue/batch.wit b/crates/wasi-keyvalue/src/p2/wit/deps/keyvalue/batch.wit similarity index 100% rename from crates/wasi-keyvalue/wit/deps/keyvalue/batch.wit rename to crates/wasi-keyvalue/src/p2/wit/deps/keyvalue/batch.wit diff --git a/crates/wasi-keyvalue/wit/deps/keyvalue/store.wit b/crates/wasi-keyvalue/src/p2/wit/deps/keyvalue/store.wit similarity index 100% rename from crates/wasi-keyvalue/wit/deps/keyvalue/store.wit rename to crates/wasi-keyvalue/src/p2/wit/deps/keyvalue/store.wit diff --git a/crates/wasi-keyvalue/wit/deps/keyvalue/watch.wit b/crates/wasi-keyvalue/src/p2/wit/deps/keyvalue/watch.wit similarity index 100% rename from crates/wasi-keyvalue/wit/deps/keyvalue/watch.wit rename to crates/wasi-keyvalue/src/p2/wit/deps/keyvalue/watch.wit diff --git a/crates/wasi-keyvalue/wit/deps/keyvalue/world.wit b/crates/wasi-keyvalue/src/p2/wit/deps/keyvalue/world.wit similarity index 100% rename from crates/wasi-keyvalue/wit/deps/keyvalue/world.wit rename to crates/wasi-keyvalue/src/p2/wit/deps/keyvalue/world.wit diff --git a/crates/wasi-keyvalue/wit/world.wit b/crates/wasi-keyvalue/src/p2/wit/world.wit similarity index 100% rename from crates/wasi-keyvalue/wit/world.wit rename to crates/wasi-keyvalue/src/p2/wit/world.wit diff --git a/crates/wasi-preview1-component-adapter/src/lib.rs b/crates/wasi-preview1-component-adapter/src/lib.rs index ad077ca9ed9b..fef8e08d6548 100644 --- a/crates/wasi-preview1-component-adapter/src/lib.rs +++ b/crates/wasi-preview1-component-adapter/src/lib.rs @@ -52,7 +52,7 @@ use crate::descriptors::{Descriptor, Descriptors, StreamType, Streams}; pub mod bindings { #[cfg(feature = "command")] wit_bindgen_rust_macro::generate!({ - path: "../wasi/wit", + path: "../wasi/src/p2/wit", world: "wasi:cli/command", raw_strings, runtime_path: "crate::bindings::wit_bindgen_rt_shim", @@ -69,7 +69,7 @@ pub mod bindings { #[cfg(feature = "reactor")] wit_bindgen_rust_macro::generate!({ - path: "../wasi/wit", + path: "../wasi/src/p2/wit", world: "wasi:cli/imports", raw_strings, runtime_path: "crate::bindings::wit_bindgen_rt_shim", @@ -86,7 +86,7 @@ pub mod bindings { #[cfg(feature = "proxy")] wit_bindgen_rust_macro::generate!({ - path: "../wasi-http/wit", + path: "../wasi-http/src/p2/wit", inline: r#" package wasmtime:adapter; diff --git a/crates/wasi/src/ctx.rs b/crates/wasi/src/ctx.rs index b86895712a9e..25ef1c512766 100644 --- a/crates/wasi/src/ctx.rs +++ b/crates/wasi/src/ctx.rs @@ -560,9 +560,9 @@ impl WasiCtxBuilder { /// Per-[`Store`] state which holds state necessary to implement WASI from this /// crate. /// -/// This structure is created through [`WasiCtxBuilder`] and is stored within +/// This structure is created through [`WasiCtxBuilder`](crate::WasiCtxBuilder) and is stored within /// the `T` of [`Store`][`Store`]. Access to the structure is provided -/// through the [`WasiView`] trait as an implementation on `T`. +/// through the [`WasiView`](crate::WasiView) trait as an implementation on `T`. /// /// Note that this structure itself does not have any accessors, it's here for /// internal use within the `wasmtime-wasi` crate's implementation of diff --git a/crates/wasi/src/lib.rs b/crates/wasi/src/lib.rs index 58375b784f70..277992c960d4 100644 --- a/crates/wasi/src/lib.rs +++ b/crates/wasi/src/lib.rs @@ -183,16 +183,13 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![expect(clippy::allow_attributes_without_reason, reason = "crate not migrated")] -use wasmtime::component::Linker; - -pub mod bindings; mod clocks; mod ctx; mod error; mod filesystem; -mod host; mod ip_name_lookup; mod network; +pub mod p2; pub mod pipe; mod poll; #[cfg(feature = "preview1")] @@ -229,212 +226,11 @@ pub use async_trait::async_trait; pub use cap_fs_ext::SystemTimeSpec; #[doc(no_inline)] pub use cap_rand::RngCore; +#[doc(inline)] +pub use p2::*; #[doc(no_inline)] pub use wasmtime::component::{ResourceTable, ResourceTableError}; -/// Add all WASI interfaces from this crate into the `linker` provided. -/// -/// This function will add the `async` variant of all interfaces into the -/// [`Linker`] provided. By `async` this means that this function is only -/// compatible with [`Config::async_support(true)`][async]. For embeddings with -/// async support disabled see [`add_to_linker_sync`] instead. -/// -/// This function will add all interfaces implemented by this crate to the -/// [`Linker`], which corresponds to the `wasi:cli/imports` world supported by -/// this crate. -/// -/// [async]: wasmtime::Config::async_support -/// -/// # Example -/// -/// ``` -/// use wasmtime::{Engine, Result, Store, Config}; -/// use wasmtime::component::{ResourceTable, Linker}; -/// use wasmtime_wasi::{IoView, WasiCtx, WasiView, WasiCtxBuilder}; -/// -/// fn main() -> Result<()> { -/// let mut config = Config::new(); -/// config.async_support(true); -/// let engine = Engine::new(&config)?; -/// -/// let mut linker = Linker::::new(&engine); -/// wasmtime_wasi::add_to_linker_async(&mut linker)?; -/// // ... add any further functionality to `linker` if desired ... -/// -/// let mut builder = WasiCtxBuilder::new(); -/// -/// // ... configure `builder` more to add env vars, args, etc ... -/// -/// let mut store = Store::new( -/// &engine, -/// MyState { -/// ctx: builder.build(), -/// table: ResourceTable::new(), -/// }, -/// ); -/// -/// // ... use `linker` to instantiate within `store` ... -/// -/// Ok(()) -/// } -/// -/// 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 } -/// } -/// ``` -pub fn add_to_linker_async(linker: &mut Linker) -> anyhow::Result<()> { - let options = crate::bindings::LinkOptions::default(); - add_to_linker_with_options_async(linker, &options) -} - -/// Similar to [`add_to_linker_async`], but with the ability to enable unstable features. -pub fn add_to_linker_with_options_async( - linker: &mut Linker, - options: &crate::bindings::LinkOptions, -) -> anyhow::Result<()> { - let l = linker; - 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, 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)?; - crate::bindings::cli::exit::add_to_linker_get_host(l, &options.into(), closure)?; - crate::bindings::cli::environment::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::stdin::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::stdout::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::stderr::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::terminal_input::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::terminal_output::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::terminal_stdin::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::terminal_stdout::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::terminal_stderr::add_to_linker_get_host(l, closure)?; - crate::bindings::sockets::tcp::add_to_linker_get_host(l, closure)?; - crate::bindings::sockets::tcp_create_socket::add_to_linker_get_host(l, closure)?; - crate::bindings::sockets::udp::add_to_linker_get_host(l, closure)?; - crate::bindings::sockets::udp_create_socket::add_to_linker_get_host(l, closure)?; - crate::bindings::sockets::instance_network::add_to_linker_get_host(l, closure)?; - crate::bindings::sockets::network::add_to_linker_get_host(l, &options.into(), closure)?; - crate::bindings::sockets::ip_name_lookup::add_to_linker_get_host(l, closure)?; - Ok(()) -} - -/// Add all WASI interfaces from this crate into the `linker` provided. -/// -/// This function will add the synchronous variant of all interfaces into the -/// [`Linker`] provided. By synchronous this means that this function is only -/// compatible with [`Config::async_support(false)`][async]. For embeddings -/// with async support enabled see [`add_to_linker_async`] instead. -/// -/// This function will add all interfaces implemented by this crate to the -/// [`Linker`], which corresponds to the `wasi:cli/imports` world supported by -/// this crate. -/// -/// [async]: wasmtime::Config::async_support -/// -/// # Example -/// -/// ``` -/// use wasmtime::{Engine, Result, Store, Config}; -/// use wasmtime::component::{ResourceTable, Linker}; -/// use wasmtime_wasi::{IoView, WasiCtx, WasiView, WasiCtxBuilder}; -/// -/// fn main() -> Result<()> { -/// let engine = Engine::default(); -/// -/// let mut linker = Linker::::new(&engine); -/// wasmtime_wasi::add_to_linker_sync(&mut linker)?; -/// // ... add any further functionality to `linker` if desired ... -/// -/// let mut builder = WasiCtxBuilder::new(); -/// -/// // ... configure `builder` more to add env vars, args, etc ... -/// -/// let mut store = Store::new( -/// &engine, -/// MyState { -/// ctx: builder.build(), -/// table: ResourceTable::new(), -/// }, -/// ); -/// -/// // ... use `linker` to instantiate within `store` ... -/// -/// Ok(()) -/// } -/// -/// 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 } -/// } -/// ``` -pub fn add_to_linker_sync( - linker: &mut wasmtime::component::Linker, -) -> anyhow::Result<()> { - let options = crate::bindings::sync::LinkOptions::default(); - add_to_linker_with_options_sync(linker, &options) -} - -/// Similar to [`add_to_linker_sync`], but with the ability to enable unstable features. -pub fn add_to_linker_with_options_sync( - linker: &mut wasmtime::component::Linker, - options: &crate::bindings::sync::LinkOptions, -) -> anyhow::Result<()> { - let l = linker; - 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, 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)?; - crate::bindings::cli::exit::add_to_linker_get_host(l, &options.into(), closure)?; - crate::bindings::cli::environment::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::stdin::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::stdout::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::stderr::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::terminal_input::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::terminal_output::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::terminal_stdin::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::terminal_stdout::add_to_linker_get_host(l, closure)?; - crate::bindings::cli::terminal_stderr::add_to_linker_get_host(l, closure)?; - crate::bindings::sync::sockets::tcp::add_to_linker_get_host(l, closure)?; - crate::bindings::sockets::tcp_create_socket::add_to_linker_get_host(l, closure)?; - crate::bindings::sync::sockets::udp::add_to_linker_get_host(l, closure)?; - crate::bindings::sockets::udp_create_socket::add_to_linker_get_host(l, closure)?; - crate::bindings::sockets::instance_network::add_to_linker_get_host(l, closure)?; - crate::bindings::sockets::network::add_to_linker_get_host(l, &options.into(), closure)?; - crate::bindings::sockets::ip_name_lookup::add_to_linker_get_host(l, closure)?; - Ok(()) -} - // NB: workaround some rustc inference - a future refactoring may make this // obsolete. fn io_type_annotate(val: F) -> F diff --git a/crates/wasi/src/bindings.rs b/crates/wasi/src/p2/bindings.rs similarity index 99% rename from crates/wasi/src/bindings.rs rename to crates/wasi/src/p2/bindings.rs index 7449b3a3f202..b1f8d7e40e65 100644 --- a/crates/wasi/src/bindings.rs +++ b/crates/wasi/src/p2/bindings.rs @@ -35,7 +35,7 @@ //! my-custom-function: func(); //! } //! ", -//! path: "wit", +//! path: "src/p2/wit", //! with: { //! "wasi": wasmtime_wasi::bindings, //! }, @@ -106,7 +106,7 @@ /// my-custom-function: func(); /// } /// ", -/// path: "wit", +/// path: "src/p2/wit", /// with: { /// "wasi": wasmtime_wasi::bindings::sync, /// }, @@ -149,7 +149,7 @@ pub mod sync { use crate::{FsError, SocketError, StreamError}; wasmtime::component::bindgen!({ - path: "wit", + path: "src/p2/wit", world: "wasi:cli/command", tracing: true, trappable_error_type: { @@ -333,7 +333,7 @@ pub mod sync { mod async_io { wasmtime::component::bindgen!({ - path: "wit", + path: "src/p2/wit", world: "wasi:cli/command", tracing: true, trappable_imports: true, diff --git a/crates/wasi/src/host/clocks.rs b/crates/wasi/src/p2/host/clocks.rs similarity index 100% rename from crates/wasi/src/host/clocks.rs rename to crates/wasi/src/p2/host/clocks.rs diff --git a/crates/wasi/src/host/env.rs b/crates/wasi/src/p2/host/env.rs similarity index 100% rename from crates/wasi/src/host/env.rs rename to crates/wasi/src/p2/host/env.rs diff --git a/crates/wasi/src/host/exit.rs b/crates/wasi/src/p2/host/exit.rs similarity index 100% rename from crates/wasi/src/host/exit.rs rename to crates/wasi/src/p2/host/exit.rs diff --git a/crates/wasi/src/host/filesystem.rs b/crates/wasi/src/p2/host/filesystem.rs similarity index 100% rename from crates/wasi/src/host/filesystem.rs rename to crates/wasi/src/p2/host/filesystem.rs diff --git a/crates/wasi/src/host/filesystem/sync.rs b/crates/wasi/src/p2/host/filesystem/sync.rs similarity index 100% rename from crates/wasi/src/host/filesystem/sync.rs rename to crates/wasi/src/p2/host/filesystem/sync.rs diff --git a/crates/wasi/src/host/instance_network.rs b/crates/wasi/src/p2/host/instance_network.rs similarity index 100% rename from crates/wasi/src/host/instance_network.rs rename to crates/wasi/src/p2/host/instance_network.rs diff --git a/crates/wasi/src/host/io.rs b/crates/wasi/src/p2/host/io.rs similarity index 100% rename from crates/wasi/src/host/io.rs rename to crates/wasi/src/p2/host/io.rs diff --git a/crates/wasi/src/host/mod.rs b/crates/wasi/src/p2/host/mod.rs similarity index 100% rename from crates/wasi/src/host/mod.rs rename to crates/wasi/src/p2/host/mod.rs diff --git a/crates/wasi/src/host/network.rs b/crates/wasi/src/p2/host/network.rs similarity index 100% rename from crates/wasi/src/host/network.rs rename to crates/wasi/src/p2/host/network.rs diff --git a/crates/wasi/src/host/random.rs b/crates/wasi/src/p2/host/random.rs similarity index 100% rename from crates/wasi/src/host/random.rs rename to crates/wasi/src/p2/host/random.rs diff --git a/crates/wasi/src/host/tcp.rs b/crates/wasi/src/p2/host/tcp.rs similarity index 100% rename from crates/wasi/src/host/tcp.rs rename to crates/wasi/src/p2/host/tcp.rs diff --git a/crates/wasi/src/host/tcp_create_socket.rs b/crates/wasi/src/p2/host/tcp_create_socket.rs similarity index 100% rename from crates/wasi/src/host/tcp_create_socket.rs rename to crates/wasi/src/p2/host/tcp_create_socket.rs diff --git a/crates/wasi/src/host/udp.rs b/crates/wasi/src/p2/host/udp.rs similarity index 100% rename from crates/wasi/src/host/udp.rs rename to crates/wasi/src/p2/host/udp.rs diff --git a/crates/wasi/src/host/udp_create_socket.rs b/crates/wasi/src/p2/host/udp_create_socket.rs similarity index 100% rename from crates/wasi/src/host/udp_create_socket.rs rename to crates/wasi/src/p2/host/udp_create_socket.rs diff --git a/crates/wasi/src/p2/mod.rs b/crates/wasi/src/p2/mod.rs new file mode 100644 index 000000000000..b493af55a48d --- /dev/null +++ b/crates/wasi/src/p2/mod.rs @@ -0,0 +1,211 @@ +//! Implementation of wasip2 version of WASI + +use wasmtime::component::Linker; + +use crate::{io_type_annotate, type_annotate, IoImpl, WasiImpl, WasiView}; + +pub mod bindings; +pub(crate) mod host; + +/// Add all WASI interfaces from this module into the `linker` provided. +/// +/// This function will add the `async` variant of all interfaces into the +/// [`Linker`] provided. By `async` this means that this function is only +/// compatible with [`Config::async_support(true)`][async]. For embeddings with +/// async support disabled see [`add_to_linker_sync`] instead. +/// +/// This function will add all interfaces implemented by this crate to the +/// [`Linker`], which corresponds to the `wasi:cli/imports` world supported by +/// this crate. +/// +/// [async]: wasmtime::Config::async_support +/// +/// # Example +/// +/// ``` +/// use wasmtime::{Engine, Result, Store, Config}; +/// use wasmtime::component::{ResourceTable, Linker}; +/// use wasmtime_wasi::{IoView, WasiCtx, WasiView, WasiCtxBuilder}; +/// +/// fn main() -> Result<()> { +/// let mut config = Config::new(); +/// config.async_support(true); +/// let engine = Engine::new(&config)?; +/// +/// let mut linker = Linker::::new(&engine); +/// wasmtime_wasi::add_to_linker_async(&mut linker)?; +/// // ... add any further functionality to `linker` if desired ... +/// +/// let mut builder = WasiCtxBuilder::new(); +/// +/// // ... configure `builder` more to add env vars, args, etc ... +/// +/// let mut store = Store::new( +/// &engine, +/// MyState { +/// ctx: builder.build(), +/// table: ResourceTable::new(), +/// }, +/// ); +/// +/// // ... use `linker` to instantiate within `store` ... +/// +/// Ok(()) +/// } +/// +/// 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 } +/// } +/// ``` +pub fn add_to_linker_async(linker: &mut Linker) -> anyhow::Result<()> { + let options = crate::bindings::LinkOptions::default(); + add_to_linker_with_options_async(linker, &options) +} + +/// Similar to [`add_to_linker_async`], but with the ability to enable unstable features. +pub fn add_to_linker_with_options_async( + linker: &mut Linker, + options: &crate::bindings::LinkOptions, +) -> anyhow::Result<()> { + let l = linker; + 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, 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)?; + crate::bindings::cli::exit::add_to_linker_get_host(l, &options.into(), closure)?; + crate::bindings::cli::environment::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stdin::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stdout::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stderr::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_input::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_output::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stdin::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stdout::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stderr::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::tcp::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::tcp_create_socket::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::udp::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::udp_create_socket::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::instance_network::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::network::add_to_linker_get_host(l, &options.into(), closure)?; + crate::bindings::sockets::ip_name_lookup::add_to_linker_get_host(l, closure)?; + Ok(()) +} + +/// Add all WASI interfaces from this crate into the `linker` provided. +/// +/// This function will add the synchronous variant of all interfaces into the +/// [`Linker`] provided. By synchronous this means that this function is only +/// compatible with [`Config::async_support(false)`][async]. For embeddings +/// with async support enabled see [`add_to_linker_async`] instead. +/// +/// This function will add all interfaces implemented by this crate to the +/// [`Linker`], which corresponds to the `wasi:cli/imports` world supported by +/// this crate. +/// +/// [async]: wasmtime::Config::async_support +/// +/// # Example +/// +/// ``` +/// use wasmtime::{Engine, Result, Store, Config}; +/// use wasmtime::component::{ResourceTable, Linker}; +/// use wasmtime_wasi::{IoView, WasiCtx, WasiView, WasiCtxBuilder}; +/// +/// fn main() -> Result<()> { +/// let engine = Engine::default(); +/// +/// let mut linker = Linker::::new(&engine); +/// wasmtime_wasi::add_to_linker_sync(&mut linker)?; +/// // ... add any further functionality to `linker` if desired ... +/// +/// let mut builder = WasiCtxBuilder::new(); +/// +/// // ... configure `builder` more to add env vars, args, etc ... +/// +/// let mut store = Store::new( +/// &engine, +/// MyState { +/// ctx: builder.build(), +/// table: ResourceTable::new(), +/// }, +/// ); +/// +/// // ... use `linker` to instantiate within `store` ... +/// +/// Ok(()) +/// } +/// +/// 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 } +/// } +/// ``` +pub fn add_to_linker_sync( + linker: &mut wasmtime::component::Linker, +) -> anyhow::Result<()> { + let options = crate::bindings::sync::LinkOptions::default(); + add_to_linker_with_options_sync(linker, &options) +} + +/// Similar to [`add_to_linker_sync`], but with the ability to enable unstable features. +pub fn add_to_linker_with_options_sync( + linker: &mut wasmtime::component::Linker, + options: &crate::bindings::sync::LinkOptions, +) -> anyhow::Result<()> { + let l = linker; + 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, 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)?; + crate::bindings::cli::exit::add_to_linker_get_host(l, &options.into(), closure)?; + crate::bindings::cli::environment::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stdin::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stdout::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stderr::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_input::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_output::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stdin::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stdout::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stderr::add_to_linker_get_host(l, closure)?; + crate::bindings::sync::sockets::tcp::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::tcp_create_socket::add_to_linker_get_host(l, closure)?; + crate::bindings::sync::sockets::udp::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::udp_create_socket::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::instance_network::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::network::add_to_linker_get_host(l, &options.into(), closure)?; + crate::bindings::sockets::ip_name_lookup::add_to_linker_get_host(l, closure)?; + Ok(()) +} diff --git a/crates/wasi/wit/deps/cli/command.wit b/crates/wasi/src/p2/wit/deps/cli/command.wit similarity index 100% rename from crates/wasi/wit/deps/cli/command.wit rename to crates/wasi/src/p2/wit/deps/cli/command.wit diff --git a/crates/wasi/wit/deps/cli/environment.wit b/crates/wasi/src/p2/wit/deps/cli/environment.wit similarity index 100% rename from crates/wasi/wit/deps/cli/environment.wit rename to crates/wasi/src/p2/wit/deps/cli/environment.wit diff --git a/crates/wasi/wit/deps/cli/exit.wit b/crates/wasi/src/p2/wit/deps/cli/exit.wit similarity index 100% rename from crates/wasi/wit/deps/cli/exit.wit rename to crates/wasi/src/p2/wit/deps/cli/exit.wit diff --git a/crates/wasi/wit/deps/cli/imports.wit b/crates/wasi/src/p2/wit/deps/cli/imports.wit similarity index 100% rename from crates/wasi/wit/deps/cli/imports.wit rename to crates/wasi/src/p2/wit/deps/cli/imports.wit diff --git a/crates/wasi/wit/deps/cli/run.wit b/crates/wasi/src/p2/wit/deps/cli/run.wit similarity index 100% rename from crates/wasi/wit/deps/cli/run.wit rename to crates/wasi/src/p2/wit/deps/cli/run.wit diff --git a/crates/wasi/wit/deps/cli/stdio.wit b/crates/wasi/src/p2/wit/deps/cli/stdio.wit similarity index 100% rename from crates/wasi/wit/deps/cli/stdio.wit rename to crates/wasi/src/p2/wit/deps/cli/stdio.wit diff --git a/crates/wasi/wit/deps/cli/terminal.wit b/crates/wasi/src/p2/wit/deps/cli/terminal.wit similarity index 100% rename from crates/wasi/wit/deps/cli/terminal.wit rename to crates/wasi/src/p2/wit/deps/cli/terminal.wit diff --git a/crates/wasi/wit/deps/clocks/monotonic-clock.wit b/crates/wasi/src/p2/wit/deps/clocks/monotonic-clock.wit similarity index 100% rename from crates/wasi/wit/deps/clocks/monotonic-clock.wit rename to crates/wasi/src/p2/wit/deps/clocks/monotonic-clock.wit diff --git a/crates/wasi/wit/deps/clocks/timezone.wit b/crates/wasi/src/p2/wit/deps/clocks/timezone.wit similarity index 100% rename from crates/wasi/wit/deps/clocks/timezone.wit rename to crates/wasi/src/p2/wit/deps/clocks/timezone.wit diff --git a/crates/wasi/wit/deps/clocks/wall-clock.wit b/crates/wasi/src/p2/wit/deps/clocks/wall-clock.wit similarity index 100% rename from crates/wasi/wit/deps/clocks/wall-clock.wit rename to crates/wasi/src/p2/wit/deps/clocks/wall-clock.wit diff --git a/crates/wasi/wit/deps/clocks/world.wit b/crates/wasi/src/p2/wit/deps/clocks/world.wit similarity index 100% rename from crates/wasi/wit/deps/clocks/world.wit rename to crates/wasi/src/p2/wit/deps/clocks/world.wit diff --git a/crates/wasi/wit/deps/filesystem/preopens.wit b/crates/wasi/src/p2/wit/deps/filesystem/preopens.wit similarity index 100% rename from crates/wasi/wit/deps/filesystem/preopens.wit rename to crates/wasi/src/p2/wit/deps/filesystem/preopens.wit diff --git a/crates/wasi/wit/deps/filesystem/types.wit b/crates/wasi/src/p2/wit/deps/filesystem/types.wit similarity index 100% rename from crates/wasi/wit/deps/filesystem/types.wit rename to crates/wasi/src/p2/wit/deps/filesystem/types.wit diff --git a/crates/wasi/wit/deps/filesystem/world.wit b/crates/wasi/src/p2/wit/deps/filesystem/world.wit similarity index 100% rename from crates/wasi/wit/deps/filesystem/world.wit rename to crates/wasi/src/p2/wit/deps/filesystem/world.wit diff --git a/crates/wasi/wit/deps/io/error.wit b/crates/wasi/src/p2/wit/deps/io/error.wit similarity index 100% rename from crates/wasi/wit/deps/io/error.wit rename to crates/wasi/src/p2/wit/deps/io/error.wit diff --git a/crates/wasi/wit/deps/io/poll.wit b/crates/wasi/src/p2/wit/deps/io/poll.wit similarity index 100% rename from crates/wasi/wit/deps/io/poll.wit rename to crates/wasi/src/p2/wit/deps/io/poll.wit diff --git a/crates/wasi/wit/deps/io/streams.wit b/crates/wasi/src/p2/wit/deps/io/streams.wit similarity index 100% rename from crates/wasi/wit/deps/io/streams.wit rename to crates/wasi/src/p2/wit/deps/io/streams.wit diff --git a/crates/wasi/wit/deps/io/world.wit b/crates/wasi/src/p2/wit/deps/io/world.wit similarity index 100% rename from crates/wasi/wit/deps/io/world.wit rename to crates/wasi/src/p2/wit/deps/io/world.wit diff --git a/crates/wasi/wit/deps/random/insecure-seed.wit b/crates/wasi/src/p2/wit/deps/random/insecure-seed.wit similarity index 100% rename from crates/wasi/wit/deps/random/insecure-seed.wit rename to crates/wasi/src/p2/wit/deps/random/insecure-seed.wit diff --git a/crates/wasi/wit/deps/random/insecure.wit b/crates/wasi/src/p2/wit/deps/random/insecure.wit similarity index 100% rename from crates/wasi/wit/deps/random/insecure.wit rename to crates/wasi/src/p2/wit/deps/random/insecure.wit diff --git a/crates/wasi/wit/deps/random/random.wit b/crates/wasi/src/p2/wit/deps/random/random.wit similarity index 100% rename from crates/wasi/wit/deps/random/random.wit rename to crates/wasi/src/p2/wit/deps/random/random.wit diff --git a/crates/wasi/wit/deps/random/world.wit b/crates/wasi/src/p2/wit/deps/random/world.wit similarity index 100% rename from crates/wasi/wit/deps/random/world.wit rename to crates/wasi/src/p2/wit/deps/random/world.wit diff --git a/crates/wasi/wit/deps/sockets/instance-network.wit b/crates/wasi/src/p2/wit/deps/sockets/instance-network.wit similarity index 100% rename from crates/wasi/wit/deps/sockets/instance-network.wit rename to crates/wasi/src/p2/wit/deps/sockets/instance-network.wit diff --git a/crates/wasi/wit/deps/sockets/ip-name-lookup.wit b/crates/wasi/src/p2/wit/deps/sockets/ip-name-lookup.wit similarity index 100% rename from crates/wasi/wit/deps/sockets/ip-name-lookup.wit rename to crates/wasi/src/p2/wit/deps/sockets/ip-name-lookup.wit diff --git a/crates/wasi/wit/deps/sockets/network.wit b/crates/wasi/src/p2/wit/deps/sockets/network.wit similarity index 100% rename from crates/wasi/wit/deps/sockets/network.wit rename to crates/wasi/src/p2/wit/deps/sockets/network.wit diff --git a/crates/wasi/wit/deps/sockets/tcp-create-socket.wit b/crates/wasi/src/p2/wit/deps/sockets/tcp-create-socket.wit similarity index 100% rename from crates/wasi/wit/deps/sockets/tcp-create-socket.wit rename to crates/wasi/src/p2/wit/deps/sockets/tcp-create-socket.wit diff --git a/crates/wasi/wit/deps/sockets/tcp.wit b/crates/wasi/src/p2/wit/deps/sockets/tcp.wit similarity index 100% rename from crates/wasi/wit/deps/sockets/tcp.wit rename to crates/wasi/src/p2/wit/deps/sockets/tcp.wit diff --git a/crates/wasi/wit/deps/sockets/udp-create-socket.wit b/crates/wasi/src/p2/wit/deps/sockets/udp-create-socket.wit similarity index 100% rename from crates/wasi/wit/deps/sockets/udp-create-socket.wit rename to crates/wasi/src/p2/wit/deps/sockets/udp-create-socket.wit diff --git a/crates/wasi/wit/deps/sockets/udp.wit b/crates/wasi/src/p2/wit/deps/sockets/udp.wit similarity index 100% rename from crates/wasi/wit/deps/sockets/udp.wit rename to crates/wasi/src/p2/wit/deps/sockets/udp.wit diff --git a/crates/wasi/wit/deps/sockets/world.wit b/crates/wasi/src/p2/wit/deps/sockets/world.wit similarity index 100% rename from crates/wasi/wit/deps/sockets/world.wit rename to crates/wasi/src/p2/wit/deps/sockets/world.wit diff --git a/crates/wasi/wit/test.wit b/crates/wasi/src/p2/wit/test.wit similarity index 100% rename from crates/wasi/wit/test.wit rename to crates/wasi/src/p2/wit/test.wit diff --git a/crates/wasi/wit/world.wit b/crates/wasi/src/p2/wit/world.wit similarity index 100% rename from crates/wasi/wit/world.wit rename to crates/wasi/src/p2/wit/world.wit diff --git a/crates/wasi/src/udp.rs b/crates/wasi/src/udp.rs index 1e0b1a199cf4..a4f67310a2b2 100644 --- a/crates/wasi/src/udp.rs +++ b/crates/wasi/src/udp.rs @@ -1,4 +1,4 @@ -use crate::host::network::util; +use crate::p2::host::network::util; use crate::poll::Subscribe; use crate::runtime::with_ambient_tokio_runtime; use async_trait::async_trait; diff --git a/crates/wasi/src/view.rs b/crates/wasi/src/view.rs index 58375b1b60ab..9e1f08eb63c9 100644 --- a/crates/wasi/src/view.rs +++ b/crates/wasi/src/view.rs @@ -13,7 +13,7 @@ pub trait IoView: Send { pub trait WasiView: IoView { /// Yields mutable access to the configuration used for this context. /// - /// The returned type is created through [`WasiCtxBuilder`]. + /// The returned type is created through [`WasiCtxBuilder`](crate::WasiCtxBuilder). fn ctx(&mut self) -> &mut WasiCtx; } diff --git a/crates/wasi/tests/all/api.rs b/crates/wasi/tests/all/api.rs index ca5219988744..2b5ea0c3f72d 100644 --- a/crates/wasi/tests/all/api.rs +++ b/crates/wasi/tests/all/api.rs @@ -132,6 +132,7 @@ fn api_proxy_forward_request() {} wasmtime::component::bindgen!({ world: "test-reactor", + path: "src/p2/wit", async: true, with: { "wasi": wasmtime_wasi::bindings }, ownership: Borrowing {