Skip to content

Commit 2cd054c

Browse files
authored
Unify HostFunctionXX traits into a single HostFunction (#464)
* Unify all the HostFunctionXX traits into a single HostFunction trait Signed-off-by: Jorge Prendes <[email protected]> * Migrate code from HostFunctionXX to HostFunction Signed-off-by: Jorge Prendes <[email protected]> --------- Signed-off-by: Jorge Prendes <[email protected]>
1 parent 3d455ca commit 2cd054c

File tree

9 files changed

+55
-191
lines changed

9 files changed

+55
-191
lines changed

src/hyperlight_host/benches/benchmarks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::time::Duration;
1919

2020
use criterion::{criterion_group, criterion_main, Criterion};
2121
use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterValue, ReturnType};
22-
use hyperlight_host::func::HostFunction2;
22+
use hyperlight_host::func::HostFunction;
2323
use hyperlight_host::sandbox::{MultiUseSandbox, SandboxConfiguration, UninitializedSandbox};
2424
use hyperlight_host::sandbox_state::sandbox::EvolvableSandbox;
2525
use hyperlight_host::sandbox_state::transition::Noop;

src/hyperlight_host/examples/guest-debugging/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::sync::{Arc, Mutex};
1818
use std::thread;
1919

2020
use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterValue, ReturnType};
21-
use hyperlight_host::func::HostFunction0;
21+
use hyperlight_host::func::HostFunction;
2222
#[cfg(gdb)]
2323
use hyperlight_host::sandbox::config::DebugInfo;
2424
use hyperlight_host::sandbox::SandboxConfiguration;

src/hyperlight_host/examples/hello-world/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::sync::{Arc, Mutex};
1818
use std::thread;
1919

2020
use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterValue, ReturnType};
21-
use hyperlight_host::func::HostFunction0;
21+
use hyperlight_host::func::HostFunction;
2222
use hyperlight_host::sandbox_state::sandbox::EvolvableSandbox;
2323
use hyperlight_host::sandbox_state::transition::Noop;
2424
use hyperlight_host::{MultiUseSandbox, UninitializedSandbox};

src/hyperlight_host/src/func/guest_dispatch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ mod tests {
112112

113113
use super::*;
114114
use crate::func::call_ctx::MultiUseGuestCallContext;
115-
use crate::func::host_functions::HostFunction0;
115+
use crate::func::host_functions::HostFunction;
116116
use crate::sandbox::is_hypervisor_present;
117117
use crate::sandbox::uninitialized::GuestBinary;
118118
use crate::sandbox_state::sandbox::EvolvableSandbox;

src/hyperlight_host/src/func/host_functions.rs

Lines changed: 42 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use std::sync::{Arc, Mutex};
2020
use hyperlight_common::flatbuffer_wrappers::function_types::{
2121
ParameterType, ParameterValue, ReturnType,
2222
};
23-
use paste::paste;
2423
use tracing::{instrument, Span};
2524

2625
use super::{HyperlightFunction, SupportedParameterType, SupportedReturnType};
@@ -54,145 +53,35 @@ impl HostFunctionDefinition {
5453
}
5554
}
5655

