@@ -189,21 +189,19 @@ where
189189 }
190190 }
191191
192+ pub fn pc_out_of_bounds_err ( & self , pc : u32 ) -> ExecutionError {
193+ ExecutionError :: PcOutOfBounds {
194+ pc,
195+ pc_base : self . pc_base ,
196+ program_len : self . pre_compute_insns . len ( ) ,
197+ }
198+ }
199+
192200 #[ cfg( feature = "tco" ) ]
193201 #[ inline( always) ]
194- pub fn get_handler ( & self , pc : u32 ) -> Result < Handler < F , Ctx > , ExecutionError > {
202+ pub fn get_handler ( & self , pc : u32 ) -> Option < Handler < F , Ctx > > {
195203 let pc_idx = get_pc_index ( self . pc_base , pc) ;
196- if std:: hint:: unlikely ( pc_idx >= self . handlers . len ( ) ) {
197- return Err ( ExecutionError :: PcOutOfBounds {
198- pc,
199- pc_base : self . pc_base ,
200- program_len : self . handlers . len ( ) ,
201- } ) ;
202- }
203- // SAFETY:
204- // - we checked above that pc_idx is within bounds
205- let handler = unsafe { self . handlers . get_unchecked ( pc_idx) } ;
206- Ok ( * handler)
204+ self . handlers . get ( pc_idx) . map ( |x| * x)
207205 }
208206}
209207
@@ -302,15 +300,21 @@ where
302300 }
303301 #[ cfg( feature = "tco" ) ]
304302 unsafe {
305- let handler = self . get_handler ( exec_state. pc ) ?;
306- let res = handler ( self , & mut exec_state) ;
307- if let Err ( err) = res {
308- match err {
309- ExecutionError :: ExecStateError => { }
310- _ => {
311- return Err ( err) ;
312- }
313- }
303+ let handler = self
304+ . get_handler ( exec_state. pc )
305+ . ok_or ( ExecutionError :: PcOutOfBounds {
306+ pc : exec_state. pc ,
307+ pc_base : self . pc_base ,
308+ program_len : self . handlers . len ( ) ,
309+ } ) ?;
310+ handler ( self , & mut exec_state) ;
311+
312+ if exec_state
313+ . exit_code
314+ . as_ref ( )
315+ . is_ok_and ( |exit_code| exit_code. is_some ( ) )
316+ {
317+ ExecutionCtx :: on_terminate ( & mut exec_state) ;
314318 }
315319 }
316320
@@ -540,17 +544,16 @@ unsafe fn terminate_execute_e12_impl<F: PrimeField32, CTX: ExecutionCtxTrait>(
540544unsafe fn terminate_execute_e12_tco_handler < F : PrimeField32 , CTX : ExecutionCtxTrait > (
541545 interpreter : & InterpretedInstance < F , CTX > ,
542546 vm_state : & mut VmExecState < F , GuestMemory , CTX > ,
543- ) -> Result < ( ) , ExecutionError > {
547+ ) {
544548 let pre_compute = interpreter. get_pre_compute ( vm_state. pc ) ;
545549 terminate_execute_e12_impl ( pre_compute, vm_state) ;
546- Ok ( ( ) )
547550}
548551#[ cfg( feature = "tco" ) ]
549552unsafe fn unreachable_tco_handler < F : PrimeField32 , CTX > (
550553 _: & InterpretedInstance < F , CTX > ,
551554 vm_state : & mut VmExecState < F , GuestMemory , CTX > ,
552- ) -> Result < ( ) , ExecutionError > {
553- Err ( ExecutionError :: Unreachable ( vm_state. pc ) )
555+ ) {
556+ vm_state . exit_code = Err ( ExecutionError :: Unreachable ( vm_state. pc ) ) ;
554557}
555558
556559fn get_pre_compute_max_size < F , E : Executor < F > > (
0 commit comments