Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
### Fixed

* Guest libc accepts null buffers for zero-length writes.
* Fix calls to guest functions with more than 11 parameters. Registration accepts up to 32, but every call with more than 11 failed.

## [v0.18.0] - 2026-10-13

Expand Down
23 changes: 23 additions & 0 deletions src/hyperlight_common/src/func/param_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,29 @@ macro_rules! impl_supported_param_type {
for_each_param_type!(impl_supported_param_type);

/// A trait to describe the tuple of parameters that a host function can take.
///
/// Functions take at most 32 parameters.
///
/// ```
/// fn takes<T: hyperlight_common::func::ParameterTuple>() {}
/// takes::<(
/// i32, i32, i32, i32, i32, i32, i32, i32,
/// i32, i32, i32, i32, i32, i32, i32, i32,
/// i32, i32, i32, i32, i32, i32, i32, i32,
/// i32, i32, i32, i32, i32, i32, i32, i32,
/// )>();
/// ```
///
/// ```compile_fail
/// fn takes<T: hyperlight_common::func::ParameterTuple>() {}
/// takes::<(
/// i32, i32, i32, i32, i32, i32, i32, i32,
/// i32, i32, i32, i32, i32, i32, i32, i32,
/// i32, i32, i32, i32, i32, i32, i32, i32,
/// i32, i32, i32, i32, i32, i32, i32, i32,
/// i32,
/// )>();
/// ```
pub trait ParameterTuple: Sized + Clone + Send + Sync + 'static {
/// The number of parameters in the tuple
const SIZE: usize;
Expand Down
14 changes: 0 additions & 14 deletions src/hyperlight_guest_bin/src/guest_function/definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,6 @@ impl<F: Copy> GuestFunctionDefinition<F> {

/// Verify that `self` has same signature as the provided `parameter_types`.
pub fn verify_parameters(&self, parameter_types: &[ParameterType]) -> Result<()> {
// Verify that the function does not have more than `MAX_PARAMETERS` parameters.
const MAX_PARAMETERS: usize = 11;
if parameter_types.len() > MAX_PARAMETERS {
return Err(HyperlightGuestError::new(
ErrorCode::GuestError,
format!(
"Function {} has too many parameters: {} (max allowed is {}).",
self.function_name,
parameter_types.len(),
MAX_PARAMETERS
),
));
}

if self.parameter_types.len() != parameter_types.len() {
return Err(HyperlightGuestError::new(
ErrorCode::GuestFunctionIncorrecNoOfParameters,
Expand Down
2 changes: 1 addition & 1 deletion src/hyperlight_guest_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl Parse for NameArg {
///
/// The function arguments must be supported parameter types, and the return type must be
/// a supported return type or a `Result<T, HyperlightGuestError>` with T being a supported
/// return type.
/// return type. Guest functions take at most 32 parameters, the limit `ParameterTuple` sets.
///
/// # Note
/// The function will be registered with the host at program initialization regardless of
Expand Down
20 changes: 19 additions & 1 deletion src/hyperlight_host/tests/sandbox_host_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use hyperlight_testing::simple_guest_as_pathbuf;

pub mod common; // pub to disable dead_code warning
use crate::common::{
with_all_guests, with_all_sandboxes, with_c_sandbox, with_c_sandbox_from,
with_all_guests, with_all_sandboxes, with_c_sandbox, with_c_sandbox_from, with_rust_sandbox,
with_rust_uninit_sandbox, with_rust_uninit_sandbox_cfg,
};

Expand Down Expand Up @@ -200,6 +200,24 @@ fn multiple_parameters() {
});
}

#[test]
fn guest_function_with_thirty_two_parameters() {
with_rust_sandbox(|mut sandbox| {
let sum: i32 = sandbox
.call(
"SumThirtyTwoArgs",
(
1_i32, 2_i32, 3_i32, 4_i32, 5_i32, 6_i32, 7_i32, 8_i32, 9_i32, 10_i32, 11_i32,
12_i32, 13_i32, 14_i32, 15_i32, 16_i32, 17_i32, 18_i32, 19_i32, 20_i32, 21_i32,
22_i32, 23_i32, 24_i32, 25_i32, 26_i32, 27_i32, 28_i32, 29_i32, 30_i32, 31_i32,
32_i32,
),
)
.unwrap();
assert_eq!(sum, (1..=32).sum::<i32>());
});
}

#[test]
fn incorrect_parameter_type() {
with_all_sandboxes(|mut sandbox| {
Expand Down
7 changes: 7 additions & 0 deletions src/tests/rust_guests/simpleguest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,13 @@ fn print_eleven_args(arg1: String, arg2: i32, arg3: i64, arg4: String, arg5: Str
host_print(message)
}

#[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
#[guest_function("SumThirtyTwoArgs")]
fn sum_thirty_two_args(a1: i32, a2: i32, a3: i32, a4: i32, a5: i32, a6: i32, a7: i32, a8: i32, a9: i32, a10: i32, a11: i32, a12: i32, a13: i32, a14: i32, a15: i32, a16: i32, a17: i32, a18: i32, a19: i32, a20: i32, a21: i32, a22: i32, a23: i32, a24: i32, a25: i32, a26: i32, a27: i32, a28: i32, a29: i32, a30: i32, a31: i32, a32: i32) -> i32 {
a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20 + a21 + a22 + a23 + a24 + a25 + a26 + a27 + a28 + a29 + a30 + a31 + a32
}

#[guest_function("BufferOverrun")]
fn buffer_overrun(value: String) -> i32 {
let c_str = value.as_str();
Expand Down
Loading