Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit f16744a

Browse files
committed
Refactor Accessor, replace GetHost
prtest:full
1 parent 85d0fb2 commit f16744a

57 files changed

Lines changed: 1702 additions & 1740 deletions

File tree

Some content is hidden

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

Cargo.lock

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

crates/misc/component-async-tests/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ edition.workspace = true
77
rust-version.workspace = true
88
publish = false
99

10+
[lints]
11+
workspace = true
12+
1013
[dependencies]
1114
anyhow = { workspace = true }
1215
flate2 = "1.0.30"

crates/misc/component-async-tests/http/src/lib.rs

Lines changed: 68 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ wasmtime::component::bindgen!({
2828
use {
2929
anyhow::anyhow,
3030
bytes::BytesMut,
31-
std::{fmt, future::Future, mem},
31+
std::{fmt, future::Future, marker, mem},
3232
wasi::http::types::{ErrorCode, HeaderError, Method, RequestOptionsError, Scheme},
3333
wasmtime::component::{
34-
Accessor, AccessorTask, ErrorContext, FutureReader, HostFuture, HostStream, Linker,
35-
Resource, ResourceTable, StreamReader,
34+
Accessor, AccessorTask, ErrorContext, FutureReader, HasData, HostFuture, HostStream,
35+
Linker, Resource, ResourceTable, StreamReader,
3636
},
3737
};
3838

@@ -50,60 +50,60 @@ impl fmt::Display for Scheme {
5050
}
5151
}
5252

53-
pub trait WasiHttpView: Send + Sized {
54-
fn table(&mut self) -> &mut ResourceTable;
53+
pub trait WasiHttpViewConcurrent: Send + 'static {
54+
type View<'a>: WasiHttpView;
5555

5656
fn send_request<T: 'static>(
57-
accessor: &mut Accessor<T, Self>,
57+
accessor: &mut Accessor<T, WasiHttp<Self>>,
5858
request: Resource<Request>,
5959
) -> impl Future<Output = wasmtime::Result<Result<Resource<Response>, ErrorCode>>> + Send + Sync;
6060
}
6161

62-
impl<T: WasiHttpView> WasiHttpView for &mut T {
62+
pub trait WasiHttpView: Send {
63+
fn table(&mut self) -> &mut ResourceTable;
64+
}
65+
66+
impl<T: WasiHttpView + ?Sized> WasiHttpView for &mut T {
6367
fn table(&mut self) -> &mut ResourceTable {
6468
(*self).table()
6569
}
66-
67-
fn send_request<U: 'static>(
68-
accessor: &mut Accessor<U, Self>,
69-
request: Resource<Request>,
70-
) -> impl Future<Output = wasmtime::Result<Result<Resource<Response>, ErrorCode>>> + Send + Sync
71-
{
72-
accessor.forward(|v| *v, SendRequestTask { request })
73-
}
7470
}
7571

76-
struct SendRequestTask {
72+
struct SendRequestTask<C> {
7773
request: Resource<Request>,
74+
_marker: marker::PhantomData<fn() -> C>,
7875
}
7976

80-
impl<T: 'static, U: WasiHttpView>
81-
AccessorTask<T, U, wasmtime::Result<Result<Resource<Response>, ErrorCode>>>
82-
for SendRequestTask
77+
impl<T: 'static, C>
78+
AccessorTask<T, WasiHttp<C>, wasmtime::Result<Result<Resource<Response>, ErrorCode>>>
79+
for SendRequestTask<C>
80+
where
81+
C: WasiHttpViewConcurrent,
8382
{
8483
async fn run(
8584
self,
86-
accessor: &mut wasmtime::component::Accessor<T, U>,
85+
accessor: &mut wasmtime::component::Accessor<T, WasiHttp<C>>,
8786
) -> wasmtime::Result<Result<Resource<Response>, ErrorCode>> {
88-
U::send_request(accessor, self.request).await
87+
C::send_request(accessor, self.request).await
8988
}
9089
}
9190

91+
pub struct WasiHttp<C: ?Sized>(marker::PhantomData<C>);
92+
93+
impl<C: ?Sized> HasData for WasiHttp<C>
94+
where
95+
C: WasiHttpViewConcurrent,
96+
{
97+
type Data<'a> = WasiHttpImpl<C::View<'a>>;
98+
}
99+
92100
#[repr(transparent)]
93101
pub struct WasiHttpImpl<T>(pub T);
94102

95103
impl<T: WasiHttpView> WasiHttpView for WasiHttpImpl<T> {
96104
fn table(&mut self) -> &mut ResourceTable {
97105
self.0.table()
98106
}
99-
100-
fn send_request<U: 'static>(
101-
accessor: &mut Accessor<U, Self>,
102-
request: Resource<Request>,
103-
) -> impl Future<Output = wasmtime::Result<Result<Resource<Response>, ErrorCode>>> + Send + Sync
104-
{
105-
accessor.forward(|v| &mut v.0, SendRequestTask { request })
106-
}
107107
}
108108

