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

Commit 0dab298

Browse files
authored
Merge pull request #236 from alexcrichton/merge
Merge with upstream
2 parents 7b215bc + 1458e4f commit 0dab298

27 files changed

Lines changed: 1437 additions & 729 deletions

File tree

ci/vendor-wit.sh

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,22 +68,12 @@ make_vendor "wasi-config" "config@f4d699b"
6868

6969
make_vendor "wasi-keyvalue" "keyvalue@219ea36"
7070

71-
# TODO: upstream `async` changes and eventually re-enable this
7271
# make_vendor "wasi/src/p3" "
73-
# cli@82b86d9@wit-0.3.0-draft
74-
# clocks@646092f@wit-0.3.0-draft
75-
# filesystem@740cd76@wit-0.3.0-draft
76-
# random@9499404@wit-0.3.0-draft
77-
# sockets@41d7079@wit-0.3.0-draft
78-
# "
79-
# `wasi:http` from https://github.com/WebAssembly/wasi-http/pull/158
80-
# make_vendor "wasi-http/src/p3" "
81-
# cli@82b86d9@wit-0.3.0-draft
82-
# clocks@646092f@wit-0.3.0-draft
83-
# filesystem@740cd76@wit-0.3.0-draft
84-
# random@9499404@wit-0.3.0-draft
85-
# sockets@41d7079@wit-0.3.0-draft
86-
# http@ae89575@wit-0.3.0-draft
72+
# cli@939bd6d@wit-0.3.0-draft
73+
# clocks@13d1c82@wit-0.3.0-draft
74+
# filesystem@e2a2ddc@wit-0.3.0-draft
75+
# random@4e94663@wit-0.3.0-draft
76+
# sockets@bb247e2@wit-0.3.0-draft
8777
# "
8878

8979
rm -rf $cache_dir

crates/test-programs/artifacts/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ impl Artifacts {
104104
}
105105
let adapter = match test.name.as_str() {
106106
"reactor" => &reactor_adapter,
107+
s if s.starts_with("p3_") => &reactor_adapter,
107108
s if s.starts_with("api_proxy") => &proxy_adapter,
108109
_ => &command_adapter,
109110
};

crates/test-programs/src/bin/p3_clocks_sleep.rs

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use core::future::Future as _;
22
use core::pin::pin;
3-
use core::ptr;
4-
use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
3+
use core::task::{Context, Poll, Waker};
54

65
use test_programs::p3::wasi::clocks::monotonic_clock;
76

@@ -18,32 +17,14 @@ impl test_programs::p3::exports::wasi::cli::run::Guest for Component {
1817
}
1918
}
2019

21-
// Adapted from https://github.com/rust-lang/rust/blob/cd805f09ffbfa3896c8f50a619de9b67e1d9f3c3/library/core/src/task/wake.rs#L63-L77
22-
// TODO: Replace by `Waker::noop` once MSRV is raised to 1.85
23-
const NOOP_RAW_WAKER: RawWaker = {
24-
const VTABLE: RawWakerVTable = RawWakerVTable::new(
25-
// Cloning just returns a new no-op raw waker
26-
|_| NOOP_RAW_WAKER,
27-
// `wake` does nothing
28-
|_| {},
29-
// `wake_by_ref` does nothing
30-
|_| {},
31-
// Dropping does nothing as we don't allocate anything
32-
|_| {},
33-
);
34-
RawWaker::new(ptr::null(), &VTABLE)
35-
};
36-
37-
const NOOP_WAKER: &'static Waker = &unsafe { Waker::from_raw(NOOP_RAW_WAKER) };
38-
3920
async fn sleep_10ms() {
4021
let dur = 10_000_000;
4122
monotonic_clock::wait_until(monotonic_clock::now() + dur).await;
4223
monotonic_clock::wait_for(dur).await;
4324
}
4425

