|
| 1 | +pub use super::common::Args; |
| 2 | + |
| 3 | +/// One-time global initialization. |
| 4 | +pub unsafe fn init(argc: isize, argv: *const *const u8) { |
| 5 | + unsafe { imp::init(argc, argv) } |
| 6 | +} |
| 7 | + |
| 8 | +/// Returns the command line arguments |
| 9 | +pub fn args() -> Args { |
| 10 | + imp::args() |
| 11 | +} |
| 12 | + |
| 13 | +mod imp { |
| 14 | + use super::Args; |
| 15 | + use crate::ffi::{CString, OsString}; |
| 16 | + use crate::os::raw::{c_uint as WaliArgIdx, c_uint}; |
| 17 | + use crate::os::unix::prelude::*; |
| 18 | + use crate::sync::OnceLock; |
| 19 | + |
| 20 | + #[link(wasm_import_module = "wali")] |
| 21 | + unsafe extern "C" { |
| 22 | + pub fn __cl_get_argc() -> WaliArgIdx; |
| 23 | + pub fn __cl_get_argv_len(offset: WaliArgIdx) -> c_uint; |
| 24 | + pub fn __cl_copy_argv(buf: *mut i8, offset: WaliArgIdx) -> c_uint; |
| 25 | + } |
| 26 | + |
| 27 | + static ARGS: OnceLock<Vec<OsString>> = OnceLock::new(); |
| 28 | + |
| 29 | + pub unsafe fn init(_argc: isize, _argv: *const *const u8) { |
| 30 | + // Uses the WALI arguments API |
| 31 | + ARGS.set(argc_argv()).ok(); |
| 32 | + } |
| 33 | + |
| 34 | + unsafe fn load_arg(idx: c_uint) -> OsString { |
| 35 | + let arg_len = unsafe { __cl_get_argv_len(idx) }; |
| 36 | + let arg_buf = CString::new(vec![b'x'; arg_len as usize]).unwrap(); |
| 37 | + let ptr = arg_buf.into_raw(); |
| 38 | + let arg_buf = unsafe { |
| 39 | + __cl_copy_argv(ptr, idx); |
| 40 | + CString::from_raw(ptr) |
| 41 | + }; |
| 42 | + OsStringExt::from_vec(arg_buf.into_bytes()) |
| 43 | + } |
| 44 | + |
| 45 | + fn argc_argv() -> Vec<OsString> { |
| 46 | + let argc = unsafe { __cl_get_argc() }; |
| 47 | + (0..argc).map(|x| unsafe { load_arg(x) }).collect() |
| 48 | + } |
| 49 | + |
| 50 | + pub fn args() -> Args { |
| 51 | + let cached = ARGS.get().cloned().unwrap_or_default(); |
| 52 | + Args::new(cached) |
| 53 | + } |
| 54 | +} |
0 commit comments