@@ -67,6 +67,7 @@ pub struct MultiUseSandbox {
67
67
dispatch_ptr : RawPtr ,
68
68
#[ cfg( gdb) ]
69
69
dbg_mem_access_fn : DbgMemAccessHandlerWrapper ,
70
+ snapshot : Option < Snapshot > ,
70
71
}
71
72
72
73
impl MultiUseSandbox {
@@ -91,6 +92,7 @@ impl MultiUseSandbox {
91
92
dispatch_ptr,
92
93
#[ cfg( gdb) ]
93
94
dbg_mem_access_fn,
95
+ snapshot : None ,
94
96
}
95
97
}
96
98
@@ -104,7 +106,7 @@ impl MultiUseSandbox {
104
106
. unwrap_mgr_mut ( )
105
107
. snapshot ( self . id , mapped_regions_vec) ?;
106
108
Ok ( Snapshot {
107
- inner : memory_snapshot,
109
+ inner : Arc :: new ( memory_snapshot) ,
108
110
} )
109
111
}
110
112
@@ -133,17 +135,43 @@ impl MultiUseSandbox {
133
135
unsafe { self . vm . map_region ( region) ? } ;
134
136
}
135
137
138
+ // The restored snapshot is now our most current snapshot
139
+ self . snapshot = Some ( snapshot. clone ( ) ) ;
140
+
136
141
Ok ( ( ) )
137
142
}
138
143
139
144
/// 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
+ ) ]
141
150
#[ instrument( err( Debug ) , skip( self , args) , parent = Span :: current( ) ) ]
142
151
pub fn call_guest_function_by_name < Output : SupportedReturnType > (
143
152
& mut self ,
144
153
func_name : & str ,
145
154
args : impl ParameterTuple ,
146
155
) -> 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 ;
147
175
maybe_time_and_emit_guest_call ( func_name, || {
148
176
let ret = self . call_guest_function_by_name_no_reset (
149
177
func_name,
@@ -326,7 +354,7 @@ mod tests {
326
354
use crate :: mem:: memory_region:: { MemoryRegion , MemoryRegionFlags , MemoryRegionType } ;
327
355
#[ cfg( target_os = "linux" ) ]
328
356
use crate :: mem:: shared_mem:: { ExclusiveSharedMemory , GuestSharedMemory , SharedMemory as _} ;
329
- use crate :: sandbox:: { Callable , SandboxConfiguration } ;
357
+ use crate :: sandbox:: { Callable as _ , SandboxConfiguration } ;
330
358
use crate :: { GuestBinary , HyperlightError , MultiUseSandbox , Result , UninitializedSandbox } ;
331
359
332
360
// 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 {
378
406
379
407
let snapshot = sbox. snapshot ( ) . unwrap ( ) ;
380
408
381
- let _ = sbox
382
- . call_guest_function_by_name :: < i32 > ( "AddToStatic" , 5i32 )
383
- . unwrap ( ) ;
409
+ let _ = sbox. run :: < i32 > ( "AddToStatic" , 5i32 ) . unwrap ( ) ;
384
410
385
- let res: i32 = sbox. call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
411
+ let res: i32 = sbox. run ( "GetStatic" , ( ) ) . unwrap ( ) ;
386
412
assert_eq ! ( res, 5 ) ;
387
413
388
414
sbox. restore ( & snapshot) . unwrap ( ) ;
389
- let res: i32 = sbox. call_guest_function_by_name ( "GetStatic" , ( ) ) . unwrap ( ) ;
415
+ let res: i32 = sbox. run ( "GetStatic" , ( ) ) . unwrap ( ) ;
390
416
assert_eq ! ( res, 0 ) ;
391
417
}
392
418
0 commit comments