@@ -12,7 +12,7 @@ use crate::{
1212 } ,
1313 execution_mode:: { metered:: segment_ctx:: SegmentationCtx , MeteredCtx , Segment } ,
1414 interpreter:: {
15- alloc_pre_compute_buf, get_metered_pre_compute_instructions,
15+ alloc_pre_compute_buf, check_termination , get_metered_pre_compute_instructions,
1616 get_metered_pre_compute_max_size, split_pre_compute_buf, PreComputeInstruction ,
1717 } ,
1818 AotError , ExecutionError , ExecutorInventory , MeteredExecutor , StaticProgramError , Streams ,
@@ -341,16 +341,21 @@ where
341341 from_state : VmState < F , GuestMemory > ,
342342 ctx : MeteredCtx ,
343343 ) -> Result < ( Vec < Segment > , VmState < F , GuestMemory > ) , ExecutionError > {
344- let vm_exec_state = VmExecState :: new ( from_state, ctx) ;
345- let vm_exec_state = self . execute_metered_until_suspend ( vm_exec_state) ?;
346- // handle execution error
347- match vm_exec_state. exit_code {
348- Ok ( _) => Ok ( (
349- vm_exec_state. ctx . segmentation_ctx . segments ,
350- vm_exec_state. vm_state ,
351- ) ) ,
352- Err ( e) => Err ( e) ,
344+ let mut exec_state = VmExecState :: new ( from_state, ctx) ;
345+
346+ loop {
347+ exec_state = self . execute_metered_until_suspend ( exec_state) ?;
348+ // The execution has terminated.
349+ if exec_state. exit_code . is_ok ( ) && exec_state. exit_code . as_ref ( ) . unwrap ( ) . is_some ( ) {
350+ break ;
351+ }
352+ if exec_state. exit_code . is_err ( ) {
353+ return Err ( exec_state. exit_code . unwrap_err ( ) ) ;
354+ }
353355 }
356+ check_termination ( exec_state. exit_code ) ?;
357+ let VmExecState { vm_state, ctx, .. } = exec_state;
358+ Ok ( ( ctx. into_segments ( ) , vm_state) )
354359 }
355360
356361 // TODO: implement execute_metered_until_suspend for AOT if needed
0 commit comments