Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion library/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,8 @@ dependencies = [
"rustc-demangle",
"std_detect",
"unwind",
"wasi",
"wasi 0.11.1+wasi-snapshot-preview1",
"wasi 0.14.3+wasi-0.2.4",
"windows-targets 0.0.0",
]

Expand Down Expand Up @@ -399,6 +400,17 @@ dependencies = [
"rustc-std-workspace-core",
]

[[package]]
name = "wasi"
version = "0.14.3+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95"
dependencies = [
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
"wit-bindgen",
]

[[package]]
name = "windows-sys"
version = "0.59.0"
Expand Down Expand Up @@ -475,3 +487,13 @@ name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"

[[package]]
name = "wit-bindgen"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814"
dependencies = [
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
]
5 changes: 5 additions & 0 deletions library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ wasi = { version = "0.11.0", features = [
'rustc-dep-of-std',
], default-features = false }

[target.'cfg(all(target_os = "wasi", target_env = "p2"))'.dependencies]
wasip2 = { version = '0.14.3', features = [
'rustc-dep-of-std',
], default-features = false, package = 'wasi' }

[target.'cfg(target_os = "uefi")'.dependencies]
r-efi = { version = "5.2.0", features = ['rustc-dep-of-std'] }
r-efi-alloc = { version = "2.0.0", features = ['rustc-dep-of-std'] }
Expand Down
10 changes: 7 additions & 3 deletions library/std/src/sys/args/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ cfg_select! {
mod uefi;
pub use uefi::*;
}
target_os = "wasi" => {
mod wasi;
pub use wasi::*;
all(target_os = "wasi", target_env = "p1") => {
mod wasip1;
pub use wasip1::*;
}
all(target_os = "wasi", target_env = "p2") => {
mod wasip2;
pub use wasip2::*;
}
target_os = "xous" => {
mod xous;
Expand Down
File renamed without changes.
6 changes: 6 additions & 0 deletions library/std/src/sys/args/wasip2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub use super::common::Args;

/// Returns the command line arguments
pub fn args() -> Args {
Args::new(wasip2::cli::environment::get_arguments().into_iter().map(|arg| arg.into()).collect())
}
6 changes: 3 additions & 3 deletions library/std/src/sys/pal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ cfg_select! {
mod wasip2;
pub use self::wasip2::*;
}
target_os = "wasi" => {
mod wasi;
pub use self::wasi::*;
all(target_os = "wasi", target_env = "p1") => {
mod wasip1;
pub use self::wasip1::*;
}
target_family = "wasm" => {
mod wasm;
Expand Down
6 changes: 2 additions & 4 deletions library/std/src/sys/pal/wasip2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@
#[path = "../wasm/atomics/futex.rs"]
pub mod futex;

#[path = "../wasi/os.rs"]
#[path = "../wasip1/os.rs"]
pub mod os;
#[path = "../unsupported/pipe.rs"]
pub mod pipe;
#[path = "../wasi/thread.rs"]
pub mod thread;
#[path = "../wasi/time.rs"]
pub mod time;

#[path = "../unsupported/common.rs"]
Expand All @@ -26,7 +24,7 @@ mod common;

pub use common::*;

#[path = "../wasi/helpers.rs"]
#[path = "../wasip1/helpers.rs"]
mod helpers;

// The following exports are listed individually to work around Rust's glob
Expand Down
73 changes: 73 additions & 0 deletions library/std/src/sys/pal/wasip2/thread.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use crate::ffi::CStr;
use crate::io;
use crate::num::NonZero;
use crate::time::{Duration, Instant};

pub struct Thread(!);

pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;

impl Thread {
pub unsafe fn new(
_stack: usize,
_name: Option<&str>,
_p: Box<dyn FnOnce()>,
) -> io::Result<Thread> {
// Note that unlike WASIp1 even if the wasm `atomics` feature is enabled
// there is no support for threads, not even experimentally, not even in
// wasi-libc. Thus this is unconditionally unsupported.
crate::sys::unsupported()
}

pub fn yield_now() {
// no API for this in WASIp2, but there's also no threads, so that's
// sort of expected.
}

pub fn set_name(_name: &CStr) {
// nope
}

pub fn sleep(dur: Duration) {
// Sleep in increments of `u64::MAX` nanoseconds until the `dur` is
// entirely drained.
let mut remaining = dur.as_nanos();
while remaining > 0 {
let amt = u64::try_from(remaining).unwrap_or(u64::MAX);
wasip2::clocks::monotonic_clock::subscribe_duration(amt).block();
remaining -= u128::from(amt);
}
}

pub fn sleep_until(deadline: Instant) {
match u64::try_from(deadline.into_inner().as_duration().as_nanos()) {
// If the point in time we're sleeping to fits within a 64-bit
// number of nanoseconds then directly use `subscribe_instant`.
Ok(deadline) => {
wasip2::clocks::monotonic_clock::subscribe_instant(deadline).block();
}
// ... otherwise we're sleeping for 500+ years relative to the
// "start" of what the system is using as a clock so speed/accuracy
// is not so much of a concern. Use `sleep` instead.
Err(_) => {
let now = Instant::now();

if let Some(delay) = deadline.checked_duration_since(now) {
Self::sleep(delay);
}
}
}
}

pub fn join(self) {
self.0
}
}

pub(crate) fn current_os_id() -> Option<u64> {
None
}

pub fn available_parallelism() -> io::Result<NonZero<usize>> {
crate::sys::unsupported()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the rationale for returning an error instead of e.g. constant 1?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is following the precedent of wasip1's implementation. Following the git-blame trail that goes back to #74480, the original implementation, which had a fallback of an error for all unknown platforms.

Personally I'd say it's somewhat accurate to leave this as unsupported for now since that basically forces callers to assume it's 1 and forces a threaded implementation in the future to come through and implement this as opposed to accidentally forgetting about it

}
69 changes: 69 additions & 0 deletions library/std/src/sys/pal/wasip2/time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use crate::time::Duration;

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct Instant(Duration);

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct SystemTime(Duration);

pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));

impl Instant {
pub fn now() -> Instant {
Instant(Duration::from_nanos(wasip2::clocks::monotonic_clock::now()))
}

pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
self.0.checked_sub(other.0)
}

pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant(self.0.checked_add(*other)?))
}

pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
Some(Instant(self.0.checked_sub(*other)?))
}

pub(super) fn as_duration(&self) -> &Duration {
&self.0
}
}

impl SystemTime {
pub fn now() -> SystemTime {
let now = wasip2::clocks::wall_clock::now();
SystemTime(Duration::new(now.seconds, now.nanoseconds))
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
SystemTime(Duration::from_nanos(ts))
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
// FIXME: const TryInto
let ns = self.0.as_nanos();
if ns <= u64::MAX as u128 { Some(ns as u64) } else { None }
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
// FIXME: ok_or_else with const closures
match self.0.checked_sub(other.0) {
Some(duration) => Ok(duration),
None => Err(other.0 - self.0),
}
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_add(*other)?))
}

#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
Some(SystemTime(self.0.checked_sub(*other)?))
}
}
11 changes: 8 additions & 3 deletions library/std/src/sys/random/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,13 @@ cfg_select! {
mod vxworks;
pub use vxworks::fill_bytes;
}
target_os = "wasi" => {
mod wasi;
pub use wasi::fill_bytes;
all(target_os = "wasi", target_env = "p1") => {
mod wasip1;
pub use wasip1::fill_bytes;
}
all(target_os = "wasi", target_env = "p2") => {
mod wasip2;
pub use wasip2::{fill_bytes, hashmap_random_keys};
}
target_os = "zkvm" => {
mod zkvm;
Expand All @@ -110,6 +114,7 @@ cfg_select! {
target_os = "linux",
target_os = "android",
all(target_family = "wasm", target_os = "unknown"),
all(target_os = "wasi", target_env = "p2"),
target_os = "xous",
)))]
pub fn hashmap_random_keys() -> (u64, u64) {
Expand Down
9 changes: 9 additions & 0 deletions library/std/src/sys/random/wasip2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pub fn fill_bytes(bytes: &mut [u8]) {
bytes.copy_from_slice(&wasip2::random::random::get_random_bytes(
u64::try_from(bytes.len()).unwrap(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this unwrap be fully optimised out since we're on a 32bit target?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

));
}

pub fn hashmap_random_keys() -> (u64, u64) {
wasip2::random::insecure_seed::insecure_seed()
}
10 changes: 10 additions & 0 deletions src/bootstrap/src/core/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,16 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
);
}
}

// For testing `wasm32-wasip2`-and-beyond it's required to have
// `wasm-component-ld`. This is enabled by default via `tool_enabled`
// but if it's disabled then double-check it's present on the system.
if target.contains("wasip")
&& !target.contains("wasip1")
&& !build.tool_enabled("wasm-component-ld")
{
cmd_finder.must_have("wasm-component-ld");
}
Comment on lines +401 to +409
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cc @rust-lang/bootstrap in case anybody wants to look at this

}

if let Some(ref s) = build.config.ccache {
Expand Down
6 changes: 5 additions & 1 deletion src/tools/tidy/src/deps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"wit-bindgen",
// tidy-alphabetical-end
];

Expand Down Expand Up @@ -798,7 +799,10 @@ fn check_runtime_no_duplicate_dependencies(metadata: &Metadata, bad: &mut bool)
continue;
}

if !seen_pkgs.insert(&*pkg.name) {
// Skip the `wasi` crate here which the standard library explicitly
// depends on two version of (one for the `wasm32-wasip1` target and
// another for the `wasm32-wasip2` target).
if pkg.name.to_string() != "wasi" && !seen_pkgs.insert(&*pkg.name) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to call out these two changes in particular. Notably the standard library on the wasm32-wasip2 target is picking up a new dependency, wit-bindgen. This is developed at https://github.com/bytecodealliance/wit-bindgen/ and basically follows the same development practices of https://github.com/bytecodealliance/wasi-rs, a preexisting dependency of the standard library.

The "wasi" check here is then to allow duplicate dependencies on the "wasi" crate from the standard library since it's intentional that wasm32-wasip1 depends on 0.11 and wasm32-wasip2 depends on 0.14.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind adding a comment about why wasi is special here?

tidy_error!(
bad,
"duplicate package `{}` is not allowed for the standard library",
Expand Down
3 changes: 2 additions & 1 deletion triagebot.toml
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,8 @@ trigger_files = [

[autolabel."O-wasi"]
trigger_files = [
"library/std/src/sys/pal/wasi",
"library/std/src/sys/pal/wasip1",
"library/std/src/sys/pal/wasip2",
"library/std/src/os/wasi"
]

Expand Down
Loading