@@ -15,12 +15,14 @@ fn instruction_handler_mismatch() -> ! {
1515macro_rules! define_unbudgeted_tail_dispatch {
1616 ( $executor: ident, $instr_ptr: ident, $dispatch_next: ident, $dispatch_flow: ident;
1717 $( $variant: ident $( ( $( $arg: pat) ,* ) ) ? $( { $( $field: ident) ,* } ) ? => $body: expr) ,* $( , ) ?) => {
18- fn handler_for( instruction: & Instruction ) -> UnbudgetedHandler {
19- use tinywasm_types:: Instruction :: * ;
20-
21- match instruction {
22- $( $variant { .. } => Self :: $variant, ) *
23- }
18+ #[ inline( always) ]
19+ fn handler_for( opcode: InstructionOpcode ) -> UnbudgetedHandler {
20+ static HANDLERS : [ UnbudgetedHandler ; InstructionOpcode :: COUNT ] = {
21+ let mut handlers = [ Unbudgeted :: Unreachable as UnbudgetedHandler ; InstructionOpcode :: COUNT ] ;
22+ $( handlers[ InstructionOpcode :: $variant as usize ] = Unbudgeted :: $variant; ) *
23+ handlers
24+ } ;
25+ HANDLERS [ opcode as usize ]
2426 }
2527
2628 $(
@@ -34,7 +36,7 @@ macro_rules! define_unbudgeted_tail_dispatch {
3436 ( $next_instr_ptr: expr) => { {
3537 let next_instr_ptr = $next_instr_ptr;
3638 let instruction = $executor. func. instructions[ next_instr_ptr] ;
37- let handler = Self :: handler_for( & instruction) ;
39+ let handler = Self :: handler_for( instruction. opcode ( ) ) ;
3840 become handler( $executor, next_instr_ptr, instruction) ;
3941 } } ;
4042 }
@@ -63,12 +65,14 @@ macro_rules! define_unbudgeted_tail_dispatch {
6365macro_rules! define_bounded_tail_dispatch {
6466 ( $executor: ident, $instr_ptr: ident, $dispatch_next: ident, $dispatch_flow: ident;
6567 $( $variant: ident $( ( $( $arg: pat) ,* ) ) ? $( { $( $field: ident) ,* } ) ? => $body: expr) ,* $( , ) ?) => {
66- fn handler_for( instruction: & Instruction ) -> BoundedHandler {
67- use tinywasm_types:: Instruction :: * ;
68-
69- match instruction {
70- $( $variant { .. } => Self :: $variant, ) *
71- }
68+ #[ inline( always) ]
69+ fn handler_for( opcode: InstructionOpcode ) -> BoundedHandler {
70+ static HANDLERS : [ BoundedHandler ; InstructionOpcode :: COUNT ] = {
71+ let mut handlers = [ Bounded :: Unreachable as BoundedHandler ; InstructionOpcode :: COUNT ] ;
72+ $( handlers[ InstructionOpcode :: $variant as usize ] = Bounded :: $variant; ) *
73+ handlers
74+ } ;
75+ HANDLERS [ opcode as usize ]
7276 }
7377
7478 $(
@@ -90,7 +94,7 @@ macro_rules! define_bounded_tail_dispatch {
9094 }
9195
9296 let instruction = $executor. func. instructions[ next_instr_ptr] ;
93- let handler = Self :: handler_for( & instruction) ;
97+ let handler = Self :: handler_for( instruction. opcode ( ) ) ;
9498 become handler( $executor, next_instr_ptr, instruction, instructions_until_checkpoint - 1 ) ;
9599 } } ;
96100 }
@@ -130,7 +134,7 @@ impl Bounded {
130134 fn run ( executor : & mut Executor < ' _ > ) -> ExecResult < ( ) > {
131135 let instr_ptr = executor. cf . instr_ptr ;
132136 let instruction = executor. func . instructions [ instr_ptr] ;
133- let handler = Self :: handler_for ( & instruction) ;
137+ let handler = Self :: handler_for ( instruction. opcode ( ) ) ;
134138 handler ( executor, instr_ptr, instruction, CHECKPOINT_INTERVAL - 1 )
135139 }
136140}
@@ -140,7 +144,7 @@ impl<'store> Executor<'store> {
140144 pub ( crate ) fn run_to_completion ( mut self ) -> Result < ( ) > {
141145 let instr_ptr = self . cf . instr_ptr ;
142146 let instruction = self . func . instructions [ instr_ptr] ;
143- let handler = Unbudgeted :: handler_for ( & instruction) ;
147+ let handler = Unbudgeted :: handler_for ( instruction. opcode ( ) ) ;
144148 Ok ( handler ( & mut self , instr_ptr, instruction) ?)
145149 }
146150
0 commit comments