57-
macro_rules! host_function {
58-
// Special case for zero parameters
59-
(0) => {
60-
paste! {
61-
/// Trait for registering a host function with zero parameters.
62-
pub trait HostFunction0<'a, R: SupportedReturnType<R>> {
63-
/// Register the host function with the given name in the sandbox.
64-
fn register(
65-
&self,
66-
sandbox: &mut UninitializedSandbox,
67-
name: &str,
68-
) -> Result<()>;
69-
70-
/// Register the host function with the given name in the sandbox, allowing extra syscalls.
71-
#[cfg(all(feature = "seccomp", target_os = "linux"))]
72-
fn register_with_extra_allowed_syscalls(
73-
&self,
74-
sandbox: &mut UninitializedSandbox,
75-
name: &str,
76-
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
77-
) -> Result<()>;
78-
}
79-
80-
impl<'a, T, R> HostFunction0<'a, R> for Arc<Mutex<T>>
81-
where
82-
T: FnMut() -> Result<R> + Send + 'static,
83-
R: SupportedReturnType<R>,
84-
{
85-
#[instrument(
86-
err(Debug), skip(self, sandbox), parent = Span::current(), level = "Trace"
87-
)]
88-
fn register(
89-
&self,
90-
sandbox: &mut UninitializedSandbox,
91-
name: &str,
92-
) -> Result<()> {
93-
register_host_function_0(self.clone(), sandbox, name, None)
94-
}
95-
96-
#[cfg(all(feature = "seccomp", target_os = "linux"))]
97-
#[instrument(
98-
err(Debug), skip(self, sandbox, extra_allowed_syscalls),
99-
parent = Span::current(), level = "Trace"
100-
)]
101-
fn register_with_extra_allowed_syscalls(
102-
&self,
103-
sandbox: &mut UninitializedSandbox,
104-
name: &str,
105-
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
106-
) -> Result<()> {
107-
register_host_function_0(self.clone(), sandbox, name, Some(extra_allowed_syscalls))
108-
}
109-
}
110-
111-
fn register_host_function_0<T, R>(
112-
self_: Arc<Mutex<T>>,
113-
sandbox: &mut UninitializedSandbox,
114-
name: &str,
115-
extra_allowed_syscalls: Option<Vec<ExtraAllowedSyscall>>,
116-
) -> Result<()>
117-
where
118-
T: FnMut() -> Result<R> + Send + 'static,
119-
R: SupportedReturnType<R>,
120-
{
121-
let cloned = self_.clone();
122-
let func = Box::new(move |_: Vec<ParameterValue>| {
123-
let result = cloned
124-
.try_lock()
125-
.map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?()?;
126-
Ok(result.get_hyperlight_value())
127-
});
128-
129-
if let Some(_eas) = extra_allowed_syscalls {
130-
if cfg!(all(feature = "seccomp", target_os = "linux")) {
131-
// Register with extra allowed syscalls
132-
#[cfg(all(feature = "seccomp", target_os = "linux"))]
133-
{
134-
sandbox
135-
.host_funcs
136-
.try_lock()
137-
.map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?
138-
.register_host_function_with_syscalls(
139-
&HostFunctionDefinition::new(name.to_string(), None, R::get_hyperlight_type()),
140-
HyperlightFunction::new(func),
141-
_eas,
142-
)?;
143-
}
144-
} else {
145-
// Log and return an error
146-
log_then_return!("Extra allowed syscalls are only supported on Linux with seccomp enabled");
147-
}
148-
} else {
149-
// Register without extra allowed syscalls
150-
sandbox
151-
.host_funcs
152-
.try_lock()
153-
.map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?
154-
.register_host_function(
155-
&HostFunctionDefinition::new(name.to_string(), None, R::get_hyperlight_type()),
156-
HyperlightFunction::new(func),
157-
)?;
158-
}
56+
/// Trait for registering a host function
57+
pub trait HostFunction<R, Args> {
58+
/// Register the host function with the given name in the sandbox.
59+
fn register(&self, sandbox: &mut UninitializedSandbox, name: &str) -> Result<()>;
60+
61+
/// Register the host function with the given name in the sandbox, allowing extra syscalls.
62+
#[cfg(all(feature = "seccomp", target_os = "linux"))]
63+
fn register_with_extra_allowed_syscalls(
64+
&self,
65+
sandbox: &mut UninitializedSandbox,
66+
name: &str,
67+
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
68+
) -> Result<()>;
69+
}
15970

160-
Ok(())
161-
}
162-
}
71+
macro_rules! impl_host_function {
72+
(@count) => { 0 };
73+
(@count $P:ident $(, $R:ident)*) => {
74+
impl_host_function!(@count $($R),*) + 1
16375
};
164-
// General case for one or more parameters
165-
($N:expr, $($P:ident),+) => {
166-
paste! {
167-
/// Trait for registering a host function with $N parameters.
168-
pub trait [<HostFunction $N>]<'a, $($P,)* R>
76+
(@impl $($P:ident),*) => {
77+
const _: () = {
78+
impl<R $(, $P)*, F> HostFunction<R, ($($P,)*)> for Arc<Mutex<F>>
16979
where
170-
$($P: SupportedParameterType<$P> + Clone + 'a,)*
80+
F: FnMut($($P),*) -> Result<R> + Send + 'static,
81+
$($P: SupportedParameterType<$P> + Clone,)*
17182
R: SupportedReturnType<R>,
17283
{
17384
/// Register the host function with the given name in the sandbox.
174-
fn register(
175-
&self,
176-
sandbox: &mut UninitializedSandbox,
177-
name: &str,
178-
) -> Result<()>;
179-
180-
/// Register the host function with the given name in the sandbox, allowing extra syscalls.
181-
#[cfg(all(feature = "seccomp", target_os = "linux"))]
182-
fn register_with_extra_allowed_syscalls(
183-
&self,
184-
sandbox: &mut UninitializedSandbox,
185-
name: &str,
186-
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
187-
) -> Result<()>;
188-
}
189-
190-
impl<'a, T, $($P,)* R> [<HostFunction $N>]<'a, $($P,)* R> for Arc<Mutex<T>>
191-
where
192-
T: FnMut($($P),*) -> Result<R> + Send + 'static,
193-
$($P: SupportedParameterType<$P> + Clone + 'a,)*
194-
R: SupportedReturnType<R>,
195-
{
19685
#[instrument(
19786
err(Debug), skip(self, sandbox), parent = Span::current(), level = "Trace"
19887
)]
@@ -201,9 +90,10 @@ macro_rules! host_function {
20190
sandbox: &mut UninitializedSandbox,
20291
name: &str,
20392
) -> Result<()> {
204-
[<register_host_function_ $N>](self.clone(), sandbox, name, None)
93+
register_host_function(self.clone(), sandbox, name, None)
20594
}
20695

96+
/// Register the host function with the given name in the sandbox, allowing extra syscalls.
20797
#[cfg(all(feature = "seccomp", target_os = "linux"))]
20898
#[instrument(
20999
err(Debug), skip(self, sandbox, extra_allowed_syscalls),
@@ -215,31 +105,28 @@ macro_rules! host_function {
215105
name: &str,
216106
extra_allowed_syscalls: Vec<ExtraAllowedSyscall>,
217107
) -> Result<()> {
218-
[<register_host_function_ $N>](self.clone(), sandbox, name, Some(extra_allowed_syscalls))
108+
register_host_function(self.clone(), sandbox, name, Some(extra_allowed_syscalls))
219109
}
220110
}
221111

222-
fn [<register_host_function_ $N>]<'a, T, $($P,)* R>(
112+
fn register_host_function<T, $($P,)* R>(
223113
self_: Arc<Mutex<T>>,
224114
sandbox: &mut UninitializedSandbox,
225115
name: &str,
226116
extra_allowed_syscalls: Option<Vec<ExtraAllowedSyscall>>,
227117
) -> Result<()>
228118
where
229119
T: FnMut($($P),*) -> Result<R> + Send + 'static,
230-
$($P: SupportedParameterType<$P> + Clone + 'a,)*
120+
$($P: SupportedParameterType<$P> + Clone,)*
231121
R: SupportedReturnType<R>,
232122
{
123+
const N: usize = impl_host_function!(@count $($P),*);
233124
let cloned = self_.clone();
234125
let func = Box::new(move |args: Vec<ParameterValue>| {
235-
if args.len() != $N {
236-
log_then_return!(UnexpectedNoOfArguments(args.len(), $N));
237-
}
238-
239-
let mut args_iter = args.into_iter();
240-
$(
241-
let $P = $P::get_inner(args_iter.next().unwrap())?;
242-
)*
126+
let ($($P,)*) = match <[ParameterValue; N]>::try_from(args) {
127+
Ok([$($P,)*]) => ($($P::get_inner($P)?,)*),
128+
Err(args) => { log_then_return!(UnexpectedNoOfArguments(args.len(), N)); }
129+
};
243130

244131
let result = cloned
245132
.try_lock()
@@ -292,18 +179,15 @@ macro_rules! host_function {
292179

293180
Ok(())
294181
}
295-
}
182+
};
183+
};
184+
() => {
185+
impl_host_function!(@impl);
186+
};
187+
($P:ident $(, $R:ident)*) => {
188+
impl_host_function!($($R),*);
189+
impl_host_function!(@impl $P $(, $R)*);
296190
};
297191
}
298192

299-
host_function!(0);
300-
host_function!(1, P1);
301-
host_function!(2, P1, P2);
302-
host_function!(3, P1, P2, P3);
303-
host_function!(4, P1, P2, P3, P4);
304-
host_function!(5, P1, P2, P3, P4, P5);
305-
host_function!(6, P1, P2, P3, P4, P5, P6);
306-
host_function!(7, P1, P2, P3, P4, P5, P6, P7);
307-
host_function!(8, P1, P2, P3, P4, P5, P6, P7, P8);
308-
host_function!(9, P1, P2, P3, P4, P5, P6, P7, P8, P9);
309-
host_function!(10, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10);
193+
impl_host_function!(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10);

src/hyperlight_host/src/func/mod.rs

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -77,25 +77,5 @@ impl HyperlightFunction {
7777
}
7878
}
7979

80-
/// Re-export for `HostFunction0` trait
81-
pub use host_functions::HostFunction0;
82-
/// Re-export for `HostFunction1` trait
83-
pub use host_functions::HostFunction1;
84-
/// Re-export for `HostFunction10` trait
85-
pub use host_functions::HostFunction10;
86-
/// Re-export for `HostFunction2` trait
87-
pub use host_functions::HostFunction2;
88-
/// Re-export for `HostFunction3` trait
89-
pub use host_functions::HostFunction3;
90-
/// Re-export for `HostFunction4` trait
91-
pub use host_functions::HostFunction4;
92-
/// Re-export for `HostFunction5` trait
93-
pub use host_functions::HostFunction5;
94-
/// Re-export for `HostFunction6` trait
95-
pub use host_functions::HostFunction6;
96-
/// Re-export for `HostFunction7` trait
97-
pub use host_functions::HostFunction7;
98-
/// Re-export for `HostFunction8` trait
99-
pub use host_functions::HostFunction8;
100-
/// Re-export for `HostFunction9` trait
101-
pub use host_functions::HostFunction9;
80+
/// Re-export for `HostFunction` trait
81+
pub use host_functions::HostFunction;

src/hyperlight_host/src/sandbox/uninitialized.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use super::mem_mgr::MemMgrWrapper;
3030
use super::run_options::SandboxRunOptions;
3131
use super::uninitialized_evolve::evolve_impl_multi_use;
3232
use crate::error::HyperlightError::GuestBinaryShouldBeAFile;
33-
use crate::func::host_functions::HostFunction1;
33+
use crate::func::host_functions::HostFunction;
3434
use crate::mem::exe::ExeInfo;
3535
use crate::mem::mgr::{SandboxMemoryManager, STACK_COOKIE_LEN};
3636
use crate::mem::shared_mem::ExclusiveSharedMemory;
@@ -128,7 +128,7 @@ impl UninitializedSandbox {
128128
guest_binary: GuestBinary,
129129
cfg: Option<SandboxConfiguration>,
130130
sandbox_run_options: Option<SandboxRunOptions>,
131-
host_print_writer: Option<&dyn HostFunction1<String, i32>>,
131+
host_print_writer: Option<&dyn HostFunction<i32, (String,)>>,
132132
) -> Result<Self> {
133133
log_build_details();
134134

@@ -355,7 +355,7 @@ mod tests {
355355
use tracing_core::Subscriber;
356356
use uuid::Uuid;
357357

358-
use crate::func::{HostFunction1, HostFunction2};
358+
use crate::func::HostFunction;
359359
use crate::sandbox::uninitialized::GuestBinary;
360360
use crate::sandbox::SandboxConfiguration;
361361
use crate::sandbox_state::sandbox::EvolvableSandbox;

src/hyperlight_host/tests/common/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
use hyperlight_host::func::HostFunction1;
17+
use hyperlight_host::func::HostFunction;
1818
use hyperlight_host::sandbox_state::sandbox::EvolvableSandbox;
1919
use hyperlight_host::sandbox_state::transition::Noop;
2020
use hyperlight_host::{GuestBinary, MultiUseSandbox, Result, UninitializedSandbox};
@@ -46,7 +46,7 @@ pub fn new_uninit_rust() -> Result<UninitializedSandbox> {
4646
}
4747

4848
pub fn get_simpleguest_sandboxes(
49-
writer: Option<&dyn HostFunction1<String, i32>>, // An optional writer to make sure correct info is passed to the host printer
49+
writer: Option<&dyn HostFunction<i32, (String,)>>, // An optional writer to make sure correct info is passed to the host printer
5050
) -> Vec<MultiUseSandbox> {
5151
let elf_path = get_c_or_rust_simpleguest_path();
5252
let exe_path = format!("{elf_path}.exe");
@@ -99,7 +99,7 @@ pub fn get_simpleguest_sandboxes(
9999
}
100100

101101
pub fn get_callbackguest_uninit_sandboxes(
102-
writer: Option<&dyn HostFunction1<String, i32>>, // An optional writer to make sure correct info is passed to the host printer
102+
writer: Option<&dyn HostFunction<i32, (String,)>>, // An optional writer to make sure correct info is passed to the host printer
103103
) -> Vec<UninitializedSandbox> {
104104
let elf_path = get_c_or_rust_callbackguest_path();
105105
let exe_path = format!("{elf_path}.exe");

src/hyperlight_host/tests/sandbox_host_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use core::f64;
1818
use std::sync::{Arc, Mutex};
1919

2020
use common::new_uninit;
21-
use hyperlight_host::func::{HostFunction1, ParameterValue, ReturnType, ReturnValue};
21+
use hyperlight_host::func::{HostFunction, ParameterValue, ReturnType, ReturnValue};
2222
use hyperlight_host::sandbox::SandboxConfiguration;
2323
use hyperlight_host::sandbox_state::sandbox::EvolvableSandbox;
2424
use hyperlight_host::sandbox_state::transition::Noop;

0 commit comments

Comments
 (0)