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
#[macro_export]
macro_rules! global {
(
$(
$vs:vis extern $name:ident: $fty:ty = $lib_name:tt$sep:tt$var:tt$([$add:tt])?;
)*
) => {
$(
#[allow(non_upper_case_globals)]
$vs static mut $name: $name = $name {
offset: $crate::__define_offset!($sep $var)
};
#[allow(non_camel_case_types)]
$vs struct $name {
offset: $crate::RuntimeOffset,
}
unsafe impl ::core::marker::Sync for $name { }
impl $name {
#[inline]
$vs unsafe fn get(&self) -> $fty {
std::ptr::read(self.get_ref() as _)
}
#[inline]
$vs unsafe fn get_ref(&self) -> &$fty {
if !self.offset.is_resolved() {
$crate::__expect!(self.offset.try_resolve($lib_name, $crate::__define_offset2!($($add)?)), "Failed to resolve global's address");
}
(self.offset.address() as *const $fty).as_ref().unwrap()
}
#[inline]
$vs unsafe fn get_mut(&mut self) -> &mut $fty {
if !self.offset.is_resolved() {
$crate::__expect!(self.offset.try_resolve($lib_name, $crate::__define_offset2!($($add)?)), "Failed to resolve global's address");
}
(self.offset.address() as *mut $fty).as_mut().unwrap()
}
}
)*
};
}