Skip to content

Commit ca95576

Browse files
authored
Split off wasmtime-wasi-io crate from wasmtime-wasi (#10036)
* stub: wasmtime-wasi-io crate * wasmtime: component::ResourceTableError now impls core::error::Error for compatibility without std * relocate much of the wasi-io impl into wasmtime-wasi-io * stump of poll that uses in_tokio * finish moving instances over to wasmtime_wasi_io * redirect wasmtime_wasi's bindgen properly over to wasmtime_wasi_io * wasmtime-wasi-http: point directly at wasmtime_wasi_io in sources it worked without these changes because all the re-exports are in the right places, but this is nice to do * comment work * fix streams rename, migrate bindings to its own file * move wasi-io impls into their own mod with appropriate name. check in CI. * change ResourceTable::iter_entries from taking a HashMap to BTreeMap so it works without std * crate-level docs for wasmtime-wasi-io * more docs * more docs, wasi-io gives an add_to_linker function for async only * wasi-io: inline view into lib.rs. improve docs. * more streams vs stream fixes... * wasi-http stream->streams fixes * fix adding wasmtime-wasi-io to public crates * wasmtime-cli: drop overzealous `=` version constraint on wasmtime-wasi-http wasmtime-wasi-http is part of the public API where we guarantee semver is obeyed * fix doctest * mechanically rename the wasi-io pub traits, and resource types resource type Pollable -> DynPollable resource type InputStream -> DynInputStream resource type OutputStream -> DynOutputStream trait Subscribe -> Pollable trait HostInputStream -> InputStream trait HostOutputStream -> OutputStream type alias PollableFuture -> DynFuture (little-used) * delete unused ClosureFuture alias * doc fixes * wasmtime-wasi-http: use all of wasmtime-wasi-io through wasmtime-wasi re-exports * fix nostd build * missing separator. i love yml * make wasmtime-wasi-io #![no_std]
1 parent 0afaa2f commit ca95576

46 files changed

Lines changed: 1505 additions & 817 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/main.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,8 @@ jobs:
541541
cargo check -p wasmtime --no-default-features --features runtime,component-model &&
542542
cargo check -p wasmtime --no-default-features --features runtime,gc,component-model &&
543543
cargo check -p cranelift-control --no-default-features &&
544-
cargo check -p pulley-interpreter --features encode,decode,disas,interp
544+
cargo check -p pulley-interpreter --features encode,decode,disas,interp &&
545+
cargo check -p wasmtime-wasi-io --no-default-features
545546
# Use `cross` for illumos to have a C compiler/linker available.
546547
- target: x86_64-unknown-illumos
547548
os: ubuntu-latest

Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,8 @@ wasmtime-fiber = { path = "crates/fiber", version = "=30.0.0" }
230230
wasmtime-jit-debug = { path = "crates/jit-debug", version = "=30.0.0" }
231231
wasmtime-wast = { path = "crates/wast", version = "=30.0.0" }
232232
wasmtime-wasi = { path = "crates/wasi", version = "30.0.0", default-features = false }
233-
wasmtime-wasi-http = { path = "crates/wasi-http", version = "=30.0.0", default-features = false }
233+
wasmtime-wasi-io = { path = "crates/wasi-io", version = "30.0.0", default-features = false }
234+
wasmtime-wasi-http = { path = "crates/wasi-http", version = "30.0.0", default-features = false }
234235
wasmtime-wasi-nn = { path = "crates/wasi-nn", version = "30.0.0" }
235236
wasmtime-wasi-config = { path = "crates/wasi-config", version = "30.0.0" }
236237
wasmtime-wasi-keyvalue = { path = "crates/wasi-keyvalue", version = "30.0.0" }
@@ -355,7 +356,7 @@ hyper = "1.0.1"
355356
http = "1.0.0"
356357
http-body = "1.0.0"
357358
http-body-util = "0.1.0"
358-
bytes = "1.4"
359+
bytes = { version = "1.4", default-features = false }
359360
futures = { version = "0.3.27", default-features = false }
360361
indexmap = { version = "2.0.0", default-features = false }
361362
pretty_env_logger = "0.5.0"

ci/vendor-wit.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ make_vendor() {
3636

3737
cache_dir=$(mktemp -d)
3838

39+
make_vendor "wasi-io" "
40+
io@v0.2.3
41+
"
42+
3943
make_vendor "wasi" "
4044
cli@v0.2.3
4145
clocks@v0.2.3

crates/wasi-http/src/bindings.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,11 @@ pub mod sync {
5959
tracing: true,
6060
async: false,
6161
with: {
62-
"wasi:http": crate::bindings::http, // http is in this crate
63-
"wasi:io": wasmtime_wasi::bindings::sync::io, // io is sync
64-
"wasi": wasmtime_wasi::bindings, // everything else
62+
// http is in this crate
63+
"wasi:http": crate::bindings::http,
64+
// sync requires the wrapper in the wasmtime_wasi crate, in
65+
// order to have in_tokio
66+
"wasi:io": wasmtime_wasi::bindings::sync::io,
6567
},
6668
require_store_data_send: true,
6769
});

crates/wasi-http/src/body.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::{pin::Pin, sync::Arc, time::Duration};
1313
use tokio::sync::{mpsc, oneshot};
1414
use wasmtime_wasi::{
1515
runtime::{poll_noop, AbortOnDropJoinHandle},
16-
HostInputStream, HostOutputStream, StreamError, Subscribe,
16+
InputStream, OutputStream, Pollable, StreamError,
1717
};
1818

1919
/// Common type for incoming bodies.
@@ -234,7 +234,7 @@ enum IncomingBodyStreamState {
234234
}
235235

236236
#[async_trait::async_trait]
237-
impl HostInputStream for HostIncomingBodyStream {
237+
impl InputStream for HostIncomingBodyStream {
238238
fn read(&mut self, size: usize) -> Result<Bytes, StreamError> {
239239
loop {
240240
// Handle buffered data/errors if any
@@ -271,7 +271,7 @@ impl HostInputStream for HostIncomingBodyStream {
271271
}
272272

273273
#[async_trait::async_trait]
274-
impl Subscribe for HostIncomingBodyStream {
274+
impl Pollable for HostIncomingBodyStream {
275275
async fn ready(&mut self) {
276276
if !self.buffer.is_empty() || self.error.is_some() {
277277
return;
@@ -327,7 +327,7 @@ pub enum HostFutureTrailers {
327327
}
328328

329329
#[async_trait::async_trait]
330-
impl Subscribe for HostFutureTrailers {
330+
impl Pollable for HostFutureTrailers {
331331
async fn ready(&mut self) {
332332
let body = match self {
333333
HostFutureTrailers::Waiting(body) => body,
@@ -415,7 +415,7 @@ impl WrittenState {
415415
/// The concrete type behind a `wasi:http/types/outgoing-body` resource.
416416
pub struct HostOutgoingBody {
417417
/// The output stream that the body is written to.
418-
body_output_stream: Option<Box<dyn HostOutputStream>>,
418+
body_output_stream: Option<Box<dyn OutputStream>>,
419419
context: StreamContext,
420420
written: Option<WrittenState>,
421421
finish_sender: Option<tokio::sync::oneshot::Sender<FinishMessage>>,
@@ -499,7 +499,7 @@ impl HostOutgoingBody {
499499
}
500500

501501
/// Take the output stream, if it's available.
502-
pub fn take_output_stream(&mut self) -> Option<Box<dyn HostOutputStream>> {
502+
pub fn take_output_stream(&mut self) -> Option<Box<dyn OutputStream>> {
503503
self.body_output_stream.take()
504504
}
505505

@@ -605,7 +605,7 @@ impl BodyWriteStream {
605605
}
606606

607607
#[async_trait::async_trait]
608-
impl HostOutputStream for BodyWriteStream {
608+
impl OutputStream for BodyWriteStream {
609609
fn write(&mut self, bytes: Bytes) -> Result<(), StreamError> {
610610
let len = bytes.len();
611611
match self.writer.try_send(bytes) {
@@ -665,7 +665,7 @@ impl HostOutputStream for BodyWriteStream {
665665
}
666666

667667
#[async_trait::async_trait]
668-
impl Subscribe for BodyWriteStream {
668+
impl Pollable for BodyWriteStream {
669669
async fn ready(&mut self) {
670670
// Attempt to perform a reservation for a send. If there's capacity in
671671
// the channel or it's already closed then this will return immediately.

crates/wasi-http/src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::bindings::http::types::ErrorCode;
22
use std::error::Error;
33
use std::fmt;
4-
use wasmtime_wasi::ResourceTableError;
4+
use wasmtime::component::ResourceTableError;
55

66
/// A [`Result`] type where the error type defaults to [`HttpError`].
77
pub type HttpResult<T, E = HttpError> = Result<T, E>;

crates/wasi-http/src/lib.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -285,12 +285,13 @@ where
285285
T: WasiHttpView + wasmtime_wasi::WasiView,
286286
{
287287
let io_closure = type_annotate_io::<T, _>(|t| wasmtime_wasi::IoImpl(t));
288-
let closure = type_annotate_wasi::<T, _>(|t| wasmtime_wasi::WasiImpl(wasmtime_wasi::IoImpl(t)));
289-
wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?;
290-
wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?;
291288
wasmtime_wasi::bindings::io::poll::add_to_linker_get_host(l, io_closure)?;
292289
wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, io_closure)?;
293290
wasmtime_wasi::bindings::io::streams::add_to_linker_get_host(l, io_closure)?;
291+
292+
let closure = type_annotate_wasi::<T, _>(|t| wasmtime_wasi::WasiImpl(wasmtime_wasi::IoImpl(t)));
293+
wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?;
294+
wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?;
294295
wasmtime_wasi::bindings::cli::stdin::add_to_linker_get_host(l, closure)?;
295296
wasmtime_wasi::bindings::cli::stdout::add_to_linker_get_host(l, closure)?;
296297
wasmtime_wasi::bindings::cli::stderr::add_to_linker_get_host(l, closure)?;
@@ -383,13 +384,17 @@ where
383384
T: WasiHttpView + wasmtime_wasi::WasiView,
384385
{
385386
let io_closure = type_annotate_io::<T, _>(|t| wasmtime_wasi::IoImpl(t));
387+
// For the sync linker, use the definitions of poll and streams from the
388+
// wasmtime_wasi::bindings::sync space because those are defined using in_tokio.
389+
wasmtime_wasi::bindings::sync::io::poll::add_to_linker_get_host(l, io_closure)?;
390+
wasmtime_wasi::bindings::sync::io::streams::add_to_linker_get_host(l, io_closure)?;
391+
// The error interface in the wasmtime_wasi is synchronous
392+
wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, io_closure)?;
393+
386394
let closure = type_annotate_wasi::<T, _>(|t| wasmtime_wasi::WasiImpl(wasmtime_wasi::IoImpl(t)));
387395

388396
wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?;
389397
wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?;
390-
wasmtime_wasi::bindings::sync::io::poll::add_to_linker_get_host(l, io_closure)?;
391-
wasmtime_wasi::bindings::sync::io::streams::add_to_linker_get_host(l, io_closure)?;
392-
wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, io_closure)?;
393398
wasmtime_wasi::bindings::cli::stdin::add_to_linker_get_host(l, closure)?;
394399
wasmtime_wasi::bindings::cli::stdout::add_to_linker_get_host(l, closure)?;
395400
wasmtime_wasi::bindings::cli::stderr::add_to_linker_get_host(l, closure)?;

crates/wasi-http/src/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::time::Duration;
1818
use tokio::net::TcpStream;
1919
use tokio::time::timeout;
2020
use wasmtime::component::{Resource, ResourceTable};
21-
use wasmtime_wasi::{runtime::AbortOnDropJoinHandle, IoImpl, IoView, Subscribe};
21+
use wasmtime_wasi::{runtime::AbortOnDropJoinHandle, IoImpl, IoView, Pollable};
2222

2323
/// Capture the state necessary for use in the wasi-http API implementation.
2424
#[derive(Debug)]
@@ -715,7 +715,7 @@ impl HostFutureIncomingResponse {
715715
}
716716

717717
#[async_trait::async_trait]
718-
impl Subscribe for HostFutureIncomingResponse {
718+
impl Pollable for HostFutureIncomingResponse {
719719
async fn ready(&mut self) {
720720
if let Self::Pending(handle) = self {
721721
*self = Self::Ready(handle.await);

crates/wasi-http/src/types_impl.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,8 @@ use crate::{
1313
use anyhow::Context;
1414
use std::any::Any;
1515
use std::str::FromStr;
16-
use wasmtime::component::{Resource, ResourceTable};
17-
use wasmtime_wasi::{
18-
bindings::io::streams::{InputStream, OutputStream},
19-
IoView, Pollable, ResourceTableError,
20-
};
16+
use wasmtime::component::{Resource, ResourceTable, ResourceTableError};
17+
use wasmtime_wasi::{DynInputStream, DynOutputStream, DynPollable, IoView};
2118

2219
impl<T> crate::bindings::http::types::Host for WasiHttpImpl<T>
2320
where
@@ -662,7 +659,7 @@ where
662659
fn subscribe(
663660
&mut self,
664661
index: Resource<HostFutureTrailers>,
665-
) -> wasmtime::Result<Resource<Pollable>> {
662+
) -> wasmtime::Result<Resource<DynPollable>> {
666663
wasmtime_wasi::subscribe(self.table(), index)
667664
}
668665

@@ -704,11 +701,11 @@ where
704701
fn stream(
705702
&mut self,
706703
id: Resource<HostIncomingBody>,
707-
) -> wasmtime::Result<Result<Resource<InputStream>, ()>> {
704+
) -> wasmtime::Result<Result<Resource<DynInputStream>, ()>> {
708705
let body = self.table().get_mut(&id)?;
709706

710707
if let Some(stream) = body.take_stream() {
711-
let stream: InputStream = Box::new(stream);
708+
let stream: DynInputStream = Box::new(stream);
712709
let stream = self.table().push_child(stream, &id)?;
713710
return Ok(Ok(stream));
714711
}
@@ -883,7 +880,7 @@ where
883880
fn subscribe(
884881
&mut self,
885882
id: Resource<HostFutureIncomingResponse>,
886-
) -> wasmtime::Result<Resource<Pollable>> {
883+
) -> wasmtime::Result<Resource<DynPollable>> {
887884
wasmtime_wasi::subscribe(self.table(), id)
888885
}
889886
}
@@ -895,7 +892,7 @@ where
895892
fn write(
896893
&mut self,
897894
id: Resource<HostOutgoingBody>,
898-
) -> wasmtime::Result<Result<Resource<OutputStream>, ()>> {
895+
) -> wasmtime::Result<Result<Resource<DynOutputStream>, ()>> {
899896
let body = self.table().get_mut(&id)?;
900897
if let Some(stream) = body.take_output_stream() {
901898
let id = self.table().push_child(stream, &id)?;

0 commit comments

Comments
 (0)