| 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<Vec<OsString>> = 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<OsString> { | |
| 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) | |
| } | |
| } |