109109
pub struct Body {
@@ -216,22 +216,22 @@ impl<T: WasiHttpView> wasi::http::types::HostFields for WasiHttpImpl<T> {
216216
}
217217
}
218218

219-
impl<T: WasiHttpView> wasi::http::types::HostBody for WasiHttpImpl<T> {
220-
async fn new<U>(
221-
accessor: &mut Accessor<U, Self>,
219+
impl<C: WasiHttpViewConcurrent> wasi::http::types::HostBodyConcurrent for WasiHttp<C> {
220+
async fn new<T>(
221+
accessor: &mut Accessor<T, Self>,
222222
stream: HostStream<u8>,
223223
) -> wasmtime::Result<Resource<Body>> {
224224
accessor.with(|mut view| {
225225
let body = Body {
226226
stream: Some(stream.into_reader(&mut view)),
227227
trailers: None,
228228
};
229-
Ok(view.table().push(body)?)
229+
Ok(view.get().table().push(body)?)
230230
})
231231
}
232232

233-
async fn new_with_trailers<U>(
234-
accessor: &mut Accessor<U, Self>,
233+
async fn new_with_trailers<T>(
234+
accessor: &mut Accessor<T, Self>,
235235
stream: HostStream<u8>,
236236
trailers: HostFuture<Resource<Fields>>,
237237
) -> wasmtime::Result<Resource<Body>> {
@@ -240,27 +240,18 @@ impl<T: WasiHttpView> wasi::http::types::HostBody for WasiHttpImpl<T> {
240240
stream: Some(stream.into_reader(&mut view)),
241241
trailers: Some(trailers.into_reader(&mut view)),
242242
};
243-
Ok(view.table().push(body)?)
243+
Ok(view.get().table().push(body)?)
244244
})
245245
}
246246

247-
fn stream(&mut self, this: Resource<Body>) -> wasmtime::Result<Result<HostStream<u8>, ()>> {
248-
// TODO: This should return a child handle
249-
let stream = self.table().get_mut(&this)?.stream.take().ok_or_else(|| {
250-
anyhow!("todo: allow wasi:http/types#body.stream to be called multiple times")
251-
})?;
252-
253-
Ok(Ok(stream.into()))
254-
}
255-
256247
// TODO: once access to the store is possible in a non-async context (similar to Accessor pattern)
257248
// we should convert this to a sync function that works w/ &mut self.
258-
async fn finish<U>(
259-
accessor: &mut Accessor<U, Self>,
249+
async fn finish<T>(
250+
accessor: &mut Accessor<T, Self>,
260251
this: Resource<Body>,
261252
) -> wasmtime::Result<HostFuture<Resource<Fields>>> {
262253
let trailers = accessor.with(|mut store| {
263-
let trailers = store.table().delete(this)?.trailers;
254+
let trailers = store.get().table().delete(this)?.trailers;
264255
Ok::<FutureReader<_>, anyhow::Error>(match trailers {
265256
Some(t) => t,
266257
None => {
@@ -272,6 +263,17 @@ impl<T: WasiHttpView> wasi::http::types::HostBody for WasiHttpImpl<T> {
272263

273264
Ok(trailers.into())
274265
}
266+
}
267+
268+
impl<T: WasiHttpView> wasi::http::types::HostBody for WasiHttpImpl<T> {
269+
fn stream(&mut self, this: Resource<Body>) -> wasmtime::Result<Result<HostStream<u8>, ()>> {
270+
// TODO: This should return a child handle
271+
let stream = self.table().get_mut(&this)?.stream.take().ok_or_else(|| {
272+
anyhow!("todo: allow wasi:http/types#body.stream to be called multiple times")
273+
})?;
274+
275+
Ok(Ok(stream.into()))
276+
}
275277

276278
fn drop(&mut self, this: Resource<Body>) -> wasmtime::Result<()> {
277279
self.table().delete(this)?;
@@ -507,31 +509,36 @@ impl<T: WasiHttpView> wasi::http::types::HostRequestOptions for WasiHttpImpl<T>
507509
}
508510
}
509511

512+
impl<C: WasiHttpViewConcurrent> wasi::http::types::HostConcurrent for WasiHttp<C> {}
513+
510514
impl<T: WasiHttpView> wasi::http::types::Host for WasiHttpImpl<T> {
511515
fn http_error_code(&mut self, _error: ErrorContext) -> wasmtime::Result<Option<ErrorCode>> {
512516
Err(anyhow!("todo: implement wasi:http/types#http-error-code"))
513517
}
514518
}
515519

516-
impl<T: WasiHttpView> wasi::http::handler::Host for WasiHttpImpl<T> {
517-
async fn handle<U: 'static>(
518-
accessor: &mut Accessor<U, Self>,
520+
impl<C: WasiHttpViewConcurrent> wasi::http::handler::HostConcurrent for WasiHttp<C> {
521+
async fn handle<T: 'static>(
522+
accessor: &mut Accessor<T, Self>,
519523
request: Resource<Request>,
520524
) -> wasmtime::Result<Result<Resource<Response>, ErrorCode>> {
521-
accessor
522-
.forward(|v| &mut v.0, SendRequestTask { request })
523-
.await
525+
SendRequestTask {
526+
request,
527+
_marker: marker::PhantomData,
528+
}
529+
.run(accessor)
530+
.await
524531
}
525532
}
526533

527-
pub fn add_to_linker<T: WasiHttpView + 'static>(linker: &mut Linker<T>) -> wasmtime::Result<()> {
528-
wasi::http::types::add_to_linker_get_host(linker, annotate_http(|ctx| WasiHttpImpl(ctx)))?;
529-
wasi::http::handler::add_to_linker_get_host(linker, annotate_http(|ctx| WasiHttpImpl(ctx)))
530-
}
534+
impl<T: WasiHttpView> wasi::http::handler::Host for WasiHttpImpl<T> {}
531535

532-
pub fn annotate_http<T, F>(val: F) -> F
536+
pub fn add_to_linker<T>(linker: &mut Linker<T>) -> wasmtime::Result<()>
533537
where
534-
F: Fn(&mut T) -> WasiHttpImpl<&mut T>,
538+
T: for<'a> WasiHttpViewConcurrent<View<'a> = &'a mut T> + 'static,
539+
T: WasiHttpView,
535540
{
536-
val
541+
wasi::http::types::add_to_linker::<T, WasiHttp<T>>(linker, |x| WasiHttpImpl(x))?;
542+
wasi::http::handler::add_to_linker::<T, WasiHttp<T>>(linker, |x| WasiHttpImpl(x))?;
543+
Ok(())
537544
}

crates/misc/component-async-tests/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
#![expect(clippy::allow_attributes_without_reason)]
2+
13
use std::sync::{Arc, Mutex};
24
use std::task::Waker;
35

4-
use wasmtime::component::ResourceTable;
6+
use wasmtime::component::{HasData, ResourceTable};
57
use wasmtime_wasi::p2::{IoView, WasiCtx, WasiView};
68

79
pub mod borrowing_host;
@@ -35,3 +37,7 @@ impl WasiView for Ctx {
3537
&mut self.wasi
3638
}
3739
}
40+
41+
impl HasData for Ctx {
42+
type Data<'a> = &'a mut Self;
43+
}

crates/misc/component-async-tests/src/proxy.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use anyhow::{anyhow, Result};
22
use wasi_http_draft::wasi::http::types::{ErrorCode, Request, Response};
3-
use wasi_http_draft::WasiHttpView;
3+
use wasi_http_draft::{WasiHttp, WasiHttpView, WasiHttpViewConcurrent};
44
use wasmtime::component::{Accessor, Resource, ResourceTable};
55

66
pub mod bindings {
@@ -25,9 +25,13 @@ impl WasiHttpView for super::Ctx {
2525
fn table(&mut self) -> &mut ResourceTable {
2626
&mut self.table
2727
}
28+
}
29+
30+
impl WasiHttpViewConcurrent for super::Ctx {
31+
type View<'a> = &'a mut Self;
2832

2933
async fn send_request<T>(
30-
_accessor: &mut Accessor<T, Self>,
34+
_accessor: &mut Accessor<T, WasiHttp<Self>>,
3135
_request: Resource<Request>,
3236
) -> wasmtime::Result<Result<Resource<Response>, ErrorCode>> {
3337
Err(anyhow!("no outbound request handler available"))

crates/misc/component-async-tests/src/resource_stream.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,40 @@ pub mod bindings {
2020

2121
pub struct ResourceStreamX;
2222

23-
impl bindings::local::local::resource_stream::HostX for &mut Ctx {
23+
impl bindings::local::local::resource_stream::HostXConcurrent for Ctx {
2424
async fn foo<T>(accessor: &mut Accessor<T, Self>, x: Resource<ResourceStreamX>) -> Result<()> {
2525
accessor.with(|mut view| {
26-
_ = IoView::table(&mut *view).get(&x)?;
26+
_ = view.get().table().get(&x)?;
2727
Ok(())
2828
})
2929
}
30+
}
3031

32+
impl bindings::local::local::resource_stream::HostX for Ctx {
3133
async fn drop(&mut self, x: Resource<ResourceStreamX>) -> Result<()> {
3234
IoView::table(self).delete(x)?;
3335
Ok(())
3436
}
3537
}
3638

37-
impl bindings::local::local::resource_stream::Host for &mut Ctx {
39+
impl bindings::local::local::resource_stream::HostConcurrent for Ctx {
3840
async fn foo<T: 'static>(
3941
accessor: &mut Accessor<T, Self>,
4042
count: u32,
4143
) -> wasmtime::Result<HostStream<Resource<ResourceStreamX>>> {
4244
struct Task {
4345
tx: StreamWriter<Option<Resource<ResourceStreamX>>>,
46+
4447
count: u32,
4548
}
4649

47-
impl<T, U: wasmtime_wasi::p2::IoView> AccessorTask<T, U, Result<()>> for Task {
48-
async fn run(self, accessor: &mut Accessor<T, U>) -> Result<()> {
50+
impl<T> AccessorTask<T, Ctx, Result<()>> for Task {
51+
async fn run(self, accessor: &mut Accessor<T, Ctx>) -> Result<()> {
4952
let mut tx = Some(self.tx);
5053
for _ in 0..self.count {
5154
tx = accessor
5255
.with(|mut view| {
53-
let item = IoView::table(&mut *view).push(ResourceStreamX)?;
56+
let item = view.get().table().push(ResourceStreamX)?;
5457
Ok::<_, anyhow::Error>(tx.take().unwrap().write_all(Some(item)))
5558
})?
5659
.await
@@ -68,3 +71,5 @@ impl bindings::local::local::resource_stream::Host for &mut Ctx {
6871
Ok(rx.into())
6972
}
7073
}
74+
75+
impl bindings::local::local::resource_stream::Host for Ctx {}

crates/misc/component-async-tests/src/round_trip.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1+
use super::Ctx;
12
use std::time::Duration;
2-
33
use wasmtime::component::Accessor;
44

5-
use super::Ctx;
6-
75
pub mod bindings {
86
wasmtime::component::bindgen!({
97
trappable_imports: true,
@@ -25,9 +23,11 @@ pub mod non_concurrent_export_bindings {
2523
});
2624
}
2725

28-
impl bindings::local::local::baz::Host for &mut Ctx {
26+
impl bindings::local::local::baz::HostConcurrent for Ctx {
2927
async fn foo<T>(_: &mut Accessor<T, Self>, s: String) -> wasmtime::Result<String> {
3028
tokio::time::sleep(Duration::from_millis(10)).await;
3129
Ok(format!("{s} - entered host - exited host"))
3230
}
3331
}
32+
33+
impl bindings::local::local::baz::Host for Ctx {}
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
#![allow(clippy::disallowed_names)]
1+
use super::Ctx;
22
use std::time::Duration;
3-
43
use wasmtime::component::Accessor;
54

6-
use super::Ctx;
7-
85
pub mod bindings {
96
wasmtime::component::bindgen!({
107
trappable_imports: true,
@@ -16,9 +13,11 @@ pub mod bindings {
1613
});
1714
}
1815

19-
impl bindings::RoundTripDirectImports for &mut Ctx {
16+
impl bindings::RoundTripDirectImportsConcurrent for Ctx {
2017
async fn foo<T>(_: &mut Accessor<T, Self>, s: String) -> wasmtime::Result<String> {
2118
tokio::time::sleep(Duration::from_millis(10)).await;
2219
Ok(format!("{s} - entered host - exited host"))
2320
}
2421
}
22+
23+
impl bindings::RoundTripDirectImports for Ctx {}

0 commit comments

Comments
 (0)