forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwali.rs
More file actions
54 lines (45 loc) · 1.54 KB
/
wali.rs
File metadata and controls
54 lines (45 loc) · 1.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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<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)
}
}