Skip to content

Commit 2f767a5

Browse files
authored
Remove dependency on std for async feature (#1591)
* Remove dependency on `std` for `async` feature This commit adds `no_std` support for the `async` feature of the `wit-bindgen` crate, notably enabling this to be used as part of the standard library for wasip3. * Fix inter-task-wakeup compat * Run rustfmt * Update test expectations * Add a `TryLock` primitive * Run rustfmt
1 parent be1402f commit 2f767a5

File tree

19 files changed

+230
-73
lines changed

19 files changed

+230
-73
lines changed

crates/guest-rust/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ default = ["macros", "realloc", "async", "std", "bitflags", "macro-string"]
3232
macros = ["dep:wit-bindgen-rust-macro"]
3333
realloc = []
3434
std = []
35-
async = ["std", "wit-bindgen-rust-macro?/async"]
35+
async = ["wit-bindgen-rust-macro?/async"]
3636
bitflags = ["dep:bitflags"]
37-
async-spawn = ['async', 'dep:futures']
37+
async-spawn = ['async', 'dep:futures', 'std']
3838
futures-stream = ['async', 'dep:futures']
3939
macro-string = ["wit-bindgen-rust-macro?/macro-string"]
4040

crates/guest-rust/src/rt/async_support.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
#![deny(missing_docs)]
22

3-
extern crate std;
3+
use alloc::boxed::Box;
4+
use alloc::collections::BTreeMap;
5+
use alloc::sync::Arc;
6+
use alloc::task::Wake;
7+
use core::ffi::c_void;
8+
use core::future::Future;
9+
use core::mem;
10+
use core::pin::Pin;
11+
use core::ptr;
412
use core::sync::atomic::{AtomicU32, Ordering};
5-
use std::boxed::Box;
6-
use std::collections::BTreeMap;
7-
use std::ffi::c_void;
8-
use std::future::Future;
9-
use std::mem;
10-
use std::pin::Pin;
11-
use std::ptr;
12-
use std::sync::Arc;
13-
use std::task::{Context, Poll, Wake, Waker};
13+
use core::task::{Context, Poll, Waker};
1414

1515
macro_rules! rtdebug {
1616
($($f:tt)*) => {
1717
// Change this flag to enable debugging, right now we're not using a
1818
// crate like `log` or such to reduce runtime deps. Intended to be used
1919
// during development for now.
2020
if false {
21+
#[cfg(feature = "std")]
2122
std::eprintln!($($f)*);
2223
}
2324
}
@@ -67,6 +68,7 @@ mod futures_stream;
6768
mod inter_task_wakeup;
6869
mod stream_support;
6970
mod subtask;
71+
mod try_lock;
7072
#[cfg(feature = "inter-task-wakeup")]
7173
mod unit_stream;
7274
mod waitable;

crates/guest-rust/src/rt/async_support/abi_buffer.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::rt::Cleanup;
22
use crate::rt::async_support::StreamOps;
3-
use std::alloc::Layout;
4-
use std::mem::{self, MaybeUninit};
5-
use std::ptr;
6-
use std::vec::Vec;
3+
use alloc::alloc::Layout;
4+
use alloc::vec::Vec;
5+
use core::mem::{self, MaybeUninit};
6+
use core::ptr;
77

88
/// A helper structure used with a stream to handle the canonical ABI
99
/// representation of lists and track partial writes.

crates/guest-rust/src/rt/async_support/error_context.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Raw bindings to `error-context` in the canonical ABI.
22
3-
use std::fmt::{self, Debug, Display};
4-
use std::ptr;
5-
use std::string::String;
3+
use alloc::string::String;
4+
use core::fmt::{self, Debug, Display};
5+
use core::ptr;
66

77
/// Represents the Component Model `error-context` type.
88
#[derive(PartialEq, Eq)]
@@ -56,7 +56,7 @@ impl Display for ErrorContext {
5656
}
5757
}
5858

59-
impl std::error::Error for ErrorContext {}
59+
impl core::error::Error for ErrorContext {}
6060

6161
impl Drop for ErrorContext {
6262
fn drop(&mut self) {

crates/guest-rust/src/rt/async_support/future_support.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,19 @@
113113
114114
use crate::rt::Cleanup;
115115
use crate::rt::async_support::ReturnCode;
116+
use crate::rt::async_support::try_lock::TryLock;
116117
use crate::rt::async_support::waitable::{WaitableOp, WaitableOperation};
117-
use std::alloc::Layout;
118-
use std::fmt;
119-
use std::future::{Future, IntoFuture};
120-
use std::marker;
121-
use std::mem::{self, ManuallyDrop};
122-
use std::pin::Pin;
123-
use std::ptr;
124-
use std::sync::atomic::{AtomicU32, Ordering::Relaxed};
125-
use std::sync::{Arc, Mutex};
126-
use std::task::{Context, Poll, Wake, Waker};
118+
use alloc::sync::Arc;
119+
use alloc::task::Wake;
120+
use core::alloc::Layout;
121+
use core::fmt;
122+
use core::future::{Future, IntoFuture};
123+
use core::marker;
124+
use core::mem::{self, ManuallyDrop};
125+
use core::pin::Pin;
126+
use core::ptr;
127+
use core::sync::atomic::{AtomicU32, Ordering::Relaxed};
128+
use core::task::{Context, Poll, Waker};
127129

128130
/// Helper trait which encapsulates the various operations which can happen
129131
/// with a future.
@@ -501,7 +503,7 @@ impl<O: FutureOps> RawFutureWriter<O> {
501503
O: 'static,
502504
{
503505
return Arc::new(DeferredWrite {
504-
write: Mutex::new(self.write(value)),
506+
write: TryLock::new(self.write(value)),
505507
})
506508
.wake();
507509

@@ -519,7 +521,7 @@ impl<O: FutureOps> RawFutureWriter<O> {
519521
/// doesn't require the `async-spawn` feature and instead works with the
520522
/// `wasip3_task` C ABI structures (which spawn doesn't support).
521523
struct DeferredWrite<O: FutureOps> {
522-
write: Mutex<RawFutureWrite<O>>,
524+
write: TryLock<RawFutureWrite<O>>,
523525
}
524526

525527
// SAFETY: Needed to satisfy `Waker::from` but otherwise should be ok
@@ -550,7 +552,7 @@ impl<O: FutureOps> RawFutureWriter<O> {
550552
let poll = {
551553
let waker = Waker::from(self.clone());
552554
let mut cx = Context::from_waker(&waker);
553-
let mut write = self.write.lock().unwrap();
555+
let mut write = self.write.try_lock().unwrap();
554556
unsafe { Pin::new_unchecked(&mut *write).poll(&mut cx) }
555557
};
556558
if poll.is_ready() {
@@ -756,7 +758,7 @@ impl<T> fmt::Display for FutureWriteError<T> {
756758
}
757759
}
758760

759-
impl<T> std::error::Error for FutureWriteError<T> {}
761+
impl<T> core::error::Error for FutureWriteError<T> {}
760762

761763
/// Result of [`FutureWrite::cancel`].
762764
#[derive(Debug)]

crates/guest-rust/src/rt/async_support/futures_stream.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::stream_support::{RawStreamReader, StreamOps, StreamVtable};
2-
use std::boxed::Box;
3-
use std::{
2+
use alloc::boxed::Box;
3+
use core::{
44
future::Future,
55
pin::Pin,
66
task::{Context, Poll},
@@ -60,7 +60,7 @@ impl<O: StreamOps + 'static> futures::stream::Stream for RawStreamReaderStream<O
6060
// All variants of `StreamAdapterState` are `Unpin`, so `Pin<&mut Self>`
6161
// can be freely projected.
6262
loop {
63-
match std::mem::replace(&mut self.state, StreamAdapterState::Complete) {
63+
match core::mem::replace(&mut self.state, StreamAdapterState::Complete) {
6464
StreamAdapterState::Idle(mut reader) => {
6565
let fut: ReadNextFut<O> = Box::pin(async move {
6666
let item = reader.next().await;

crates/guest-rust/src/rt/async_support/inter_task_wakeup.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use super::FutureState;
2+
use crate::rt::async_support::try_lock::TryLock;
23
use crate::rt::async_support::{BLOCKED, COMPLETED};
34
use crate::{RawStreamReader, RawStreamWriter, StreamOps, UnitStreamOps};
4-
use std::ptr;
5-
use std::sync::Mutex;
5+
use core::ptr;
66

77
#[derive(Default)]
88
pub struct State {
@@ -27,7 +27,7 @@ impl FutureState<'_> {
2727
assert!(!self.inter_task_wakeup.stream_reading);
2828
let (writer, reader) = UnitStreamOps::new();
2929
self.inter_task_wakeup.stream = Some(reader);
30-
let mut waker_stream = self.waker.inter_task_stream.lock.lock().unwrap();
30+
let mut waker_stream = self.waker.inter_task_stream.lock.try_lock().unwrap();
3131
assert!(waker_stream.is_none());
3232
*waker_stream = Some(writer);
3333
}
@@ -81,7 +81,7 @@ impl State {
8181

8282
#[derive(Default)]
8383
pub struct WakerState {
84-
lock: Mutex<Option<RawStreamWriter<UnitStreamOps>>>,
84+
lock: TryLock<Option<RawStreamWriter<UnitStreamOps>>>,
8585
}
8686

8787
impl WakerState {
@@ -90,7 +90,7 @@ impl WakerState {
9090
// original future itself. The stream should also have an active read
9191
// while the future is sleeping. This means that this write should
9292
// succeed immediately.
93-
let mut inter_task_stream = self.lock.lock().unwrap();
93+
let mut inter_task_stream = self.lock.try_lock().unwrap();
9494
let stream = inter_task_stream.as_mut().unwrap();
9595
let rc = unsafe { UnitStreamOps.start_write(stream.handle(), ptr::null_mut(), 1) };
9696
assert_eq!(rc, COMPLETED | (1 << 4));

crates/guest-rust/src/rt/async_support/spawn_disabled.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::rt::async_support::BoxFuture;
2-
use std::task::{Context, Poll};
2+
use core::task::{Context, Poll};
33

44
#[derive(Default)]
55
pub struct Tasks<'a> {

crates/guest-rust/src/rt/async_support/stream_support.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
44
use crate::rt::async_support::waitable::{WaitableOp, WaitableOperation};
55
use crate::rt::async_support::{AbiBuffer, DROPPED, ReturnCode};
6+
use alloc::vec::Vec;
67
use {
78
crate::rt::Cleanup,
8-
std::{
9+
core::{
910
alloc::Layout,
1011
fmt,
1112
future::Future,
1213
pin::Pin,
1314
ptr,
1415
sync::atomic::{AtomicU32, Ordering::Relaxed},
1516
task::{Context, Poll},
16-
vec::Vec,
1717
},
1818
};
1919

@@ -308,7 +308,7 @@ where
308308
// TODO: can probably be a bit more efficient about this and avoid
309309
// moving `value` onto the heap in some situations, but that's left as
310310
// an optimization for later.
311-
self.write_all(std::vec![value]).await.pop()
311+
self.write_all(alloc::vec![value]).await.pop()
312312
}
313313
}
314314

crates/guest-rust/src/rt/async_support/subtask.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ use crate::rt::async_support::{
1313
STATUS_RETURNED, STATUS_RETURNED_CANCELLED, STATUS_STARTED, STATUS_STARTED_CANCELLED,
1414
STATUS_STARTING,
1515
};
16-
use std::alloc::Layout;
17-
use std::future::Future;
18-
use std::marker;
19-
use std::num::NonZeroU32;
20-
use std::ptr;
16+
use core::alloc::Layout;
17+
use core::future::Future;
18+
use core::marker;
19+
use core::num::NonZeroU32;
20+
use core::ptr;
2121

2222
/// Raw operations used to invoke an imported asynchronous function.
2323
///

0 commit comments

Comments
 (0)