Skip to content

Commit d90bcb9

Browse files
committed
Fix wasip2 build
1 parent 0b9c90f commit d90bcb9

5 files changed

Lines changed: 60 additions & 5 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;

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]

0 commit comments

Comments
 (0)