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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#[macro_export]
macro_rules! lucet_hostcalls {
{
$(
$(#[$attr:meta])*
pub unsafe extern "C" fn $name:ident(
&mut $vmctx:ident
$(, $arg:ident : $arg_ty:ty )*,
) -> $ret_ty:ty {
$($body:tt)*
}
)*
} => {
$(
$(#[$attr])*
pub unsafe extern "C" fn $name(
vmctx_raw: *mut $crate::vmctx::lucet_vmctx,
$( $arg: $arg_ty ),*
) -> $ret_ty {
#[inline(always)]
unsafe fn hostcall_impl(
$vmctx: &mut $crate::vmctx::Vmctx,
$( $arg : $arg_ty ),*
) -> $ret_ty {
$($body)*
}
#[allow(unused_imports)]
use $crate::vmctx::VmctxInternal;
$crate::vmctx::Vmctx::from_raw(vmctx_raw).instance_mut().uninterruptable(|| {
let res = std::panic::catch_unwind(move || {
hostcall_impl(&mut $crate::vmctx::Vmctx::from_raw(vmctx_raw), $( $arg ),*)
});
match res {
Ok(res) => res,
Err(e) => {
match e.downcast::<$crate::instance::TerminationDetails>() {
Ok(details) => {
let mut vmctx = $crate::vmctx::Vmctx::from_raw(vmctx_raw);
vmctx.terminate_no_unwind(*details)
},
Err(e) => std::panic::resume_unwind(e),
}
}
}
})
}
)*
}
}
#[macro_export]
macro_rules! lucet_hostcall_terminate {
() => {
lucet_hostcall_terminate!("lucet_hostcall_terminate")
};
( $payload:expr ) => {
panic!($crate::instance::TerminationDetails::provide($payload))
};
( $payload:expr, ) => {
lucet_hostcall_terminate!($payload)
};
( $fmt:expr, $($arg:tt)+ ) => {
lucet_hostcall_terminate!(format!($fmt, $($arg),+))
};
}