Skip to content

Commit db87fbe

Browse files
authored
Mirror WASIp{2,3} clocks implementations (#11377)
This is an implementation of #11362 but for the `wasi:clocks` implementation of WASIp2. The goal here is to have the impls be implemented and look roughly the same across WASIp2 and WASIp3, namely the target of the implementation of now `WasiClocksCtxView` instead of `WasiCtxView`. This makes the trait implementations a bit more flexible as it means embedders aren't required to, for example, provide a full WASI context for clocks but just clock-related context.
1 parent 7315a82 commit db87fbe

File tree

7 files changed

+62
-57
lines changed

7 files changed

+62
-57
lines changed

crates/wasi/src/clocks.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
use cap_std::time::{Duration, Instant, SystemClock};
22
use cap_std::{AmbientAuthority, ambient_authority};
33
use cap_time_ext::{MonotonicClockExt as _, SystemClockExt as _};
4+
use wasmtime::component::{HasData, ResourceTable};
5+
6+
pub(crate) struct WasiClocks;
7+
8+
impl HasData for WasiClocks {
9+
type Data<'a> = WasiClocksCtxView<'a>;
10+
}
411

512
pub struct WasiClocksCtx {
613
pub wall_clock: Box<dyn HostWallClock + Send>,
@@ -17,13 +24,12 @@ impl Default for WasiClocksCtx {
1724
}
1825

1926
pub trait WasiClocksView: Send {
20-
fn clocks(&mut self) -> &mut WasiClocksCtx;
27+
fn clocks(&mut self) -> WasiClocksCtxView<'_>;
2128
}
2229

23-
impl WasiClocksView for WasiClocksCtx {
24-
fn clocks(&mut self) -> &mut WasiClocksCtx {
25-
self
26-
}
30+
pub struct WasiClocksCtxView<'a> {
31+
pub ctx: &'a mut WasiClocksCtx,
32+
pub table: &'a mut ResourceTable,
2733
}
2834

2935
pub trait HostWallClock: Send {

crates/wasi/src/p2/host/clocks.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
use crate::clocks::WasiClocksCtxView;
2+
use crate::p2::DynPollable;
13
use crate::p2::bindings::{
24
clocks::monotonic_clock::{self, Duration as WasiDuration, Instant},
35
clocks::wall_clock::{self, Datetime},
46
};
5-
use crate::p2::{DynPollable, WasiCtxView};
67
use cap_std::time::SystemTime;
78
use std::time::Duration;
89
use wasmtime::component::Resource;
@@ -22,17 +23,17 @@ impl TryFrom<SystemTime> for Datetime {
2223
}
2324
}
2425

25-
impl wall_clock::Host for WasiCtxView<'_> {
26+
impl wall_clock::Host for WasiClocksCtxView<'_> {
2627
fn now(&mut self) -> anyhow::Result<Datetime> {
27-
let now = self.ctx.clocks.wall_clock.now();
28+
let now = self.ctx.wall_clock.now();
2829
Ok(Datetime {
2930
seconds: now.as_secs(),
3031
nanoseconds: now.subsec_nanos(),
3132
})
3233
}
3334

3435
fn resolution(&mut self) -> anyhow::Result<Datetime> {
35-
let res = self.ctx.clocks.wall_clock.resolution();
36+
let res = self.ctx.wall_clock.resolution();
3637
Ok(Datetime {
3738
seconds: res.as_secs(),
3839
nanoseconds: res.subsec_nanos(),
@@ -59,17 +60,17 @@ fn subscribe_to_duration(
5960
subscribe(table, sleep)
6061
}
6162

62-
impl monotonic_clock::Host for WasiCtxView<'_> {
63+
impl monotonic_clock::Host for WasiClocksCtxView<'_> {
6364
fn now(&mut self) -> anyhow::Result<Instant> {
64-
Ok(self.ctx.clocks.monotonic_clock.now())
65+
Ok(self.ctx.monotonic_clock.now())
6566
}
6667

6768
fn resolution(&mut self) -> anyhow::Result<Instant> {
68-
Ok(self.ctx.clocks.monotonic_clock.resolution())
69+
Ok(self.ctx.monotonic_clock.resolution())
6970
}
7071

7172
fn subscribe_instant(&mut self, when: Instant) -> anyhow::Result<Resource<DynPollable>> {
72-
let clock_now = self.ctx.clocks.monotonic_clock.now();
73+
let clock_now = self.ctx.monotonic_clock.now();
7374
let duration = if when > clock_now {
7475
Duration::from_nanos(when - clock_now)
7576
} else {

crates/wasi/src/p2/mod.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@
222222
//! [`ResourceTable`]: wasmtime::component::ResourceTable
223223
224224
use crate::cli::{WasiCli, WasiCliView};
225+
use crate::clocks::{WasiClocks, WasiClocksView};
225226
use crate::random::WasiRandom;
226227
use crate::{WasiCtxView, WasiView};
227228
use wasmtime::component::{HasData, Linker, ResourceTable};
@@ -339,8 +340,8 @@ where
339340
use crate::p2::bindings::{cli, clocks, filesystem, random, sockets};
340341

341342
let l = linker;
342-
clocks::wall_clock::add_to_linker::<T, HasWasi>(l, T::ctx)?;
343-
clocks::monotonic_clock::add_to_linker::<T, HasWasi>(l, T::ctx)?;
343+
clocks::wall_clock::add_to_linker::<T, WasiClocks>(l, T::clocks)?;
344+
clocks::monotonic_clock::add_to_linker::<T, WasiClocks>(l, T::clocks)?;
344345
filesystem::preopens::add_to_linker::<T, HasWasi>(l, T::ctx)?;
345346
random::random::add_to_linker::<T, WasiRandom>(l, |t| &mut t.ctx().ctx.random)?;
346347
random::insecure::add_to_linker::<T, WasiRandom>(l, |t| &mut t.ctx().ctx.random)?;
@@ -386,8 +387,8 @@ fn add_proxy_interfaces_nonblocking<T: WasiView>(linker: &mut Linker<T>) -> anyh
386387
use crate::p2::bindings::{cli, clocks, random};
387388

388389
let l = linker;
389-
clocks::wall_clock::add_to_linker::<T, HasWasi>(l, T::ctx)?;
390-
clocks::monotonic_clock::add_to_linker::<T, HasWasi>(l, T::ctx)?;
390+
clocks::wall_clock::add_to_linker::<T, WasiClocks>(l, T::clocks)?;
391+
clocks::monotonic_clock::add_to_linker::<T, WasiClocks>(l, T::clocks)?;
391392
random::random::add_to_linker::<T, WasiRandom>(l, |t| &mut t.ctx().ctx.random)?;
392393
cli::stdin::add_to_linker::<T, WasiCli>(l, T::cli)?;
393394
cli::stdout::add_to_linker::<T, WasiCli>(l, T::cli)?;

crates/wasi/src/p3/clocks/host.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
use core::time::Duration;
2-
1+
use crate::clocks::WasiClocksCtxView;
2+
use crate::p3::bindings::clocks::{monotonic_clock, wall_clock};
3+
use crate::p3::clocks::WasiClocks;
34
use cap_std::time::SystemTime;
5+
use core::time::Duration;
46
use tokio::time::sleep;
57
use wasmtime::component::Accessor;
68

7-
use crate::clocks::WasiClocksCtx;
8-
use crate::p3::bindings::clocks::{monotonic_clock, wall_clock};
9-
use crate::p3::clocks::WasiClocks;
10-
119
impl TryFrom<SystemTime> for wall_clock::Datetime {
1210
type Error = wasmtime::Error;
1311

@@ -22,17 +20,17 @@ impl TryFrom<SystemTime> for wall_clock::Datetime {
2220
}
2321
}
2422

25-
impl wall_clock::Host for WasiClocksCtx {
23+
impl wall_clock::Host for WasiClocksCtxView<'_> {
2624
fn now(&mut self) -> wasmtime::Result<wall_clock::Datetime> {
27-
let now = self.wall_clock.now();
25+
let now = self.ctx.wall_clock.now();
2826
Ok(wall_clock::Datetime {
2927
seconds: now.as_secs(),
3028
nanoseconds: now.subsec_nanos(),
3129
})
3230
}
3331

3432
fn resolution(&mut self) -> wasmtime::Result<wall_clock::Datetime> {
35-
let res = self.wall_clock.resolution();
33+
let res = self.ctx.wall_clock.resolution();
3634
Ok(wall_clock::Datetime {
3735
seconds: res.as_secs(),
3836
nanoseconds: res.subsec_nanos(),
@@ -45,7 +43,7 @@ impl monotonic_clock::HostWithStore for WasiClocks {
4543
store: &Accessor<U, Self>,
4644
when: monotonic_clock::Instant,
4745
) -> wasmtime::Result<()> {
48-
let clock_now = store.with(|mut view| view.get().monotonic_clock.now());
46+
let clock_now = store.with(|mut view| view.get().ctx.monotonic_clock.now());
4947
if when > clock_now {
5048
sleep(Duration::from_nanos(when - clock_now)).await;
5149
};
@@ -63,12 +61,12 @@ impl monotonic_clock::HostWithStore for WasiClocks {
6361
}
6462
}
6563

66-
impl monotonic_clock::Host for WasiClocksCtx {
64+
impl monotonic_clock::Host for WasiClocksCtxView<'_> {
6765
fn now(&mut self) -> wasmtime::Result<monotonic_clock::Instant> {
68-
Ok(self.monotonic_clock.now())
66+
Ok(self.ctx.monotonic_clock.now())
6967
}
7068

7169
fn resolution(&mut self) -> wasmtime::Result<monotonic_clock::Instant> {
72-
Ok(self.monotonic_clock.resolution())
70+
Ok(self.ctx.monotonic_clock.resolution())
7371
}
7472
}

crates/wasi/src/p3/clocks/mod.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
mod host;
22

3-
use crate::clocks::{WasiClocksCtx, WasiClocksView};
3+
use crate::clocks::{WasiClocks, WasiClocksView};
44
use crate::p3::bindings::clocks;
5-
use wasmtime::component::{HasData, Linker};
5+
use wasmtime::component::Linker;
66

77
/// Add all WASI interfaces from this module into the `linker` provided.
88
///
@@ -18,8 +18,8 @@ use wasmtime::component::{HasData, Linker};
1818
///
1919
/// ```
2020
/// use wasmtime::{Engine, Result, Store, Config};
21-
/// use wasmtime::component::Linker;
22-
/// use wasmtime_wasi::clocks::{WasiClocksView, WasiClocksCtx};
21+
/// use wasmtime::component::{Linker, ResourceTable};
22+
/// use wasmtime_wasi::clocks::{WasiClocksView, WasiClocksCtxView, WasiClocksCtx};
2323
///
2424
/// fn main() -> Result<()> {
2525
/// let mut config = Config::new();
@@ -33,22 +33,24 @@ use wasmtime::component::{HasData, Linker};
3333
///
3434
/// let mut store = Store::new(
3535
/// &engine,
36-
/// MyState {
37-
/// clocks: WasiClocksCtx::default(),
38-
/// },
36+
/// MyState::default(),
3937
/// );
4038
///
4139
/// // ... use `linker` to instantiate within `store` ...
4240
///
4341
/// Ok(())
4442
/// }
4543
///
44+
/// #[derive(Default)]
4645
/// struct MyState {
4746
/// clocks: WasiClocksCtx,
47+
/// table: ResourceTable,
4848
/// }
4949
///
5050
/// impl WasiClocksView for MyState {
51-
/// fn clocks(&mut self) -> &mut WasiClocksCtx { &mut self.clocks }
51+
/// fn clocks(&mut self) -> WasiClocksCtxView {
52+
/// WasiClocksCtxView { ctx: &mut self.clocks, table: &mut self.table }
53+
/// }
5254
/// }
5355
/// ```
5456
pub fn add_to_linker<T>(linker: &mut Linker<T>) -> wasmtime::Result<()>
@@ -59,9 +61,3 @@ where
5961
clocks::wall_clock::add_to_linker::<_, WasiClocks>(linker, T::clocks)?;
6062
Ok(())
6163
}
62-
63-
struct WasiClocks;
64-
65-
impl HasData for WasiClocks {
66-
type Data<'a> = &'a mut WasiClocksCtx;
67-
}

crates/wasi/src/preview1.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
//! ```
6565
6666
use crate::cli::WasiCliView;
67+
use crate::clocks::WasiClocksView;
6768
use crate::p2::bindings::{
6869
cli::{
6970
stderr::Host as _, stdin::Host as _, stdout::Host as _, terminal_input, terminal_output,
@@ -1232,15 +1233,13 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
12321233
id: types::Clockid,
12331234
) -> Result<types::Timestamp, types::Error> {
12341235
let res = match id {
1235-
types::Clockid::Realtime => wall_clock::Host::resolution(&mut self.as_wasi_impl())
1236+
types::Clockid::Realtime => wall_clock::Host::resolution(&mut self.clocks())
12361237
.context("failed to call `wall_clock::resolution`")
12371238
.map_err(types::Error::trap)?
12381239
.try_into()?,
1239-
types::Clockid::Monotonic => {
1240-
monotonic_clock::Host::resolution(&mut self.as_wasi_impl())
1241-
.context("failed to call `monotonic_clock::resolution`")
1242-
.map_err(types::Error::trap)?
1243-
}
1240+
types::Clockid::Monotonic => monotonic_clock::Host::resolution(&mut self.clocks())
1241+
.context("failed to call `monotonic_clock::resolution`")
1242+
.map_err(types::Error::trap)?,
12441243
types::Clockid::ProcessCputimeId | types::Clockid::ThreadCputimeId => {
12451244
return Err(types::Errno::Badf.into());
12461245
}
@@ -1256,11 +1255,11 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
12561255
_precision: types::Timestamp,
12571256
) -> Result<types::Timestamp, types::Error> {
12581257
let now = match id {
1259-
types::Clockid::Realtime => wall_clock::Host::now(&mut self.as_wasi_impl())
1258+
types::Clockid::Realtime => wall_clock::Host::now(&mut self.clocks())
12601259
.context("failed to call `wall_clock::now`")
12611260
.map_err(types::Error::trap)?
12621261
.try_into()?,
1263-
types::Clockid::Monotonic => monotonic_clock::Host::now(&mut self.as_wasi_impl())
1262+
types::Clockid::Monotonic => monotonic_clock::Host::now(&mut self.clocks())
12641263
.context("failed to call `monotonic_clock::now`")
12651264
.map_err(types::Error::trap)?,
12661265
types::Clockid::ProcessCputimeId | types::Clockid::ThreadCputimeId => {
@@ -2320,7 +2319,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
23202319
types::Clockid::Monotonic => (timeout, absolute),
23212320
types::Clockid::Realtime if !absolute => (timeout, false),
23222321
types::Clockid::Realtime => {
2323-
let now = wall_clock::Host::now(&mut self.as_wasi_impl())
2322+
let now = wall_clock::Host::now(&mut self.clocks())
23242323
.context("failed to call `wall_clock::now`")
23252324
.map_err(types::Error::trap)?;
23262325

@@ -2343,11 +2342,11 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
23432342
_ => return Err(types::Errno::Inval.into()),
23442343
};
23452344
if absolute {
2346-
monotonic_clock::Host::subscribe_instant(&mut self.as_wasi_impl(), timeout)
2345+
monotonic_clock::Host::subscribe_instant(&mut self.clocks(), timeout)
23472346
.context("failed to call `monotonic_clock::subscribe_instant`")
23482347
.map_err(types::Error::trap)?
23492348
} else {
2350-
monotonic_clock::Host::subscribe_duration(&mut self.as_wasi_impl(), timeout)
2349+
monotonic_clock::Host::subscribe_duration(&mut self.clocks(), timeout)
23512350
.context("failed to call `monotonic_clock::subscribe_duration`")
23522351
.map_err(types::Error::trap)?
23532352
}

crates/wasi/src/view.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,12 @@ impl<T: WasiView> crate::sockets::WasiSocketsView for T {
5959
}
6060

6161
impl<T: WasiView> crate::clocks::WasiClocksView for T {
62-
fn clocks(&mut self) -> &mut crate::clocks::WasiClocksCtx {
63-
&mut self.ctx().ctx.clocks
62+
fn clocks(&mut self) -> crate::clocks::WasiClocksCtxView<'_> {
63+
let WasiCtxView { ctx, table } = self.ctx();
64+
crate::clocks::WasiClocksCtxView {
65+
ctx: &mut ctx.clocks,
66+
table,
67+
}
6468
}
6569
}
6670

0 commit comments

Comments
 (0)