@@ -35,8 +35,7 @@ use crate::hypervisor::{Hypervisor, InterruptHandle};
3535use crate :: mem:: ptr:: RawPtr ;
3636use crate :: mem:: shared_mem:: HostSharedMemory ;
3737use crate :: metrics:: maybe_time_and_emit_guest_call;
38- use crate :: sandbox_state:: sandbox:: { EvolvableSandbox , Sandbox } ;
39- use crate :: sandbox_state:: transition:: MultiUseContextCallback ;
38+ use crate :: sandbox_state:: sandbox:: Sandbox ;
4039use crate :: { HyperlightError , Result } ;
4140
4241/// A sandbox that supports being used Multiple times.
@@ -189,6 +188,26 @@ impl MultiUseSandbox {
189188 } )
190189 }
191190
191+ /// Call a guest function by name, with the given return type and arguments.
192+ /// The changes made to the sandbox are persisted
193+ #[ instrument( err( Debug ) , skip( self , args) , parent = Span :: current( ) ) ]
194+ pub fn persist_call_guest_function_by_name < Output : SupportedReturnType > (
195+ & mut self ,
196+ func_name : & str ,
197+ args : impl ParameterTuple ,
198+ ) -> Result < Output > {
199+ maybe_time_and_emit_guest_call ( func_name, || {
200+ let ret = self . call_guest_function_by_name_no_reset (
201+ func_name,
202+ Output :: TYPE ,
203+ args. into_value ( ) ,
204+ ) ;
205+ let ret = Output :: from_value ( ret?) ;
206+ self . mem_mgr . unwrap_mgr_mut ( ) . push_state ( ) ?;
207+ ret
208+ } )
209+ }
210+
192211 /// This function is kept here for fuzz testing the parameter and return types
193212 #[ cfg( feature = "fuzzing" ) ]
194213 #[ instrument( err( Debug ) , skip( self , args) , parent = Span :: current( ) ) ]
@@ -279,48 +298,16 @@ impl std::fmt::Debug for MultiUseSandbox {
279298 }
280299}
281300
282- impl < ' a , F >
283- EvolvableSandbox <
284- MultiUseSandbox ,
285- MultiUseSandbox ,
286- MultiUseContextCallback < ' a , MultiUseSandbox , F > ,
287- > for MultiUseSandbox
288- where
289- F : FnOnce ( & mut MultiUseGuestCallContext ) -> Result < ( ) > + ' a ,
290- {
291- /// The purpose of this function is to allow multiple states to be associated with a single MultiUseSandbox.
292- ///
293- /// An implementation such as HyperlightJs or HyperlightWasm can use this to call guest functions to load JS or WASM code and then evolve the sandbox causing state to be captured.
294- /// The new MultiUseSandbox can then be used to call guest functions to execute the loaded code.
295- ///
296- /// The evolve function creates a new MultiUseCallContext which is then passed to a callback function allowing the
297- /// callback function to call guest functions as part of the evolve process, once the callback function is complete
298- /// the context is finished using a crate internal method that does not restore the prior state of the Sandbox.
299- /// It then creates a mew memory snapshot on the snapshot stack and returns the MultiUseSandbox
300- #[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) , level = "Trace" ) ]
301- fn evolve (
302- self ,
303- transition_func : MultiUseContextCallback < ' a , MultiUseSandbox , F > ,
304- ) -> Result < MultiUseSandbox > {
305- let mut ctx = self . new_call_context ( ) ;
306- transition_func. call ( & mut ctx) ?;
307- let mut sbox = ctx. finish_no_reset ( ) ;
308- sbox. mem_mgr . unwrap_mgr_mut ( ) . push_state ( ) ?;
309- Ok ( sbox)
310- }
311- }
312-
313301#[ cfg( test) ]
314302mod tests {
315303 use std:: sync:: { Arc , Barrier } ;
316304 use std:: thread;
317305
318306 use hyperlight_testing:: simple_guest_as_string;
319307
320- use crate :: func:: call_ctx:: MultiUseGuestCallContext ;
321308 use crate :: sandbox:: { Callable , SandboxConfiguration } ;
322309 use crate :: sandbox_state:: sandbox:: EvolvableSandbox ;
323- use crate :: sandbox_state:: transition:: { MultiUseContextCallback , Noop } ;
310+ use crate :: sandbox_state:: transition:: Noop ;
324311 use crate :: { GuestBinary , HyperlightError , MultiUseSandbox , Result , UninitializedSandbox } ;
325312
326313 // Tests to ensure that many (1000) function calls can be made in a call context with a small stack (1K) and heap(14K).
@@ -375,18 +362,13 @@ mod tests {
375362
376363 let snapshot = sbox. snapshot ( ) . unwrap ( ) ;
377364
378- let func = Box :: new ( |call_ctx : & mut MultiUseGuestCallContext | {
379- call_ctx. call :: < i32 > ( "AddToStatic" , 5i32 ) ?;
380- Ok ( ( ) )
381- } ) ;
382- let transition_func = MultiUseContextCallback :: from ( func) ;
383- let mut sbox = sbox. evolve ( transition_func) . unwrap ( ) ;
365+ sbox. persist_call_guest_function_by_name :: < i32 > ( "AddToStatic" , 5i32 ) . unwrap ( ) ;
384366
385- let res: i32 = sbox. call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
367+ let res: i32 = sbox. persist_call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
386368 assert_eq ! ( res, 5 ) ;
387369
388370 sbox. restore ( & snapshot) . unwrap ( ) ;
389- let res: i32 = sbox. call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
371+ let res: i32 = sbox. persist_call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
390372 assert_eq ! ( res, 0 ) ;
391373 }
392374
0 commit comments