@@ -20,7 +20,6 @@ use std::sync::{Arc, Mutex};
20
20
use hyperlight_common:: flatbuffer_wrappers:: function_types:: {
21
21
ParameterType , ParameterValue , ReturnType ,
22
22
} ;
23
- use paste:: paste;
24
23
use tracing:: { instrument, Span } ;
25
24
26
25
use super :: { HyperlightFunction , SupportedParameterType , SupportedReturnType } ;
@@ -54,145 +53,35 @@ impl HostFunctionDefinition {
54
53
}
55
54
}
56
55
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
+ }
159
70
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
163
75
} ;
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 >>
169
79
where
170
- $( $P: SupportedParameterType <$P> + Clone + ' a, ) *
80
+ F : FnMut ( $( $P) ,* ) -> Result <R > + Send + ' static ,
81
+ $( $P: SupportedParameterType <$P> + Clone , ) *
171
82
R : SupportedReturnType <R >,
172
83
{
173
84
/// 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
- {
196
85
#[ instrument(
197
86
err( Debug ) , skip( self , sandbox) , parent = Span :: current( ) , level = "Trace"
198
87
) ]
@@ -201,9 +90,10 @@ macro_rules! host_function {
201
90
sandbox: & mut UninitializedSandbox ,
202
91
name: & str ,
203
92
) -> Result <( ) > {
204
- [ <register_host_function_ $N> ] ( self . clone( ) , sandbox, name, None )
93
+ register_host_function ( self . clone( ) , sandbox, name, None )
205
94
}
206
95
96
+ /// Register the host function with the given name in the sandbox, allowing extra syscalls.
207
97
#[ cfg( all( feature = "seccomp" , target_os = "linux" ) ) ]
208
98
#[ instrument(
209
99
err( Debug ) , skip( self , sandbox, extra_allowed_syscalls) ,
@@ -215,31 +105,28 @@ macro_rules! host_function {
215
105
name: & str ,
216
106
extra_allowed_syscalls: Vec <ExtraAllowedSyscall >,
217
107
) -> 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) )
219
109
}
220
110
}
221
111
222
- fn [ <register_host_function_ $N> ] < ' a , T , $( $P, ) * R >(
112
+ fn register_host_function< T , $( $P, ) * R >(
223
113
self_: Arc <Mutex <T >>,
224
114
sandbox: & mut UninitializedSandbox ,
225
115
name: & str ,
226
116
extra_allowed_syscalls: Option <Vec <ExtraAllowedSyscall >>,
227
117
) -> Result <( ) >
228
118
where
229
119
T : FnMut ( $( $P) ,* ) -> Result <R > + Send + ' static ,
230
- $( $P: SupportedParameterType <$P> + Clone + ' a , ) *
120
+ $( $P: SupportedParameterType <$P> + Clone , ) *
231
121
R : SupportedReturnType <R >,
232
122
{
123
+ const N : usize = impl_host_function!( @count $( $P) ,* ) ;
233
124
let cloned = self_. clone( ) ;
234
125
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
+ } ;
243
130
244
131
let result = cloned
245
132
. try_lock( )
@@ -292,18 +179,15 @@ macro_rules! host_function {
292
179
293
180
Ok ( ( ) )
294
181
}
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) * ) ;
296
190
} ;
297
191
}
298
192
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