From a1c5893176e25a56cdbcd8f60f2513d387a85996 Mon Sep 17 00:00:00 2001 From: Arjun Ramesh Date: Fri, 1 May 2026 16:29:04 -0400 Subject: [PATCH 1/3] Added std library support for WALI command-line arguments. --- library/std/src/os/linux/raw.rs | 5 +-- library/std/src/sys/args/mod.rs | 6 +++- library/std/src/sys/args/wali.rs | 56 ++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 library/std/src/sys/args/wali.rs 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..8bd835c08d7c1 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(target_family = "wasm", 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..36455d4821554 --- /dev/null +++ b/library/std/src/sys/args/wali.rs @@ -0,0 +1,56 @@ +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) + }; + let mut arg_buf = arg_buf.into_bytes_with_nul(); + let _ = arg_buf.pop(); + OsStringExt::from_vec(arg_buf) + } + + 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) + } +} From f4e1b2f3e89b49bfd92a6c7c4d24a8ee35ff6a91 Mon Sep 17 00:00:00 2001 From: Arjun Ramesh Date: Mon, 4 May 2026 08:34:11 -0400 Subject: [PATCH 2/3] Use `into_bytes` directly --- library/std/src/sys/args/wali.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/std/src/sys/args/wali.rs b/library/std/src/sys/args/wali.rs index 36455d4821554..dc6295a483334 100644 --- a/library/std/src/sys/args/wali.rs +++ b/library/std/src/sys/args/wali.rs @@ -39,9 +39,7 @@ mod imp { __cl_copy_argv(ptr, idx); CString::from_raw(ptr) }; - let mut arg_buf = arg_buf.into_bytes_with_nul(); - let _ = arg_buf.pop(); - OsStringExt::from_vec(arg_buf) + OsStringExt::from_vec(arg_buf.into_bytes()) } fn argc_argv() -> Vec { From 9ef7541f7c7d377092d052ee19de0fda8f1504de Mon Sep 17 00:00:00 2001 From: Arjun Ramesh Date: Mon, 4 May 2026 13:43:56 -0400 Subject: [PATCH 3/3] Restrict cfg gating on unix to not interfere with emscripten target --- library/std/src/sys/args/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/args/mod.rs b/library/std/src/sys/args/mod.rs index 8bd835c08d7c1..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_family = "wasm", 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;