@@ -251,6 +251,8 @@ pub struct Instance {
251251 /// The value passed back to the guest when resuming a yielded instance.
252252 pub ( crate ) resumed_val : Option < Box < dyn Any + ' static > > ,
253253
254+ hostcall_count : u64 ,
255+
254256 /// `_padding` must be the last member of the structure.
255257 /// This marks where the padding starts to make the structure exactly 4096 bytes long.
256258 /// It is also used to compute the size of the structure up to that point, i.e. without padding.
@@ -533,10 +535,7 @@ impl Instance {
533535 /// This function runs the guest code for the WebAssembly `start` section, and running any guest
534536 /// code is potentially unsafe; see [`Instance::run()`](struct.Instance.html#method.run).
535537 pub fn reset ( & mut self ) -> Result < ( ) , Error > {
536- // temporary heuristic for whether this should happen upon a reset; in the long term we only
537- // want to force an unwind if there are hostcall frames present, which we'll need to track
538- // via the instance
539- if self . ctx . gpr . rsp != 0 {
538+ if self . hostcall_count > 0 {
540539 self . force_unwind ( ) . unwrap ( ) ;
541540 }
542541 self . alloc . reset_heap ( self . module . as_ref ( ) ) ?;
@@ -694,6 +693,14 @@ impl Instance {
694693 self . c_fatal_handler = Some ( handler) ;
695694 }
696695
696+ pub fn begin_hostcall ( & mut self ) {
697+ self . hostcall_count += 1 ;
698+ }
699+
700+ pub fn end_hostcall ( & mut self ) {
701+ self . hostcall_count -= 1 ;
702+ }
703+
697704 #[ inline]
698705 pub fn get_instruction_count ( & self ) -> u64 {
699706 self . get_instance_implicits ( ) . instruction_count
@@ -721,6 +728,7 @@ impl Instance {
721728 signal_handler : Box :: new ( signal_handler_none) as Box < SignalHandler > ,
722729 entrypoint : None ,
723730 resumed_val : None ,
731+ hostcall_count : 0 ,
724732 _padding : ( ) ,
725733 } ;
726734 inst. set_globals_ptr ( globals_ptr) ;
@@ -806,6 +814,10 @@ impl Instance {
806814 let mut args_with_vmctx = vec ! [ Val :: from( self . alloc. slot( ) . heap) ] ;
807815 args_with_vmctx. extend_from_slice ( args) ;
808816
817+ // when preparing a new context for the guest to run, we must have cleaned up any existing
818+ // host call frames on the stack.
819+ assert_eq ! ( self . hostcall_count, 0 ) ;
820+
809821 HOST_CTX . with ( |host_ctx| {
810822 Context :: init (
811823 unsafe { self . alloc . stack_u64_mut ( ) } ,
0 commit comments