diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs index 6483f0861139b..6f2da15a98d69 100644 --- a/library/std/src/os/linux/raw.rs +++ b/library/std/src/os/linux/raw.rs @@ -31,7 +31,6 @@ pub use self::arch::{blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t}; target_arch = "powerpc", target_arch = "sparc", target_arch = "arm", - target_arch = "wasm32" ))] mod arch { use crate::os::raw::{c_long, c_short, c_uint}; @@ -311,7 +310,9 @@ mod arch { } } -#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] +#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", + // `wasm32-wali-linux-musl` uses ABI similar to x86_64 + target_arch = "wasm32"))] mod arch { use crate::os::raw::{c_int, c_long}; diff --git a/library/std/src/sys/args/mod.rs b/library/std/src/sys/args/mod.rs index fd5562a520b71..2659750f49eff 100644 --- a/library/std/src/sys/args/mod.rs +++ b/library/std/src/sys/args/mod.rs @@ -15,7 +15,7 @@ mod common; cfg_select! { any( - all(target_family = "unix", not(any(target_os = "espidf", target_os = "vita"))), + all(target_family = "unix", not(any(all(target_family = "wasm", target_os = "linux"), target_os = "espidf", target_os = "vita"))), target_os = "hermit", ) => { mod unix; @@ -45,6 +45,10 @@ cfg_select! { mod wasi; pub use wasi::*; } + all(target_family = "wasm", target_os = "linux") => { + mod wali; + pub use wali::*; + } target_os = "xous" => { mod xous; pub use xous::*; diff --git a/library/std/src/sys/args/wali.rs b/library/std/src/sys/args/wali.rs new file mode 100644 index 0000000000000..dc6295a483334 --- /dev/null +++ b/library/std/src/sys/args/wali.rs @@ -0,0 +1,54 @@ +pub use super::common::Args; + +/// One-time global initialization. +pub unsafe fn init(argc: isize, argv: *const *const u8) { + unsafe { imp::init(argc, argv) } +} + +/// Returns the command line arguments +pub fn args() -> Args { + imp::args() +} + +mod imp { + use super::Args; + use crate::ffi::{CString, OsString}; + use crate::os::raw::{c_uint as WaliArgIdx, c_uint}; + use crate::os::unix::prelude::*; + use crate::sync::OnceLock; + + #[link(wasm_import_module = "wali")] + unsafe extern "C" { + pub fn __cl_get_argc() -> WaliArgIdx; + pub fn __cl_get_argv_len(offset: WaliArgIdx) -> c_uint; + pub fn __cl_copy_argv(buf: *mut i8, offset: WaliArgIdx) -> c_uint; + } + + static ARGS: OnceLock> = OnceLock::new(); + + pub unsafe fn init(_argc: isize, _argv: *const *const u8) { + // Uses the WALI arguments API + ARGS.set(argc_argv()).ok(); + } + + unsafe fn load_arg(idx: c_uint) -> OsString { + let arg_len = unsafe { __cl_get_argv_len(idx) }; + let arg_buf = CString::new(vec![b'x'; arg_len as usize]).unwrap(); + let ptr = arg_buf.into_raw(); + let arg_buf = unsafe { + __cl_copy_argv(ptr, idx); + CString::from_raw(ptr) + }; + OsStringExt::from_vec(arg_buf.into_bytes()) + } + + fn argc_argv() -> Vec { + let argc = unsafe { __cl_get_argc() }; + (0..argc).map(|x| unsafe { load_arg(x) }).collect() + } + + pub fn args() -> Args { + let cached = ARGS.get().cloned().unwrap_or_default(); + Args::new(cached) + } +}