Skip to content

Commit bd8f60a

Browse files
committed
[library/std pal args]: implemented args for safaos
1 parent 44c9cf2 commit bd8f60a

File tree

2 files changed

+85
-20
lines changed

2 files changed

+85
-20
lines changed
Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,87 @@
1+
use core::cell::SyncUnsafeCell;
2+
use core::ptr::NonNull;
3+
14
use crate::ffi::OsString;
25
use crate::fmt;
6+
use crate::mem::MaybeUninit;
7+
8+
#[derive(Debug, Clone, Copy)]
9+
pub(super) struct RawArgs {
10+
pub(super) args: NonNull<[(NonNull<u8>, usize)]>,
11+
}
12+
13+
impl RawArgs {
14+
fn len(&self) -> usize {
15+
unsafe { (*self.args.as_ptr()).len() }
16+
}
317

4-
pub struct Args {}
18+
fn get(&self, index: usize) -> Option<&'static str> {
19+
unsafe {
20+
let args = &*self.args.as_ptr();
21+
let (ptr, len) = args.get(index)?;
22+
Some(core::str::from_utf8_unchecked(core::slice::from_raw_parts(ptr.as_ptr(), *len)))
23+
}
24+
}
25+
}
26+
27+
unsafe impl Sync for RawArgs {}
28+
29+
pub(super) static RAW_ARGS: SyncUnsafeCell<MaybeUninit<Option<RawArgs>>> =
30+
SyncUnsafeCell::new(MaybeUninit::uninit());
31+
pub struct Args {
32+
raw_args: Option<RawArgs>,
33+
index: usize,
34+
}
535

636
pub fn args() -> Args {
7-
Args {}
37+
Args { raw_args: unsafe { (*RAW_ARGS.get()).assume_init() }, index: 0 }
838
}
939

1040
impl fmt::Debug for Args {
1141
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12-
f.debug_list().finish()
42+
let mut list = f.debug_list();
43+
let len = self.len();
44+
for i in 0..len {
45+
// safe because index is always in len and raw_args is initialized (otherwise len is going to be 0)
46+
let arg = unsafe { self.raw_args.unwrap_unchecked().get(i).unwrap_unchecked() };
47+
list.entry(&arg);
48+
}
49+
list.finish()
1350
}
1451
}
1552

1653
impl Iterator for Args {
1754
type Item = OsString;
1855
fn next(&mut self) -> Option<OsString> {
19-
None
56+
if self.index >= self.len() {
57+
return None;
58+
}
59+
// it is gruanted that the raw_args is initialized if len > 0
60+
let raw_args = unsafe { self.raw_args.unwrap_unchecked() };
61+
let results = raw_args.get(self.index).map(|arg| OsString::from(arg));
62+
self.index += 1;
63+
results
2064
}
2165
fn size_hint(&self) -> (usize, Option<usize>) {
22-
(0, Some(0))
66+
let len = self.len();
67+
68+
if len == 0 {
69+
(0, Some(0))
70+
} else {
71+
let left = len - self.index;
72+
(left, Some(left))
73+
}
2374
}
2475
}
2576

2677
impl ExactSizeIterator for Args {
2778
fn len(&self) -> usize {
28-
0
79+
self.raw_args.map(|s| s.len()).unwrap_or(0)
2980
}
3081
}
3182

3283
impl DoubleEndedIterator for Args {
3384
fn next_back(&mut self) -> Option<OsString> {
34-
None
85+
todo!("next_back on Args is not implemented yet")
3586
}
3687
}
Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,35 @@
1-
use crate::ffi::{c_char, c_int};
2-
use crate::ptr;
1+
use core::ptr::NonNull;
2+
3+
use super::args::RAW_ARGS;
4+
use super::args::RawArgs;
5+
use super::os::exit;
6+
use crate::mem::MaybeUninit;
37

48
extern "C" {
5-
fn main(argc: c_int, argv: *const *const c_char) -> c_int;
9+
fn main() -> u16;
10+
}
11+
12+
unsafe fn _start_inner(argc: usize, argv: *mut (NonNull<u8>, usize)) -> ! {
13+
unsafe {
14+
let raw_args = match argc == 0 || argv.is_null() {
15+
true => None,
16+
false => {
17+
let args_slice = core::slice::from_raw_parts_mut(argv, argc);
18+
let args = NonNull::new_unchecked(args_slice as *mut _);
19+
Some(RawArgs { args })
20+
}
21+
};
22+
23+
RAW_ARGS.get().write(MaybeUninit::new(raw_args));
24+
let results = main();
25+
26+
exit(results as i32)
27+
}
628
}
729

830
#[no_mangle]
931
#[allow(unused)]
10-
pub extern "C" fn _start() {
32+
pub extern "C" fn _start(argc: usize, argv: *mut (NonNull<u8>, usize)) {
1133
unsafe {
1234
core::arch::asm!(
1335
"
@@ -17,14 +39,6 @@ pub extern "C" fn _start() {
1739
",
1840
options(nostack)
1941
);
20-
main(0, ptr::null());
21-
core::arch::asm!(
22-
"
23-
xor rax, rax
24-
xor rdi, rdi
25-
int 0x80
26-
",
27-
options(noreturn)
28-
);
42+
_start_inner(argc, argv);
2943
};
3044
}

0 commit comments

Comments
 (0)