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::{reset_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::<i64, 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 reset_error();
85
86 #[cfg(debug_assertions)]
87 log::trace!("internal_dispatch_function");
88
89 let function_call = try_pop_shared_input_data_into::<FunctionCall>()
90 .expect("Function call deserialization failed");
91
92 let result_vec = call_guest_function(function_call).inspect_err(|e| {
93 set_error(e.kind.clone(), e.message.as_str());
94 })?;
95
96 push_shared_output_data(result_vec)
97}
98
99pub(crate) extern "win64" fn dispatch_function() {
103 let _ = internal_dispatch_function();
104 halt();
105}