4526
fn sleep_0ms() {
46-
let mut cx = Context::from_waker(NOOP_WAKER);
27+
let mut cx = Context::from_waker(Waker::noop());
4728

4829
assert_eq!(
4930
pin!(monotonic_clock::wait_until(monotonic_clock::now())).poll(&mut cx),
@@ -58,7 +39,7 @@ fn sleep_0ms() {
5839
}
5940

6041
fn sleep_backwards_in_time() {
61-
let mut cx = Context::from_waker(NOOP_WAKER);
42+
let mut cx = Context::from_waker(Waker::noop());
6243

6344
assert_eq!(
6445
pin!(monotonic_clock::wait_until(monotonic_clock::now() - 1)).poll(&mut cx),

crates/test-programs/src/bin/p3_random_imports.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,6 @@ test_programs::p3::export!(Component);
66

77
impl test_programs::p3::exports::wasi::cli::run::Guest for Component {
88
async fn run() -> Result<(), ()> {
9-
let mut bytes = [0_u8; 256];
10-
unsafe {
11-
wasip1::random_get(bytes.as_mut_ptr(), bytes.len()).unwrap();
12-
}
13-
14-
assert!(bytes.iter().any(|x| *x != 0));
15-
169
// Acquired random bytes should be of the expected length.
1710
let array = random::random::get_random_bytes(100);
1811
assert_eq!(array.len(), 100);

crates/wasi-http/src/p3/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@ use wasmtime_wasi::p3::ResourceView;
277277
pub fn add_to_linker<T>(l: &mut wasmtime::component::Linker<T>) -> anyhow::Result<()>
278278
where
279279
T: WasiHttpView
280-
+ wasmtime_wasi::p3::clocks::WasiClocksView
281-
+ wasmtime_wasi::p3::random::WasiRandomView
280+
+ wasmtime_wasi::clocks::WasiClocksView
281+
+ wasmtime_wasi::random::WasiRandomView
282282
+ wasmtime_wasi::p3::cli::WasiCliView
283283
+ 'static,
284284
{

crates/wasi-http/tests/all/p3/mod.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ use core::future::Future;
33
use bytes::Bytes;
44
use wasmtime::Store;
55
use wasmtime::component::{Component, Linker, ResourceTable};
6+
use wasmtime_wasi::clocks::{WasiClocksCtx, WasiClocksView};
67
use wasmtime_wasi::p2::{IoView, WasiCtx, WasiCtxBuilder, WasiView};
78
use wasmtime_wasi::p3::ResourceView;
89
use wasmtime_wasi::p3::cli::{WasiCliCtx, WasiCliView};
9-
use wasmtime_wasi::p3::clocks::{WasiClocksCtx, WasiClocksView};
1010
use wasmtime_wasi::p3::filesystem::{WasiFilesystemCtx, WasiFilesystemView};
11-
use wasmtime_wasi::p3::random::{WasiRandomCtx, WasiRandomView};
1211
use wasmtime_wasi::p3::sockets::{WasiSocketsCtx, WasiSocketsView};
12+
use wasmtime_wasi::random::{WasiRandomCtx, WasiRandomView};
1313
use wasmtime_wasi_http::p3::bindings::http::types::ErrorCode;
1414
use wasmtime_wasi_http::p3::{
1515
Client, DEFAULT_FORBIDDEN_HEADERS, RequestOptions, WasiHttpCtx, WasiHttpView,
@@ -22,12 +22,11 @@ mod proxy;
2222

2323
struct Ctx<C: Client = TestClient> {
2424
cli: WasiCliCtx,
25-
clocks: WasiClocksCtx,
2625
filesystem: WasiFilesystemCtx,
27-
random: WasiRandomCtx,
2826
sockets: WasiSocketsCtx,
2927
table: ResourceTable,
3028
wasip2: WasiCtx,
29+
wasip3: wasmtime_wasi::p3::WasiCtx,
3130
http: WasiHttpCtx<C>,
3231
}
3332

@@ -38,12 +37,13 @@ where
3837
fn default() -> Self {
3938
Self {
4039
cli: WasiCliCtx::default(),
41-
clocks: WasiClocksCtx::default(),
4240
filesystem: WasiFilesystemCtx::default(),
4341
sockets: WasiSocketsCtx::default(),
44-
random: WasiRandomCtx::default(),
4542
table: ResourceTable::default(),
4643
wasip2: WasiCtxBuilder::new().inherit_stdio().build(),
44+
wasip3: wasmtime_wasi::p3::WasiCtxBuilder::new()
45+
.inherit_stdio()
46+
.build(),
4747
http: WasiHttpCtx::default(),
4848
}
4949
}
@@ -61,6 +61,12 @@ impl<C: Client> IoView for Ctx<C> {
6161
}
6262
}
6363

64+
impl<C: Client> wasmtime_wasi::p3::WasiView for Ctx<C> {
65+
fn ctx(&mut self) -> &mut wasmtime_wasi::p3::WasiCtx {
66+
&mut self.wasip3
67+
}
68+
}
69+
6470
impl<C: Client> ResourceView for Ctx<C> {
6571
fn table(&mut self) -> &mut ResourceTable {
6672
&mut self.table
@@ -75,7 +81,7 @@ impl<C: Client> WasiCliView for Ctx<C> {
7581

7682
impl<C: Client> WasiClocksView for Ctx<C> {
7783
fn clocks(&mut self) -> &WasiClocksCtx {
78-
&self.clocks
84+
&self.wasip3.clocks
7985
}
8086
}
8187

@@ -87,7 +93,7 @@ impl<C: Client> WasiFilesystemView for Ctx<C> {
8793

8894
impl<C: Client> WasiRandomView for Ctx<C> {
8995
fn random(&mut self) -> &mut WasiRandomCtx {
90-
&mut self.random
96+
&mut self.wasip3.random
9197
}
9298
}
9399

crates/wasi/src/clocks.rs

Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,45 @@
1-
pub mod host;
2-
use cap_std::time::Duration;
1+
use cap_std::time::{Duration, Instant, SystemClock};
2+
use cap_std::{AmbientAuthority, ambient_authority};
3+
use cap_time_ext::{MonotonicClockExt as _, SystemClockExt as _};
4+
5+
#[repr(transparent)]
6+
pub struct WasiClocksImpl<T>(pub T);
7+
8+
impl<T: WasiClocksView> WasiClocksView for &mut T {
9+
fn clocks(&mut self) -> &WasiClocksCtx {
10+
(**self).clocks()
11+
}
12+
}
13+
14+
impl<T: WasiClocksView> WasiClocksView for WasiClocksImpl<T> {
15+
fn clocks(&mut self) -> &WasiClocksCtx {
16+
self.0.clocks()
17+
}
18+
}
19+
20+
impl WasiClocksView for WasiClocksCtx {
21+
fn clocks(&mut self) -> &WasiClocksCtx {
22+
self
23+
}
24+
}
25+
26+
pub trait WasiClocksView: Send {
27+
fn clocks(&mut self) -> &WasiClocksCtx;
28+
}
29+
30+
pub struct WasiClocksCtx {
31+
pub wall_clock: Box<dyn HostWallClock + Send>,
32+
pub monotonic_clock: Box<dyn HostMonotonicClock + Send>,
33+
}
34+
35+
impl Default for WasiClocksCtx {
36+
fn default() -> Self {
37+
Self {
38+
wall_clock: wall_clock(),
39+
monotonic_clock: monotonic_clock(),
40+
}
41+
}
42+
}
343

444
pub trait HostWallClock: Send {
545
fn resolution(&self) -> Duration;
@@ -10,3 +50,84 @@ pub trait HostMonotonicClock: Send {
1050
fn resolution(&self) -> u64;
1151
fn now(&self) -> u64;
1252
}
53+
54+
pub struct WallClock {
55+
/// The underlying system clock.
56+
clock: cap_std::time::SystemClock,
57+
}
58+
59+
impl Default for WallClock {
60+
fn default() -> Self {
61+
Self::new(ambient_authority())
62+
}
63+
}
64+
65+
impl WallClock {
66+
pub fn new(ambient_authority: AmbientAuthority) -> Self {
67+
Self {
68+
clock: cap_std::time::SystemClock::new(ambient_authority),
69+
}
70+
}
71+
}
72+
73+
impl HostWallClock for WallClock {
74+
fn resolution(&self) -> Duration {
75+
self.clock.resolution()
76+
}
77+
78+
fn now(&self) -> Duration {
79+
// WASI defines wall clocks to return "Unix time".
80+
self.clock
81+
.now()
82+
.duration_since(SystemClock::UNIX_EPOCH)
83+
.unwrap()
84+
}
85+
}
86+
87+
pub struct MonotonicClock {
88+
/// The underlying system clock.
89+
clock: cap_std::time::MonotonicClock,
90+
91+
/// The `Instant` this clock was created. All returned times are
92+
/// durations since that time.
93+
initial: Instant,
94+
}
95+
96+
impl Default for MonotonicClock {
97+
fn default() -> Self {
98+
Self::new(ambient_authority())
99+
}
100+
}
101+
102+
impl MonotonicClock {
103+
pub fn new(ambient_authority: AmbientAuthority) -> Self {
104+
let clock = cap_std::time::MonotonicClock::new(ambient_authority);
105+
let initial = clock.now();
106+
Self { clock, initial }
107+
}
108+
}
109+
110+
impl HostMonotonicClock for MonotonicClock {
111+
fn resolution(&self) -> u64 {
112+
self.clock.resolution().as_nanos().try_into().unwrap()
113+
}
114+
115+
fn now(&self) -> u64 {
116+
// Unwrap here and in `resolution` above; a `u64` is wide enough to
117+
// hold over 584 years of nanoseconds.
118+
self.clock
119+
.now()
120+
.duration_since(self.initial)
121+
.as_nanos()
122+
.try_into()
123+
.unwrap()
124+
}
125+
}
126+
127+
pub fn monotonic_clock() -> Box<dyn HostMonotonicClock + Send> {
128+
Box::new(MonotonicClock::default())
129+
}
130+
131+
pub fn wall_clock() -> Box<dyn HostWallClock + Send> {
132+
Box::new(WallClock::default())
133+
}

crates/wasi/src/clocks/host.rs

Lines changed: 0 additions & 73 deletions
This file was deleted.

0 commit comments

Comments
 (0)