lucet_runtime_internals/hostcall_macros.rs
1/// The macro that surrounds definitions of Lucet hostcalls in Rust.
2///
3/// **Note:** this macro has been deprecated and replaced by the `#[lucet_hostcall]` attribute.
4///
5/// It is important to use this macro for hostcalls, rather than exporting them directly, as it
6/// installs unwind protection that prevents panics from unwinding into the guest stack.
7///
8/// Since this is not a proc macro, the syntax is unfortunately fairly brittle. The functions it
9/// encloses must be of the form:
10///
11/// ```ignore
12/// #[$attr1]
13/// #[$attr2]
14/// ... // any number of attributes are supported; in most cases you will want `#[no_mangle]`
15/// pub unsafe extern "C" fn $name( // must be `pub unsafe extern "C"`
16/// &mut $vmctx,
17/// $arg1: $arg1_ty,
18/// $arg2: $arg2_ty,
19/// ... , // trailing comma must always be present
20/// ) -> $ret_ty { // return type must always be present even if it is `()`
21/// // body
22/// }
23/// ```
24#[macro_export]
25#[deprecated(since = "0.5.0", note = "Use the #[lucet_hostcall] attribute instead")]
26macro_rules! lucet_hostcalls {
27 {
28 $(
29 $(#[$attr:meta])*
30 pub unsafe extern "C" fn $name:ident(
31 &mut $vmctx:ident
32 $(, $arg:ident : $arg_ty:ty )*,
33 ) -> $ret_ty:ty {
34 $($body:tt)*
35 }
36 )*
37 } => {
38 $(
39 #[allow(unused_mut)]
40 #[allow(unused_unsafe)]
41 #[$crate::lucet_hostcall]
42 $(#[$attr])*
43 pub unsafe extern "C" fn $name(
44 $vmctx: &mut lucet_runtime::vmctx::Vmctx,
45 $( $arg: $arg_ty ),*
46 ) -> $ret_ty {
47 $($body)*
48 }
49 )*
50 }
51}
52
53/// Terminate an instance from within a hostcall, returning an optional value as an error.
54///
55/// Use this instead of `panic!` when you want the instance to terminate, but not the entire host
56/// program. Like `panic!`, you can pass a format string with arguments, a value that implements
57/// `Any`, or nothing to return a default message.
58///
59/// Upon termination, the call to `Instance::run()` will return with an
60/// `Err(Error::RuntimeTerminated)` value containing the value you pass to this macro.
61///
62/// This macro safely unwinds the hostcall stack out to the entrypoint of the hostcall, so any
63/// resources that may have been acquired will be properly dropped.
64#[macro_export]
65macro_rules! lucet_hostcall_terminate {
66 () => {
67 lucet_hostcall_terminate!("lucet_hostcall_terminate")
68 };
69 ( $payload:expr ) => {
70 panic!($crate::instance::TerminationDetails::provide($payload))
71 };
72 ( $payload:expr, ) => {
73 lucet_hostcall_terminate!($payload)
74 };
75 ( $fmt:expr, $($arg:tt)+ ) => {
76 lucet_hostcall_terminate!(format!($fmt, $($arg),+))
77 };
78}