@@ -3,7 +3,8 @@ use super::*;
33struct Unbudgeted ;
44struct Bounded ;
55
6- type UnbudgetedHandler = for <' store > fn ( & mut Executor < ' store > , usize , Instruction ) -> ExecResult < ( ) > ;
6+ type UnbudgetedHandler =
7+ for <' store > fn ( & mut Executor < ' store > , & [ Instruction ] , FuncAddr , usize , Instruction ) -> ExecResult < ( ) > ;
78type BoundedHandler = for <' store > fn ( & mut Executor < ' store > , usize , Instruction , u32 ) -> ExecResult < ( ) > ;
89
910#[ cold]
@@ -29,22 +30,30 @@ macro_rules! define_unbudgeted_tail_dispatch {
2930 #[ allow( non_snake_case, unreachable_code, unused_imports, unused_macros, unused_variables) ]
3031 fn $variant(
3132 $executor: & mut Executor <' _>,
33+ instructions: & [ Instruction ] ,
34+ func_addr: FuncAddr ,
3235 $instr_ptr: usize ,
3336 instruction: Instruction ,
3437 ) -> ExecResult <( ) > {
3538 macro_rules! $dispatch_next {
3639 ( $next_instr_ptr: expr) => { {
3740 let next_instr_ptr = $next_instr_ptr;
38- let instruction = $executor . func . instructions[ next_instr_ptr] ;
41+ let instruction = instructions[ next_instr_ptr] ;
3942 let handler = Self :: handler_for( instruction. opcode( ) ) ;
40- become handler( $executor, next_instr_ptr, instruction) ;
43+ become handler( $executor, instructions , func_addr , next_instr_ptr, instruction) ;
4144 } } ;
4245 }
4346 macro_rules! $dispatch_flow {
4447 ( $flow: expr) => { {
4548 match $flow. next_instr_ptr( ) {
46- Some ( next_instr_ptr) => $dispatch_next!( next_instr_ptr) ,
47- None => return cold!( Ok ( ( ) ) ) ,
49+ Some ( next_instr_ptr) => {
50+ if $executor. cf. func_addr != func_addr {
51+ $executor. cf. instr_ptr = next_instr_ptr;
52+ return Ok ( ( ) ) ;
53+ }
54+ $dispatch_next!( next_instr_ptr)
55+ } ,
56+ None => return cold!( { $executor. completed = true ; Ok ( ( ) ) } ) ,
4857 }
4958 } } ;
5059 }
@@ -142,10 +151,18 @@ impl Bounded {
142151impl < ' store > Executor < ' store > {
143152 #[ inline( always) ]
144153 pub ( crate ) fn run_to_completion ( mut self ) -> Result < ( ) > {
145- let instr_ptr = self . cf . instr_ptr ;
146- let instruction = self . func . instructions [ instr_ptr] ;
147- let handler = Unbudgeted :: handler_for ( instruction. opcode ( ) ) ;
148- Ok ( handler ( & mut self , instr_ptr, instruction) ?)
154+ loop {
155+ let func = self . func . clone ( ) ;
156+ let instructions = & func. instructions ;
157+ let func_addr = self . cf . func_addr ;
158+ let instr_ptr = self . cf . instr_ptr ;
159+ let instruction = instructions[ instr_ptr] ;
160+ let handler = Unbudgeted :: handler_for ( instruction. opcode ( ) ) ;
161+ handler ( & mut self , instructions, func_addr, instr_ptr, instruction) ?;
162+ if self . completed {
163+ return Ok ( ( ) ) ;
164+ }
165+ }
149166 }
150167
151168 #[ cfg( feature = "std" ) ]
0 commit comments