@@ -43,8 +43,7 @@ use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
4343use crate :: mem:: ptr:: RawPtr ;
4444use crate :: mem:: shared_mem:: HostSharedMemory ;
4545use crate :: metrics:: maybe_time_and_emit_guest_call;
46- use crate :: sandbox_state:: sandbox:: { EvolvableSandbox , Sandbox } ;
47- use crate :: sandbox_state:: transition:: MultiUseContextCallback ;
46+ use crate :: sandbox_state:: sandbox:: Sandbox ;
4847use crate :: { HyperlightError , Result , log_then_return} ;
4948
5049/// A sandbox that supports being used Multiple times.
@@ -199,6 +198,26 @@ impl MultiUseSandbox {
199198 } )
200199 }
201200
201+ /// Call a guest function by name, with the given return type and arguments.
202+ /// The changes made to the sandbox are persisted
203+ #[ instrument( err( Debug ) , skip( self , args) , parent = Span :: current( ) ) ]
204+ pub fn persist_call_guest_function_by_name < Output : SupportedReturnType > (
205+ & mut self ,
206+ func_name : & str ,
207+ args : impl ParameterTuple ,
208+ ) -> Result < Output > {
209+ maybe_time_and_emit_guest_call ( func_name, || {
210+ let ret = self . call_guest_function_by_name_no_reset (
211+ func_name,
212+ Output :: TYPE ,
213+ args. into_value ( ) ,
214+ ) ;
215+ let ret = Output :: from_value ( ret?) ;
216+ self . mem_mgr . unwrap_mgr_mut ( ) . push_state ( ) ?;
217+ ret
218+ } )
219+ }
220+
202221 /// Map a region of host memory into the sandbox.
203222 ///
204223 /// Depending on the host platform, there are likely alignment
@@ -360,52 +379,20 @@ impl std::fmt::Debug for MultiUseSandbox {
360379 }
361380}
362381
363- impl < ' a , F >
364- EvolvableSandbox <
365- MultiUseSandbox ,
366- MultiUseSandbox ,
367- MultiUseContextCallback < ' a , MultiUseSandbox , F > ,
368- > for MultiUseSandbox
369- where
370- F : FnOnce ( & mut MultiUseGuestCallContext ) -> Result < ( ) > + ' a ,
371- {
372- /// The purpose of this function is to allow multiple states to be associated with a single MultiUseSandbox.
373- ///
374- /// 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.
375- /// The new MultiUseSandbox can then be used to call guest functions to execute the loaded code.
376- ///
377- /// The evolve function creates a new MultiUseCallContext which is then passed to a callback function allowing the
378- /// callback function to call guest functions as part of the evolve process, once the callback function is complete
379- /// the context is finished using a crate internal method that does not restore the prior state of the Sandbox.
380- /// It then creates a mew memory snapshot on the snapshot stack and returns the MultiUseSandbox
381- #[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) , level = "Trace" ) ]
382- fn evolve (
383- self ,
384- transition_func : MultiUseContextCallback < ' a , MultiUseSandbox , F > ,
385- ) -> Result < MultiUseSandbox > {
386- let mut ctx = self . new_call_context ( ) ;
387- transition_func. call ( & mut ctx) ?;
388- let mut sbox = ctx. finish_no_reset ( ) ;
389- sbox. mem_mgr . unwrap_mgr_mut ( ) . push_state ( ) ?;
390- Ok ( sbox)
391- }
392- }
393-
394382#[ cfg( test) ]
395383mod tests {
396384 use std:: sync:: { Arc , Barrier } ;
397385 use std:: thread;
398386
399387 use hyperlight_testing:: simple_guest_as_string;
400388
401- use crate :: func:: call_ctx:: MultiUseGuestCallContext ;
402389 #[ cfg( target_os = "linux" ) ]
403390 use crate :: mem:: memory_region:: { MemoryRegion , MemoryRegionFlags , MemoryRegionType } ;
404391 #[ cfg( target_os = "linux" ) ]
405392 use crate :: mem:: shared_mem:: { ExclusiveSharedMemory , GuestSharedMemory , SharedMemory as _} ;
406393 use crate :: sandbox:: { Callable , SandboxConfiguration } ;
407394 use crate :: sandbox_state:: sandbox:: EvolvableSandbox ;
408- use crate :: sandbox_state:: transition:: { MultiUseContextCallback , Noop } ;
395+ use crate :: sandbox_state:: transition:: Noop ;
409396 use crate :: { GuestBinary , HyperlightError , MultiUseSandbox , Result , UninitializedSandbox } ;
410397
411398 // Tests to ensure that many (1000) function calls can be made in a call context with a small stack (1K) and heap(14K).
@@ -460,18 +447,13 @@ mod tests {
460447
461448 let snapshot = sbox. snapshot ( ) . unwrap ( ) ;
462449
463- let func = Box :: new ( |call_ctx : & mut MultiUseGuestCallContext | {
464- call_ctx. call :: < i32 > ( "AddToStatic" , 5i32 ) ?;
465- Ok ( ( ) )
466- } ) ;
467- let transition_func = MultiUseContextCallback :: from ( func) ;
468- let mut sbox = sbox. evolve ( transition_func) . unwrap ( ) ;
450+ let _ = sbox. persist_call_guest_function_by_name :: < i32 > ( "AddToStatic" , 5i32 ) . unwrap ( ) ;
469451
470- let res: i32 = sbox. call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
452+ let res: i32 = sbox. persist_call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
471453 assert_eq ! ( res, 5 ) ;
472454
473455 sbox. restore ( & snapshot) . unwrap ( ) ;
474- let res: i32 = sbox. call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
456+ let res: i32 = sbox. persist_call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
475457 assert_eq ! ( res, 0 ) ;
476458 }
477459
0 commit comments