@@ -67,6 +67,7 @@ pub struct MultiUseSandbox {
6767 dispatch_ptr : RawPtr ,
6868 #[ cfg( gdb) ]
6969 dbg_mem_access_fn : DbgMemAccessHandlerWrapper ,
70+ snapshot : Option < Snapshot > ,
7071}
7172
7273impl MultiUseSandbox {
@@ -91,6 +92,7 @@ impl MultiUseSandbox {
9192 dispatch_ptr,
9293 #[ cfg( gdb) ]
9394 dbg_mem_access_fn,
95+ snapshot : None ,
9496 }
9597 }
9698
@@ -104,7 +106,7 @@ impl MultiUseSandbox {
104106 . unwrap_mgr_mut ( )
105107 . snapshot ( self . id , mapped_regions_vec) ?;
106108 Ok ( Snapshot {
107- inner : memory_snapshot,
109+ inner : Arc :: new ( memory_snapshot) ,
108110 } )
109111 }
110112
@@ -133,17 +135,43 @@ impl MultiUseSandbox {
133135 unsafe { self . vm . map_region ( region) ? } ;
134136 }
135137
138+ // The restored snapshot is now our most current snapshot
139+ self . snapshot = Some ( snapshot. clone ( ) ) ;
140+
136141 Ok ( ( ) )
137142 }
138143
139144 /// Call a guest function by name, with the given return type and arguments.
140- /// The changes made to the sandbox are persisted
145+ /// The changes made to the sandbox are **not** persisted
146+ #[ deprecated(
147+ since = "0.8.0" ,
148+ note = "Deprecated in favour or call_guest and snapshot/restore."
149+ ) ]
141150 #[ instrument( err( Debug ) , skip( self , args) , parent = Span :: current( ) ) ]
142151 pub fn call_guest_function_by_name < Output : SupportedReturnType > (
143152 & mut self ,
144153 func_name : & str ,
145154 args : impl ParameterTuple ,
146155 ) -> Result < Output > {
156+ let snapshot = match & self . snapshot {
157+ Some ( snapshot) => snapshot. clone ( ) ,
158+ None => self . snapshot ( ) ?,
159+ } ;
160+ let res = self . run ( func_name, args) ;
161+ self . restore ( & snapshot) ?;
162+ res
163+ }
164+
165+ /// Call a guest function by name, with the given return type and arguments.
166+ /// The changes made to the sandbox are persisted
167+ #[ instrument( err( Debug ) , skip( self , args) , parent = Span :: current( ) ) ]
168+ pub fn run < Output : SupportedReturnType > (
169+ & mut self ,
170+ func_name : & str ,
171+ args : impl ParameterTuple ,
172+ ) -> Result < Output > {
173+ // Reset snapshot since we are mutating the sandbox state
174+ self . snapshot = None ;
147175 maybe_time_and_emit_guest_call ( func_name, || {
148176 let ret = self . call_guest_function_by_name_no_reset (
149177 func_name,
@@ -326,7 +354,7 @@ mod tests {
326354 use crate :: mem:: memory_region:: { MemoryRegion , MemoryRegionFlags , MemoryRegionType } ;
327355 #[ cfg( target_os = "linux" ) ]
328356 use crate :: mem:: shared_mem:: { ExclusiveSharedMemory , GuestSharedMemory , SharedMemory as _} ;
329- use crate :: sandbox:: { Callable , SandboxConfiguration } ;
357+ use crate :: sandbox:: { Callable as _ , SandboxConfiguration } ;
330358 use crate :: { GuestBinary , HyperlightError , MultiUseSandbox , Result , UninitializedSandbox } ;
331359
332360 // Tests to ensure that many (1000) function calls can be made in a call context with a small stack (1K) and heap(14K).
@@ -378,15 +406,13 @@ mod tests {
378406
379407 let snapshot = sbox. snapshot ( ) . unwrap ( ) ;
380408
381- let _ = sbox
382- . call_guest_function_by_name :: < i32 > ( "AddToStatic" , 5i32 )
383- . unwrap ( ) ;
409+ let _ = sbox. run :: < i32 > ( "AddToStatic" , 5i32 ) . unwrap ( ) ;
384410
385- let res: i32 = sbox. call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
411+ let res: i32 = sbox. run ( "GetStatic" , ( ) ) . unwrap ( ) ;
386412 assert_eq ! ( res, 5 ) ;
387413
388414 sbox. restore ( & snapshot) . unwrap ( ) ;
389- let res: i32 = sbox. call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
415+ let res: i32 = sbox. run ( "GetStatic" , ( ) ) . unwrap ( ) ;
390416 assert_eq ! ( res, 0 ) ;
391417 }
392418
0 commit comments