Skip to content

Commit

Permalink
Start to port Wasmtime to the new wasi-io API with resources.
Browse files Browse the repository at this point in the history
This imports the new APIs posted in WebAssembly/wasi-io#46.
  • Loading branch information
sunfishcode committed Sep 12, 2023
1 parent ce4950e commit b88f250
Show file tree
Hide file tree
Showing 19 changed files with 299 additions and 318 deletions.
8 changes: 4 additions & 4 deletions crates/wasi/src/preview2/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ wasmtime::component::bindgen!({
"wasi:filesystem/preopens": crate::preview2::bindings::filesystem::preopens,
"wasi:sockets/tcp": crate::preview2::bindings::sockets::tcp,
"wasi:clocks/monotonic_clock": crate::preview2::bindings::clocks::monotonic_clock,
"wasi:poll/poll": crate::preview2::bindings::poll::poll,
"wasi:io/poll": crate::preview2::bindings::io::poll,
"wasi:io/streams": crate::preview2::bindings::io::streams,
"wasi:clocks/timezone": crate::preview2::bindings::clocks::timezone,
"wasi:clocks/wall_clock": crate::preview2::bindings::clocks::wall_clock,
Expand All @@ -37,7 +37,7 @@ pub fn add_to_linker<T: WasiView>(l: &mut wasmtime::component::Linker<T>) -> any
crate::preview2::bindings::clocks::timezone::add_to_linker(l, |t| t)?;
crate::preview2::bindings::filesystem::types::add_to_linker(l, |t| t)?;
crate::preview2::bindings::filesystem::preopens::add_to_linker(l, |t| t)?;
crate::preview2::bindings::poll::poll::add_to_linker(l, |t| t)?;
crate::preview2::bindings::io::poll::add_to_linker(l, |t| t)?;
crate::preview2::bindings::io::streams::add_to_linker(l, |t| t)?;
crate::preview2::bindings::random::random::add_to_linker(l, |t| t)?;
crate::preview2::bindings::cli::exit::add_to_linker(l, |t| t)?;
Expand Down Expand Up @@ -73,7 +73,7 @@ pub mod sync {
"wasi:filesystem/preopens": crate::preview2::bindings::filesystem::preopens,
"wasi:sockets/tcp": crate::preview2::bindings::sockets::tcp,
"wasi:clocks/monotonic_clock": crate::preview2::bindings::clocks::monotonic_clock,
"wasi:poll/poll": crate::preview2::bindings::sync_io::poll::poll,
"wasi:io/poll": crate::preview2::bindings::sync_io::io::poll,
"wasi:io/streams": crate::preview2::bindings::sync_io::io::streams,
"wasi:clocks/timezone": crate::preview2::bindings::clocks::timezone,
"wasi:clocks/wall_clock": crate::preview2::bindings::clocks::wall_clock,
Expand All @@ -99,7 +99,7 @@ pub mod sync {
crate::preview2::bindings::clocks::timezone::add_to_linker(l, |t| t)?;
crate::preview2::bindings::sync_io::filesystem::types::add_to_linker(l, |t| t)?;
crate::preview2::bindings::filesystem::preopens::add_to_linker(l, |t| t)?;
crate::preview2::bindings::sync_io::poll::poll::add_to_linker(l, |t| t)?;
crate::preview2::bindings::sync_io::io::poll::add_to_linker(l, |t| t)?;
crate::preview2::bindings::sync_io::io::streams::add_to_linker(l, |t| t)?;
crate::preview2::bindings::random::random::add_to_linker(l, |t| t)?;
crate::preview2::bindings::cli::exit::add_to_linker(l, |t| t)?;
Expand Down
2 changes: 1 addition & 1 deletion crates/wasi/src/preview2/host/clocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::preview2::bindings::{
clocks::monotonic_clock::{self, Instant},
clocks::timezone::{self, Timezone, TimezoneDisplay},
clocks::wall_clock::{self, Datetime},
poll::poll::Pollable,
io::poll::Pollable,
};
use crate::preview2::{HostPollable, TablePollableExt, WasiView};
use cap_std::time::SystemTime;
Expand Down
4 changes: 2 additions & 2 deletions crates/wasi/src/preview2/host/io.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::preview2::{
bindings::io::streams::{self, InputStream, OutputStream},
bindings::poll::poll::Pollable,
bindings::io::poll::Pollable,
filesystem::FileInputStream,
poll::PollableFuture,
stream::{
Expand Down Expand Up @@ -404,7 +404,7 @@ pub mod sync {
use crate::preview2::{
bindings::io::streams::{self as async_streams, Host as AsyncHost},
bindings::sync_io::io::streams::{self, InputStream, OutputStream},
bindings::sync_io::poll::poll::Pollable,
bindings::sync_io::io::poll::Pollable,
in_tokio, WasiView,
};

Expand Down
2 changes: 1 addition & 1 deletion crates/wasi/src/preview2/host/tcp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::preview2::bindings::{
io::streams::{InputStream, OutputStream},
poll::poll::Pollable,
io::poll::Pollable,
sockets::network::{self, ErrorCode, IpAddressFamily, IpSocketAddress, Network},
sockets::tcp::{self, ShutdownType},
};
Expand Down
10 changes: 5 additions & 5 deletions crates/wasi/src/preview2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub mod bindings {
wasmtime::component::bindgen!({
path: "wit",
interfaces: "
import wasi:poll/poll
import wasi:io/poll
import wasi:io/streams
import wasi:filesystem/types
",
Expand All @@ -67,7 +67,7 @@ pub mod bindings {
}
});
}
pub use self::_internal::wasi::{filesystem, io, poll};
pub use self::_internal::wasi::{filesystem, io};
}

pub(crate) mod _internal_clocks {
Expand All @@ -87,7 +87,7 @@ pub mod bindings {
wasmtime::component::bindgen!({
path: "wit",
interfaces: "
import wasi:poll/poll
import wasi:io/poll
import wasi:io/streams
import wasi:filesystem/types
",
Expand All @@ -102,7 +102,7 @@ pub mod bindings {
}
});
}
pub use self::_internal_io::wasi::{io, poll};
pub use self::_internal_io::wasi::io;

pub(crate) mod _internal_rest {
wasmtime::component::bindgen!({
Expand Down Expand Up @@ -134,7 +134,7 @@ pub mod bindings {
},
with: {
"wasi:clocks/wall-clock": crate::preview2::bindings::clocks::wall_clock,
"wasi:poll/poll": crate::preview2::bindings::poll::poll,
"wasi:io/poll": crate::preview2::bindings::io::poll,
"wasi:io/streams": crate::preview2::bindings::io::streams,
"wasi:filesystem/types": crate::preview2::bindings::filesystem::types,
}
Expand Down
18 changes: 9 additions & 9 deletions crates/wasi/src/preview2/poll.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::preview2::{
bindings::poll::poll::{self, Pollable},
bindings::io::poll::{self, Pollable},
Table, TableError, WasiView,
};
use anyhow::Result;
Expand All @@ -13,12 +13,12 @@ pub type PollableFuture<'a> = Pin<Box<dyn Future<Output = Result<()>> + Send + '
pub type MakeFuture = for<'a> fn(&'a mut dyn Any) -> PollableFuture<'a>;
pub type ClosureFuture = Box<dyn Fn() -> PollableFuture<'static> + Send + Sync + 'static>;

/// A host representation of the `wasi:poll/poll.pollable` resource.
/// A host representation of the `wasi:io/poll.pollable` resource.
///
/// A pollable is not the same thing as a Rust Future: the same pollable may be used to
/// repeatedly check for readiness of a given condition, e.g. if a stream is readable
/// or writable. So, rather than containing a Future, which can only become Ready once, a
/// HostPollable contains a way to create a Future in each call to poll_oneoff.
/// HostPollable contains a way to create a Future in each call to `poll_list`.
pub enum HostPollable {
/// Create a Future by calling a fn on another resource in the table. This
/// indirection means the created Future can use a mut borrow of another
Expand Down Expand Up @@ -58,7 +58,7 @@ impl<T: WasiView> poll::Host for T {
Ok(())
}

async fn poll_oneoff(&mut self, pollables: Vec<Pollable>) -> Result<Vec<bool>> {
async fn poll_list(&mut self, pollables: Vec<Pollable>) -> Result<Vec<bool>> {
type ReadylistIndex = usize;

let table = self.table_mut();
Expand Down Expand Up @@ -107,7 +107,7 @@ impl<T: WasiView> poll::Host for T {
}
Poll::Ready(Err(e)) => {
return Poll::Ready(Err(
e.context(format!("poll_oneoff {readylist_indicies:?}"))
e.context(format!("poll_list {readylist_indicies:?}"))
));
}
Poll::Pending => {}
Expand All @@ -130,8 +130,8 @@ impl<T: WasiView> poll::Host for T {

pub mod sync {
use crate::preview2::{
bindings::poll::poll::Host as AsyncHost,
bindings::sync_io::poll::poll::{self, Pollable},
bindings::io::poll::Host as AsyncHost,
bindings::sync_io::io::poll::{self, Pollable},
in_tokio, WasiView,
};
use anyhow::Result;
Expand All @@ -141,8 +141,8 @@ pub mod sync {
in_tokio(async { AsyncHost::drop_pollable(self, pollable).await })
}

fn poll_oneoff(&mut self, pollables: Vec<Pollable>) -> Result<Vec<bool>> {
in_tokio(async { AsyncHost::poll_oneoff(self, pollables).await })
fn poll_list(&mut self, pollables: Vec<Pollable>) -> Result<Vec<bool>> {
in_tokio(async { AsyncHost::poll_list(self, pollables).await })
}
}
}
10 changes: 5 additions & 5 deletions crates/wasi/src/preview2/preview1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::preview2::bindings::cli::{
use crate::preview2::bindings::clocks::{monotonic_clock, wall_clock};
use crate::preview2::bindings::filesystem::{preopens, types as filesystem};
use crate::preview2::bindings::io::streams;
use crate::preview2::bindings::poll;
use crate::preview2::bindings::io::poll;
use crate::preview2::filesystem::TableFsExt;
use crate::preview2::host::filesystem::TableReaddirExt;
use crate::preview2::{bindings, IsATTY, TableError, WasiView};
Expand Down Expand Up @@ -69,7 +69,7 @@ impl BlockingMode {
}
async fn write(
&self,
host: &mut (impl streams::Host + poll::poll::Host),
host: &mut (impl streams::Host + poll::Host),
output_stream: streams::OutputStream,
mut bytes: &[u8],
) -> Result<usize, types::Error> {
Expand Down Expand Up @@ -498,7 +498,7 @@ wiggle::from_witx!({
wasi_snapshot_preview1::{
fd_advise, fd_close, fd_datasync, fd_fdstat_get, fd_filestat_get, fd_filestat_set_size,
fd_filestat_set_times, fd_read, fd_pread, fd_seek, fd_sync, fd_readdir, fd_write,
fd_pwrite, poll_oneoff, path_create_directory, path_filestat_get,
fd_pwrite, poll_list, path_create_directory, path_filestat_get,
path_filestat_set_times, path_link, path_open, path_readlink, path_remove_directory,
path_rename, path_symlink, path_unlink_file
}
Expand All @@ -517,7 +517,7 @@ mod sync {
wasi_snapshot_preview1::{
fd_advise, fd_close, fd_datasync, fd_fdstat_get, fd_filestat_get, fd_filestat_set_size,
fd_filestat_set_times, fd_read, fd_pread, fd_seek, fd_sync, fd_readdir, fd_write,
fd_pwrite, poll_oneoff, path_create_directory, path_filestat_get,
fd_pwrite, poll_list, path_create_directory, path_filestat_get,
path_filestat_set_times, path_link, path_open, path_readlink, path_remove_directory,
path_rename, path_symlink, path_unlink_file
}
Expand Down Expand Up @@ -849,7 +849,7 @@ impl<
+ bindings::cli::exit::Host
+ bindings::filesystem::preopens::Host
+ bindings::filesystem::types::Host
+ bindings::poll::poll::Host
+ bindings::io::poll::Host
+ bindings::random::random::Host
+ bindings::io::streams::Host
+ bindings::clocks::monotonic_clock::Host
Expand Down
2 changes: 1 addition & 1 deletion crates/wasi/wit/command-extended.wit
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ world command-extended {
import wasi:random/random
import wasi:random/insecure
import wasi:random/insecure-seed
import wasi:poll/poll
import wasi:io/poll
import wasi:io/streams
import wasi:cli/environment
import wasi:cli/exit
Expand Down
2 changes: 1 addition & 1 deletion crates/wasi/wit/deps/cli/command.wit
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ world command {
import wasi:random/random
import wasi:random/insecure
import wasi:random/insecure-seed
import wasi:poll/poll
import wasi:io/poll
import wasi:io/streams

import environment
Expand Down
2 changes: 1 addition & 1 deletion crates/wasi/wit/deps/clocks/monotonic-clock.wit
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ package wasi:clocks
///
/// It is intended for measuring elapsed time.
interface monotonic-clock {
use wasi:poll/poll.{pollable}
use wasi:io/poll.{pollable}

/// A timestamp in nanoseconds.
type instant = u64
Expand Down
6 changes: 3 additions & 3 deletions crates/wasi/wit/deps/http/types.wit
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// imported and exported interfaces.
interface types {
use wasi:io/streams.{input-stream, output-stream}
use wasi:poll/poll.{pollable}
use wasi:io/poll.{pollable}

// This type corresponds to HTTP standard Methods.
variant method {
Expand Down Expand Up @@ -95,7 +95,7 @@ interface types {
// Additional optional parameters that can be set when making a request.
record request-options {
// The following timeouts are specific to the HTTP protocol and work
// independently of the overall timeouts passed to `io.poll.poll-oneoff`.
// independently of the overall timeouts passed to `io.poll.poll-list`.

// The timeout for the initial connect.
connect-timeout-ms: option<u32>,
Expand Down Expand Up @@ -147,7 +147,7 @@ interface types {
// `future-incoming-response`, the client can call the non-blocking `get`
// method to get the result if it is available. If the result is not available,
// the client can call `listen` to get a `pollable` that can be passed to
// `io.poll.poll-oneoff`.
// `wasi:io/poll.poll-list`.
type future-incoming-response = u32
drop-future-incoming-response: func(f: future-incoming-response)
future-incoming-response-get: func(f: future-incoming-response) -> option<result<incoming-response, error>>
Expand Down
34 changes: 34 additions & 0 deletions crates/wasi/wit/deps/io/poll.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package wasi:io

/// A poll API intended to let users wait for I/O events on multiple handles
/// at once.
interface poll {
/// A "pollable" handle.
resource pollable

/// Poll for completion on a set of pollables.
///
/// This function takes a list of pollables, which identify I/O sources of
/// interest, and waits until one or more of the events is ready for I/O.
///
/// The result `list<u32>` contains one or more indices of handles in the
/// argument list that is ready for I/O.
///
/// If the list contains more elements than can be indexed with a `u32`
/// value, this function traps.
///
/// A timeout can be implemented by adding a pollable from the
/// wasi-clocks API to the list.
///
/// This function does not return a `result`; polling in itself does not
/// do any I/O so it doesn't fail. If any of the I/O sources identified by
/// the pollables has an error, it is indicated by marking the source as
/// being reaedy for I/O.
poll-list: func(in: list<pollable>) -> list<u32>

/// Poll for completion on a single pollable.
///
/// This function is similar to `poll-list`, but operates on only a single
/// pollable. When it returns, the handle is ready for I/O.
poll-one: func(in: pollable)
}
Loading

0 comments on commit b88f250

Please sign in to comment.