Skip to content
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b4c0313
Closes #274: Adding FFI functions for bool, float, double, string, ve…
vshailesh Oct 6, 2025
c0e5dfb
Adding Tests for CAPI flatbuffers
vshailesh Oct 6, 2025
1f402f9
Corrected number of arguments in guest function
vshailesh Oct 6, 2025
4a27841
corrected return type in test cases, integration_test.rs
vshailesh Oct 6, 2025
2c1cea0
corrected test case
vshailesh Oct 6, 2025
e66ce6e
corrected test case
vshailesh Oct 6, 2025
cfe2c62
corrected test cases
vshailesh Oct 6, 2025
3c5acec
corrected test cases
vshailesh Oct 6, 2025
ab379d7
corrected test cases
vshailesh Oct 6, 2025
24eb8cc
format fix
vshailesh Oct 6, 2025
da42d0e
removed unnecessary imports
vshailesh Oct 6, 2025
e77c24e
Separate function for creating Uninitialized Sandbox in C-language
vshailesh Oct 7, 2025
4450a0b
resolve import errors
vshailesh Oct 7, 2025
b828616
Bump crate-ci/typos from 1.37.1 to 1.37.2 (#934)
dependabot[bot] Oct 6, 2025
afae3f6
Bump windows-sys from 0.61.1 to 0.61.2 (#939)
dependabot[bot] Oct 7, 2025
9ae84d3
Bump crate-ci/typos from 1.37.2 to 1.38.0 (#938)
dependabot[bot] Oct 7, 2025
a060875
Documentation and integration_test fixes
vshailesh Oct 7, 2025
2deadbb
Bump windows-result from 0.4.0 to 0.4.1 (#942)
dependabot[bot] Oct 8, 2025
6f750ad
Bump windows-version from 0.1.6 to 0.1.7 (#940)
dependabot[bot] Oct 8, 2025
f6eb18f
Bump crate-ci/typos from 1.38.0 to 1.38.1 (#945)
dependabot[bot] Oct 8, 2025
5df0587
Restructure guest/host error handling (#868)
ludfjig Oct 8, 2025
f66d987
Fix join github actions job (#944)
ludfjig Oct 8, 2025
666a14f
Bump wasmparser from 0.239.0 to 0.240.0 (#949)
dependabot[bot] Oct 9, 2025
6ae9059
Bump windows from 0.62.1 to 0.62.2 (#941)
dependabot[bot] Oct 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion src/hyperlight_guest_capi/src/flatbuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ limitations under the License.
*/

use alloc::boxed::Box;
use alloc::ffi::CString;
use alloc::string::String;
use alloc::vec::Vec;
use core::ffi::{CStr, c_char};

use hyperlight_common::flatbuffer_wrappers::util::get_flatbuffer_result;
Expand Down Expand Up @@ -92,6 +95,13 @@ pub extern "C" fn hl_flatbuffer_result_from_Bytes(data: *const u8, len: usize) -
Box::new(unsafe { FfiVec::from_vec(vec) })
}

#[unsafe(no_mangle)]
pub extern "C" fn hl_flatbuffer_result_from_Bool(value: bool) -> Box<FfiVec> {
let vec = get_flatbuffer_result(value);

Box::new(unsafe { FfiVec::from_vec(vec) })
}

//--- Functions for getting values returned by host functions calls

#[unsafe(no_mangle)]
Expand All @@ -115,4 +125,34 @@ pub extern "C" fn hl_get_host_return_value_as_ULong() -> u64 {
get_host_return_value().expect("Unable to get host return value as ulong")
}

// TODO add bool, float, double, string, vecbytes
#[unsafe(no_mangle)]
pub extern "C" fn hl_get_host_return_value_as_Bool() -> bool {
get_host_return_value().expect("Unable to get host return value as bool")
}

#[unsafe(no_mangle)]
pub extern "C" fn hl_get_host_return_value_as_Float() -> f32 {
get_host_return_value().expect("Unable to get host return value as f32")
}

#[unsafe(no_mangle)]
pub extern "C" fn hl_get_host_return_value_as_Double() -> f64 {
get_host_return_value().expect("Unable to get host return value as f64")
}

#[unsafe(no_mangle)]
pub extern "C" fn hl_get_host_return_value_as_String() -> *const c_char {
let string_value: String =
get_host_return_value().expect("Unable to get host return value as string");

let c_string = CString::new(string_value).expect("Failed to create CString");
c_string.into_raw()
}

#[unsafe(no_mangle)]
pub extern "C" fn hl_get_host_return_value_as_VecBytes() -> Box<FfiVec> {
let vec_value: Vec<u8> =
get_host_return_value().expect("Unable to get host return value as vec bytes");

Box::new(unsafe { FfiVec::from_vec(vec_value) })
}
8 changes: 8 additions & 0 deletions src/hyperlight_host/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ pub fn new_uninit_rust() -> Result<UninitializedSandbox> {
)
}

/// Returns a c-language simpleguest.
pub fn new_uninit_c() -> Result<UninitializedSandbox> {
UninitializedSandbox::new(
GuestBinary::FilePath(c_simple_guest_as_string().unwrap()),
None,
)
}

pub fn get_simpleguest_sandboxes(
writer: Option<HostFunction<i32, (String,)>>, // An optional writer to make sure correct info is passed to the host printer
) -> Vec<MultiUseSandbox> {
Expand Down
86 changes: 86 additions & 0 deletions src/hyperlight_host/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,3 +765,89 @@ fn log_test_messages(levelfilter: Option<log::LevelFilter>) {
.unwrap();
}
}

/// Tests whether host is able to return Bool as return type
/// or not
#[test]
fn test_if_guest_is_able_to_get_bool_return_values_from_host() {
let mut sbox1 = new_uninit_c().unwrap();

sbox1
.register("HostBool", |a: i32, b: i32| a + b > 10)
.unwrap();
let mut sbox3 = sbox1.evolve().unwrap();

for i in 1..10 {
if i < 6 {
let res = sbox3
.call::<bool>("GuestRetrievesBoolValue", (i, i))
.unwrap();
println!("{:?}", res);
assert!(matches!(res, false));
} else {
let res = sbox3
.call::<bool>("GuestRetrievesBoolValue", (i, i))
.unwrap();
println!("{:?}", res);
assert!(matches!(res, true));
}
}
}

/// Tests whether host is able to return Float/f32 as return type
/// or not
#[ignore]
#[test]
fn test_if_guest_is_able_to_get_float_return_values_from_host() {
let mut sbox1 = new_uninit_c().unwrap();

sbox1
.register("HostAddFloat", |a: f32, b: f32| a + b)
.unwrap();
let mut sbox3 = sbox1.evolve().unwrap();
let res = sbox3
.call::<f32>("GuestRetrievesFloatValue", (1.34_f32, 1.34_f32))
.unwrap();
println!("{:?}", res);
assert_eq!(res, 2.68_f32);
}

/// Tests whether host is able to return Double/f64 as return type
/// or not
#[ignore]
#[test]
fn test_if_guest_is_able_to_get_double_return_values_from_host() {
let mut sbox1 = new_uninit_c().unwrap();

sbox1
.register("HostAddDouble", |a: f64, b: f64| a + b)
.unwrap();
let mut sbox3 = sbox1.evolve().unwrap();
let res = sbox3
.call::<f64>("GuestRetrievesDoubleValue", (1.34_f64, 1.34_f64))
.unwrap();
println!("{:?}", res);
assert_eq!(res, 2.68_f64);
}

/// Tests whether host is able to return String as return type
/// or not
#[test]
fn test_if_guest_is_able_to_get_string_return_values_from_host() {
let mut sbox1 = new_uninit_c().unwrap();

sbox1
.register("HostAddStrings", |a: String| {
a + ", string added by Host Function"
})
.unwrap();
let mut sbox3 = sbox1.evolve().unwrap();
let res = sbox3
.call::<String>("GuestRetrievesStringValue", ())
.unwrap();
println!("{:?}", res);
assert_eq!(
res,
"Guest Function, string added by Host Function".to_string()
);
}
80 changes: 79 additions & 1 deletion src/tests/c_guests/c_simpleguest/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,80 @@ int guest_function(const char *from_host) {
return 0;
}

bool guest_fn_checks_if_host_returns_bool_value(int32_t a, int32_t b) {
hl_Parameter params[2];

params[0].tag = hl_ParameterType_Int;
params[0].value.Int = a;

params[1].tag = hl_ParameterType_Int;
params[1].value.Int = b;

const hl_FunctionCall host_call = {.function_name = "HostBool",
.parameters = params,
.parameters_len = 2,
.return_type = hl_ReturnType_Bool
};
hl_call_host_function(&host_call);
return hl_get_host_return_value_as_Bool();
}

float guest_fn_checks_if_host_returns_float_value(float a, float b) {
hl_Parameter params[2];

params[0].tag = hl_ParameterType_Float;
params[0].value.Float = a;

params[1].tag = hl_ParameterType_Float;
params[1].value.Float = b;

const hl_FunctionCall host_call = {.function_name = "HostAddFloat",
.parameters = params,
.parameters_len = 2,
.return_type = hl_ReturnType_Float
};
hl_call_host_function(&host_call);
return hl_get_host_return_value_as_Float();
}

double guest_fn_checks_if_host_returns_double_value(double a, double b) {
hl_Parameter params[2];

params[0].tag = hl_ParameterType_Double;
params[0].value.Double = a;

params[1].tag = hl_ParameterType_Double;
params[1].value.Double = b;

const hl_FunctionCall host_call = {.function_name = "HostAddDouble",
.parameters = params,
.parameters_len = 2,
.return_type = hl_ReturnType_Double
};
hl_call_host_function(&host_call);
return hl_get_host_return_value_as_Double();
}

const char* guest_fn_checks_if_host_returns_string_value() {
char guest_message[256] = "Guest Function";
hl_Parameter params;

params.tag = hl_ParameterType_String;
params.value.String = guest_message;

const hl_FunctionCall host_call = {.function_name = "HostAddStrings",
.parameters = &params,
.parameters_len = 1,
.return_type = hl_ReturnType_String
};
hl_call_host_function(&host_call);
return hl_get_host_return_value_as_String();
}

HYPERLIGHT_WRAP_FUNCTION(guest_fn_checks_if_host_returns_float_value, Float, 2, Float, Float)
HYPERLIGHT_WRAP_FUNCTION(guest_fn_checks_if_host_returns_double_value, Double, 2, Double, Double)
HYPERLIGHT_WRAP_FUNCTION(guest_fn_checks_if_host_returns_string_value, String, 0)
HYPERLIGHT_WRAP_FUNCTION(guest_fn_checks_if_host_returns_bool_value, Bool, 2, Int, Int)
HYPERLIGHT_WRAP_FUNCTION(echo, String, 1, String)
// HYPERLIGHT_WRAP_FUNCTION(set_byte_array_to_zero, 1, VecBytes) is not valid for functions that return VecBytes
HYPERLIGHT_WRAP_FUNCTION(guest_function, Int, 1, String)
Expand Down Expand Up @@ -289,6 +363,10 @@ HYPERLIGHT_WRAP_FUNCTION(log_message, Int, 2, String, Long)

void hyperlight_main(void)
{
HYPERLIGHT_REGISTER_FUNCTION("GuestRetrievesFloatValue", guest_fn_checks_if_host_returns_float_value);
HYPERLIGHT_REGISTER_FUNCTION("GuestRetrievesDoubleValue", guest_fn_checks_if_host_returns_double_value);
HYPERLIGHT_REGISTER_FUNCTION("GuestRetrievesStringValue", guest_fn_checks_if_host_returns_string_value);
HYPERLIGHT_REGISTER_FUNCTION("GuestRetrievesBoolValue", guest_fn_checks_if_host_returns_bool_value);
HYPERLIGHT_REGISTER_FUNCTION("Echo", echo);
// HYPERLIGHT_REGISTER_FUNCTION macro does not work for functions that return VecBytes,
// so we use hl_register_function_definition directly
Expand Down Expand Up @@ -338,4 +416,4 @@ hl_Vec *c_guest_dispatch_function(const hl_FunctionCall *function_call) {
}

return NULL;
}
}
Loading