hyperlight_guest_bin/
host_comm.rs1use alloc::string::{String, ToString};
18use alloc::vec::Vec;
19use core::ffi::{CStr, c_char};
20use core::mem;
21
22use hyperlight_common::flatbuffer_wrappers::function_call::FunctionCall;
23use hyperlight_common::flatbuffer_wrappers::function_types::{
24 ParameterValue, ReturnType, ReturnValue,
25};
26use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
27use hyperlight_common::flatbuffer_wrappers::util::get_flatbuffer_result;
28use hyperlight_common::func::{ParameterTuple, SupportedReturnType};
29use hyperlight_guest::error::{HyperlightGuestError, Result};
30
31const BUFFER_SIZE: usize = 1000;
32static mut MESSAGE_BUFFER: Vec<u8> = Vec::new();
33
34use crate::GUEST_HANDLE;
35
36pub fn call_host_function<T>(
37 function_name: &str,
38 parameters: Option<Vec<ParameterValue>>,
39 return_type: ReturnType,
40) -> Result<T>
41where
42 T: TryFrom<ReturnValue>,
43{
44 let handle = unsafe { GUEST_HANDLE };
45 handle.call_host_function::<T>(function_name, parameters, return_type)
46}
47
48pub fn call_host<T>(function_name: impl AsRef<str>, args: impl ParameterTuple) -> Result<T>
49where
50 T: SupportedReturnType + TryFrom<ReturnValue>,
51{
52 call_host_function::<T>(function_name.as_ref(), Some(args.into_value()), T::TYPE)
53}
54
55pub fn call_host_function_without_returning_result(
56 function_name: &str,
57 parameters: Option<Vec<ParameterValue>>,
58 return_type: ReturnType,
59) -> Result<()> {
60 let handle = unsafe { GUEST_HANDLE };
61 handle.call_host_function_without_returning_result(function_name, parameters, return_type)
62}
63
64pub fn get_host_return_value_raw() -> Result<ReturnValue> {
65 let handle = unsafe { GUEST_HANDLE };
66 handle.get_host_return_raw()
67}
68
69pub fn get_host_return_value<T: TryFrom<ReturnValue>>() -> Result<T> {
70 let handle = unsafe { GUEST_HANDLE };
71 handle.get_host_return_value::<T>()
72}
73
74pub fn read_n_bytes_from_user_memory(num: u64) -> Result<Vec<u8>> {
75 let handle = unsafe { GUEST_HANDLE };
76 handle.read_n_bytes_from_user_memory(num)
77}
78
79pub fn print_output_with_host_print(function_call: FunctionCall) -> Result<Vec<u8>> {
84 let handle = unsafe { GUEST_HANDLE };
85 if let ParameterValue::String(message) = function_call.parameters.unwrap().remove(0) {
86 let res = handle.call_host_function::<i32>(
87 "HostPrint",
88 Some(Vec::from(&[ParameterValue::String(message)])),
89 ReturnType::Int,
90 )?;
91
92 Ok(get_flatbuffer_result(res))
93 } else {
94 Err(HyperlightGuestError::new(
95 ErrorCode::GuestError,
96 "Wrong Parameters passed to print_output_with_host_print".to_string(),
97 ))
98 }
99}
100
101#[unsafe(no_mangle)]
106#[allow(static_mut_refs)]
107pub unsafe extern "C" fn _putchar(c: c_char) {
108 let handle = unsafe { GUEST_HANDLE };
109 let char = c as u8;
110 let message_buffer = unsafe { &mut MESSAGE_BUFFER };
111
112 if message_buffer.capacity() == 0 {
115 message_buffer.reserve(BUFFER_SIZE);
116 }
117
118 message_buffer.push(char);
119
120 if message_buffer.len() == BUFFER_SIZE || char == b'\0' {
121 let str = if char == b'\0' {
122 CStr::from_bytes_until_nul(message_buffer)
123 .expect("No null byte in buffer")
124 .to_string_lossy()
125 .into_owned()
126 } else {
127 String::from_utf8(mem::take(message_buffer))
128 .expect("Failed to convert buffer to string")
129 };
130
131 let _ = handle
133 .call_host_function::<i32>(
134 "HostPrint",
135 Some(Vec::from(&[ParameterValue::String(str)])),
136 ReturnType::Int,
137 )
138 .expect("Failed to call HostPrint");
139
140 message_buffer.clear();
142 }
143}