Skip to content

Commit 5e732c5

Browse files
authored
Fix wasip2 build (RustPython#6935)
1 parent 5997507 commit 5e732c5

7 files changed

Lines changed: 67 additions & 10 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,13 @@ jobs:
257257
- name: Check compilation for freeBSD
258258
run: cargo check --target x86_64-unknown-freebsd ${{ env.CARGO_ARGS_NO_SSL }}
259259

260+
- uses: dtolnay/rust-toolchain@stable
261+
with:
262+
target: wasm32-wasip2
263+
264+
- name: Check compilation for wasip2
265+
run: cargo check --target wasm32-wasip2 ${{ env.CARGO_ARGS_NO_SSL }}
266+
260267
# - name: Prepare repository for redox compilation
261268
# run: bash scripts/redox/uncomment-cargo.sh
262269
# - name: Check compilation for Redox

crates/common/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
//! A crate to hold types and functions common to all rustpython components.
22
3-
#![cfg_attr(all(target_os = "wasi", target_env = "p2"), feature(wasip2))]
4-
53
extern crate alloc;
64

75
#[macro_use]

crates/common/src/os.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,61 @@ pub fn bytes_as_os_str(b: &[u8]) -> Result<&std::ffi::OsStr, Utf8Error> {
9494

9595
#[cfg(unix)]
9696
pub use std::os::unix::ffi;
97-
#[cfg(target_os = "wasi")]
97+
98+
// WASIp1 uses stable std::os::wasi::ffi
99+
#[cfg(all(target_os = "wasi", not(target_env = "p2")))]
98100
pub use std::os::wasi::ffi;
99101

102+
// WASIp2: std::os::wasip2::ffi is unstable, so we provide a stable implementation
103+
// leveraging WASI's UTF-8 string guarantee
104+
#[cfg(all(target_os = "wasi", target_env = "p2"))]
105+
pub mod ffi {
106+
use std::ffi::{OsStr, OsString};
107+
108+
pub trait OsStrExt: sealed::Sealed {
109+
fn as_bytes(&self) -> &[u8];
110+
fn from_bytes(slice: &[u8]) -> &Self;
111+
}
112+
113+
impl OsStrExt for OsStr {
114+
fn as_bytes(&self) -> &[u8] {
115+
// WASI strings are guaranteed to be UTF-8
116+
self.to_str().expect("wasip2 strings are UTF-8").as_bytes()
117+
}
118+
119+
fn from_bytes(slice: &[u8]) -> &OsStr {
120+
// WASI strings are guaranteed to be UTF-8
121+
OsStr::new(std::str::from_utf8(slice).expect("wasip2 strings are UTF-8"))
122+
}
123+
}
124+
125+
pub trait OsStringExt: sealed::Sealed {
126+
fn from_vec(vec: Vec<u8>) -> Self;
127+
fn into_vec(self) -> Vec<u8>;
128+
}
129+
130+
impl OsStringExt for OsString {
131+
fn from_vec(vec: Vec<u8>) -> OsString {
132+
// WASI strings are guaranteed to be UTF-8
133+
OsString::from(String::from_utf8(vec).expect("wasip2 strings are UTF-8"))
134+
}
135+
136+
fn into_vec(self) -> Vec<u8> {
137+
// WASI strings are guaranteed to be UTF-8
138+
self.to_str()
139+
.expect("wasip2 strings are UTF-8")
140+
.as_bytes()
141+
.to_vec()
142+
}
143+
}
144+
145+
mod sealed {
146+
pub trait Sealed {}
147+
impl Sealed for std::ffi::OsStr {}
148+
impl Sealed for std::ffi::OsString {}
149+
}
150+
}
151+
100152
#[cfg(windows)]
101153
pub fn errno_to_winerror(errno: i32) -> i32 {
102154
use libc::*;

crates/stdlib/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// how `mod` works, but we want this sometimes for pymodule declarations
33

44
#![allow(clippy::module_inception)]
5-
#![cfg_attr(all(target_os = "wasi", target_env = "p2"), feature(wasip2))]
65

76
#[macro_use]
87
extern crate rustpython_derive;

crates/stdlib/src/select.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ mod platform {
6161
#[cfg(target_os = "wasi")]
6262
mod platform {
6363
pub use libc::{FD_SETSIZE, timeval};
64-
pub use std::os::wasi::io::RawFd;
64+
pub use std::os::fd::RawFd;
6565

6666
pub fn check_err(x: i32) -> bool {
6767
x < 0

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
//!
4545
//! See [`rustpython_derive`](../rustpython_derive/index.html) crate for documentation on macros used in the example above.
4646
47-
#![cfg_attr(all(target_os = "wasi", target_env = "p2"), feature(wasip2))]
4847
#![allow(clippy::needless_doctest_main)]
4948

5049
#[macro_use]

src/settings.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,10 @@ pub(crate) use env::split_paths;
407407
pub(crate) fn split_paths<T: AsRef<std::ffi::OsStr> + ?Sized>(
408408
s: &T,
409409
) -> impl Iterator<Item = std::path::PathBuf> + '_ {
410-
use std::os::wasi::ffi::OsStrExt;
411-
let s = s.as_ref().as_bytes();
412-
s.split(|b| *b == b':')
413-
.map(|x| std::ffi::OsStr::from_bytes(x).to_owned().into())
410+
let s = s.as_ref().as_encoded_bytes();
411+
s.split(|b| *b == b':').map(|x| {
412+
unsafe { std::ffi::OsStr::from_encoded_bytes_unchecked(x) }
413+
.to_owned()
414+
.into()
415+
})
414416
}

0 commit comments

Comments
 (0)