hyperlight_guest/
guest_function_call.rs1use alloc::format;
18use alloc::vec::Vec;
19
20use hyperlight_common::flatbuffer_wrappers::function_call::{FunctionCall, FunctionCallType};
21use hyperlight_common::flatbuffer_wrappers::function_types::ParameterType;
22use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
23
24use crate::entrypoint::halt;
25use crate::error::{HyperlightGuestError, Result};
26use crate::guest_error::set_error;
27use crate::shared_input_data::try_pop_shared_input_data_into;
28use crate::shared_output_data::push_shared_output_data;
29use crate::REGISTERED_GUEST_FUNCTIONS;
30
31type GuestFunc = fn(&FunctionCall) -> Result<Vec<u8>>;
32
33pub(crate) fn call_guest_function(function_call: FunctionCall) -> Result<Vec<u8>> {
34 if function_call.function_call_type() != FunctionCallType::Guest {
36 return Err(HyperlightGuestError::new(
37 ErrorCode::GuestError,
38 format!(
39 "Invalid function call type: {:#?}, should be Guest.",
40 function_call.function_call_type()
41 ),
42 ));
43 }
44
45 if let Some(registered_function_definition) =
47 unsafe { REGISTERED_GUEST_FUNCTIONS.get(&function_call.function_name) }
48 {
49 let function_call_parameter_types: Vec<ParameterType> = function_call
50 .parameters
51 .iter()
52 .flatten()
53 .map(|p| p.into())
54 .collect();
55
56 registered_function_definition.verify_parameters(&function_call_parameter_types)?;
58
59 let p_function = unsafe {
60 let function_pointer = registered_function_definition.function_pointer;
61 core::mem::transmute::<usize, GuestFunc>(function_pointer)
62 };
63
64 p_function(&function_call)
65 } else {
66 extern "Rust" {
72 fn guest_dispatch_function(function_call: FunctionCall) -> Result<Vec<u8>>;
73 }
74
75 unsafe { guest_dispatch_function(function_call) }
76 }
77}
78
79#[no_mangle]
82#[inline(never)]
83fn internal_dispatch_function() -> Result<()> {
84 #[cfg(debug_assertions)]
85 log::trace!("internal_dispatch_function");
86
87 let function_call = try_pop_shared_input_data_into::<FunctionCall>()
88 .expect("Function call deserialization failed");
89
90 let result_vec = call_guest_function(function_call).inspect_err(|e| {
91 set_error(e.kind.clone(), e.message.as_str());
92 })?;
93
94 push_shared_output_data(result_vec)
95}
96
97pub(crate) extern "C" fn dispatch_function() {
101 let _ = internal_dispatch_function();
102 halt();
103}