@@ -20,7 +20,6 @@ use std::sync::{Arc, Mutex};
2020use hyperlight_common:: flatbuffer_wrappers:: function_types:: {
2121 ParameterType , ParameterValue , ReturnType ,
2222} ;
23- use paste:: paste;
2423use tracing:: { instrument, Span } ;
2524
2625use 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 ) ;
0 commit comments