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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use std::cell::Cell;
const CELL: Cell<bool> = Cell::new(false);
thread_local! {
pub static OPTION_ARGS: [Cell<bool>; 256] = [CELL; 256];
pub static OPTION_RETURN: Cell<bool> = CELL;
}
use self::macro_::impl_ffi_optional;
#[doc(hidden)]
pub trait FfiOptional {
fn unused_value() -> Self;
}
impl_ffi_optional!(u8, 123);
impl_ffi_optional!(u16, 123);
impl_ffi_optional!(u32, 123);
impl_ffi_optional!(u64, 123);
impl_ffi_optional!(usize, 123);
impl_ffi_optional!(i8, 123);
impl_ffi_optional!(i16, 123);
impl_ffi_optional!(i32, 123);
impl_ffi_optional!(i64, 123);
impl_ffi_optional!(isize, 123);
impl_ffi_optional!(bool, false);
#[doc(hidden)]
#[no_mangle]
pub extern "C" fn _get_option_arg(idx: u8) -> bool {
OPTION_ARGS.with(|o| o[idx as usize].get())
}
#[doc(hidden)]
#[no_mangle]
pub extern "C" fn _set_option_arg(idx: u8, bool: bool) {
OPTION_ARGS.with(|o| o[idx as usize].set(bool));
}
#[doc(hidden)]
#[no_mangle]
pub extern "C" fn _get_option_return() -> bool {
OPTION_RETURN.with(|o| o.get())
}
#[no_mangle]
#[doc(hidden)]
pub extern "C" fn _set_option_return(bool: bool) {
OPTION_RETURN.with(|o| o.set(bool));
}
mod macro_ {
macro_rules! impl_ffi_optional {
($ty:ty, $val:expr) => {
impl FfiOptional for $ty {
fn unused_value() -> Self {
$val
}
}
};
}
pub(super) use impl_ffi_optional;
}