@@ -288,13 +288,39 @@ pub type ModuleImports = HashMap<String, ExportValue>;
288288pub type Imports = HashMap < String , ModuleImports > ;
289289
290290#[ repr( C ) ]
291+ #[ derive( Copy , Clone ) ]
291292struct ControlFrame {
292293 stack_len : u32 ,
293294 dest_pc : u32 ,
294295 arity : u32 ,
295296 has_result : u32 ,
296297}
297298
299+ impl ControlFrame {
300+ #[ inline( always) ]
301+ fn new ( stack_len : usize , dest_pc : usize , arity : u32 , has_result : bool ) -> Self {
302+ Self {
303+ stack_len : stack_len as u32 ,
304+ dest_pc : dest_pc as u32 ,
305+ arity,
306+ has_result : has_result as u32 ,
307+ }
308+ }
309+
310+ #[ inline( always) ]
311+ fn dest_pc ( self ) -> usize {
312+ self . dest_pc as usize
313+ }
314+ #[ inline( always) ]
315+ fn arity ( self ) -> usize {
316+ self . arity as usize
317+ }
318+ #[ inline( always) ]
319+ fn has_result ( self ) -> bool {
320+ self . has_result != 0
321+ }
322+ }
323+
298324#[ derive( Copy , Clone ) ]
299325struct CallFrame {
300326 stack_base : usize ,
@@ -636,12 +662,7 @@ impl Instance {
636662 stack. resize ( stack. len ( ) + locals_count, WasmValue :: default ( ) ) ;
637663
638664 // Push return target
639- control. push ( ControlFrame {
640- stack_len : locals_start as u32 ,
641- dest_pc : return_dest as u32 ,
642- arity : if has_result { 1 } else { 0 } ,
643- has_result : has_result as u32 ,
644- } ) ;
665+ control. push ( ControlFrame :: new ( locals_start, return_dest, has_result as u32 , has_result) ) ;
645666
646667 const MAX_CONTROL_DEPTH : usize = 1000 ;
647668 if control. len ( ) > MAX_CONTROL_DEPTH {
@@ -698,20 +719,15 @@ impl Instance {
698719 }
699720
700721 #[ inline( always) ]
701- fn call_function_idx (
722+ fn dispatch_call (
702723 & self ,
703- idx : usize ,
704- return_pc : & mut usize ,
724+ f : & RuntimeFunction ,
725+ return_pc : usize ,
705726 stack : & mut Vec < WasmValue > ,
706727 control : & mut Vec < ControlFrame > ,
707728 call_frames : & mut Vec < CallFrame > ,
708- ) -> Result < ( ) , Error > {
709- const MAX_CALL_DEPTH : usize = 1000 ;
710- if call_frames. len ( ) >= MAX_CALL_DEPTH {
711- return Err ( Error :: trap ( STACK_EXHAUSTED ) ) ;
712- }
713- let fi = & self . functions [ idx] ;
714- match fi {
729+ ) -> Result < Option < usize > , Error > {
730+ match f {
715731 RuntimeFunction :: OwnedWasm { runtime_sig, pc_start, locals_count } => {
716732 let pc = Self :: setup_wasm_function_call (
717733 * runtime_sig,
@@ -720,27 +736,45 @@ impl Instance {
720736 stack,
721737 control,
722738 call_frames,
723- * return_pc,
739+ return_pc,
724740 ) ?;
725- self . interpret ( pc , stack , control , call_frames ) ? ;
741+ Ok ( Some ( pc ) )
726742 }
727- RuntimeFunction :: ImportedWasm { owner, function_index, .. } => {
728- if let Some ( owner_rc) = owner. upgrade ( ) {
729- owner_rc. call_function_idx (
730- * function_index,
731- return_pc,
732- stack,
733- control,
734- call_frames,
735- ) ?;
736- } else {
737- return Err ( Error :: trap ( FUNC_NO_IMPL ) ) ;
738- }
743+ RuntimeFunction :: ImportedWasm { owner, function_index, runtime_sig } => {
744+ let owner_rc = owner. upgrade ( ) . ok_or ( Error :: trap ( FUNC_NO_IMPL ) ) ?;
745+ Self :: call_remote (
746+ & owner_rc,
747+ * function_index,
748+ runtime_sig. n_params ( ) as usize ,
749+ stack,
750+ ) ?;
751+ Ok ( None )
739752 }
740753 RuntimeFunction :: Host { callback, runtime_sig } => {
741754 Self :: call_host ( callback. as_ref ( ) , * runtime_sig, stack) ;
755+ Ok ( None )
742756 }
743757 }
758+ }
759+
760+ #[ inline( always) ]
761+ fn call_function_idx (
762+ & self ,
763+ idx : usize ,
764+ return_pc : & mut usize ,
765+ stack : & mut Vec < WasmValue > ,
766+ control : & mut Vec < ControlFrame > ,
767+ call_frames : & mut Vec < CallFrame > ,
768+ ) -> Result < ( ) , Error > {
769+ const MAX_CALL_DEPTH : usize = 1000 ;
770+ if call_frames. len ( ) >= MAX_CALL_DEPTH {
771+ return Err ( Error :: trap ( STACK_EXHAUSTED ) ) ;
772+ }
773+ if let Some ( pc) =
774+ self . dispatch_call ( & self . functions [ idx] , * return_pc, stack, control, call_frames) ?
775+ {
776+ self . interpret ( pc, stack, control, call_frames) ?;
777+ }
744778 Ok ( ( ) )
745779 }
746780
@@ -996,35 +1030,35 @@ impl Instance {
9961030 let ( body_pc, end_pc, _else_pc, params_len, has_result) =
9971031 self . module . side_table . lookup ( pc) . unwrap ( ) ;
9981032 pc = body_pc;
999- control. push ( ControlFrame {
1000- stack_len : ( stack. len ( ) - ( params_len as usize ) ) as u32 ,
1001- dest_pc : end_pc as u32 ,
1002- arity : has_result as u32 ,
1003- has_result : has_result as u32 ,
1004- } ) ;
1033+ control. push ( ControlFrame :: new (
1034+ stack. len ( ) - params_len as usize ,
1035+ end_pc,
1036+ has_result as u32 ,
1037+ has_result,
1038+ ) ) ;
10051039 }
10061040 LOOP => {
10071041 let loop_op_pc = pc - 1 ;
10081042 let ( body_pc, _end_pc, _else_pc, params_len, has_result) =
10091043 self . module . side_table . lookup ( pc) . unwrap ( ) ;
10101044 pc = body_pc;
1011- control. push ( ControlFrame {
1012- stack_len : ( stack. len ( ) - ( params_len as usize ) ) as u32 ,
1013- dest_pc : loop_op_pc as u32 ,
1014- arity : params_len as u32 ,
1015- has_result : has_result as u32 ,
1016- } ) ;
1045+ control. push ( ControlFrame :: new (
1046+ stack. len ( ) - params_len as usize ,
1047+ loop_op_pc,
1048+ params_len as u32 ,
1049+ has_result,
1050+ ) ) ;
10171051 }
10181052 IF => {
10191053 let ( body_pc, end_pc, else_pc, params_len, has_result) =
10201054 self . module . side_table . lookup ( pc) . unwrap ( ) ;
10211055 let cond = pop_val ! ( ) . as_u32 ( ) ;
1022- control. push ( ControlFrame {
1023- stack_len : ( stack. len ( ) - ( params_len as usize ) ) as u32 ,
1024- dest_pc : end_pc as u32 ,
1025- arity : has_result as u32 ,
1026- has_result : has_result as u32 ,
1027- } ) ;
1056+ control. push ( ControlFrame :: new (
1057+ stack. len ( ) - params_len as usize ,
1058+ end_pc,
1059+ has_result as u32 ,
1060+ has_result,
1061+ ) ) ;
10281062 pc = if cond == 0 { else_pc } else { body_pc } ;
10291063 }
10301064 ELSE => {
@@ -1047,7 +1081,7 @@ impl Instance {
10471081 // Regular block end (not a function boundary)
10481082 if let Some ( target) = control. pop ( ) {
10491083 let sl = target. stack_len as usize ;
1050- if target. has_result != 0 {
1084+ if target. has_result ( ) {
10511085 let result = stack[ stack. len ( ) - 1 ] ;
10521086 stack. truncate ( sl + 1 ) ;
10531087 stack[ sl] = result;
@@ -1091,18 +1125,9 @@ impl Instance {
10911125 let fi: u32 = read_leb128 ( bytes, & mut pc) ?;
10921126 let f = & self . functions [ fi as usize ] ;
10931127
1094- match f {
1095- RuntimeFunction :: OwnedWasm { runtime_sig, pc_start, locals_count } => {
1096- pc = Self :: setup_wasm_function_call ( * runtime_sig, * pc_start, * locals_count, stack, control, call_frames, pc) ?;
1097- current_base = call_frames. last ( ) . unwrap ( ) . stack_base ;
1098- }
1099- RuntimeFunction :: ImportedWasm { owner, function_index, runtime_sig } => {
1100- let owner_rc = owner. upgrade ( ) . ok_or ( Error :: trap ( FUNC_NO_IMPL ) ) ?;
1101- Self :: call_remote ( & owner_rc, * function_index, runtime_sig. n_params ( ) as usize , stack) ?;
1102- }
1103- RuntimeFunction :: Host { callback, runtime_sig } => {
1104- Self :: call_host ( callback. as_ref ( ) , * runtime_sig, stack) ;
1105- }
1128+ if let Some ( new_pc) = self . dispatch_call ( f, pc, stack, control, call_frames) ? {
1129+ pc = new_pc;
1130+ current_base = call_frames. last ( ) . unwrap ( ) . stack_base ;
11061131 }
11071132 }
11081133 CALL_INDIRECT => {
@@ -1162,18 +1187,9 @@ impl Instance {
11621187 return Err ( Error :: trap ( INDIRECT_CALL_MISMATCH ) ) ;
11631188 }
11641189
1165- match callee {
1166- RuntimeFunction :: ImportedWasm { runtime_sig, owner, function_index } => {
1167- let owner_rc = owner. upgrade ( ) . ok_or ( Error :: trap ( FUNC_NO_IMPL ) ) ?;
1168- Self :: call_remote ( & owner_rc, * function_index, runtime_sig. n_params ( ) as usize , stack) ?;
1169- }
1170- RuntimeFunction :: OwnedWasm { runtime_sig, pc_start, locals_count } => {
1171- pc = Self :: setup_wasm_function_call ( * runtime_sig, * pc_start, * locals_count, stack, control, call_frames, pc) ?;
1172- current_base = call_frames. last ( ) . unwrap ( ) . stack_base ;
1173- }
1174- RuntimeFunction :: Host { callback, runtime_sig } => {
1175- Self :: call_host ( callback. as_ref ( ) , * runtime_sig, stack) ;
1176- }
1190+ if let Some ( new_pc) = self . dispatch_call ( callee, pc, stack, control, call_frames) ? {
1191+ pc = new_pc;
1192+ current_base = call_frames. last ( ) . unwrap ( ) . stack_base ;
11771193 }
11781194 }
11791195 DROP => {
@@ -1413,7 +1429,7 @@ impl Instance {
14131429 let Some ( target) = control. pop ( ) else {
14141430 return true ;
14151431 } ;
1416- let result_arity = target. arity as usize ;
1432+ let result_arity = target. arity ( ) ;
14171433 let sl = target. stack_len as usize ;
14181434
14191435 if result_arity > 0 {
@@ -1428,7 +1444,7 @@ impl Instance {
14281444 stack. truncate ( sl) ;
14291445 }
14301446
1431- * pc = target. dest_pc as usize ;
1447+ * pc = target. dest_pc ( ) ;
14321448 control. is_empty ( )
14331449 }
14341450
@@ -1446,43 +1462,9 @@ impl Instance {
14461462 stack. extend_from_slice ( args) ;
14471463 let mut control: Vec < ControlFrame > = Vec :: with_capacity ( 64 ) ;
14481464 let mut call_frames: Vec < CallFrame > = Vec :: with_capacity ( 16 ) ;
1449- let return_pc: usize = 0 ;
14501465
1451- match func {
1452- RuntimeFunction :: OwnedWasm { runtime_sig, pc_start, locals_count } => {
1453- let pc = Self :: setup_wasm_function_call (
1454- * runtime_sig,
1455- * pc_start,
1456- * locals_count,
1457- & mut stack,
1458- & mut control,
1459- & mut call_frames,
1460- return_pc,
1461- ) ?;
1462- self . interpret ( pc, & mut stack, & mut control, & mut call_frames) ?;
1463- }
1464- RuntimeFunction :: ImportedWasm { owner, function_index, .. } => {
1465- if let Some ( owner_rc) = owner. upgrade ( ) {
1466- let mut owned_stack: Vec < WasmValue > = Vec :: with_capacity ( 64 ) ;
1467- owned_stack. extend_from_slice ( args) ;
1468- let mut control: Vec < ControlFrame > = Vec :: with_capacity ( 16 ) ;
1469- let mut return_pc: usize = 0 ;
1470- let mut call_frames: Vec < CallFrame > = Vec :: with_capacity ( 8 ) ;
1471- owner_rc. call_function_idx (
1472- * function_index,
1473- & mut return_pc,
1474- & mut owned_stack,
1475- & mut control,
1476- & mut call_frames,
1477- ) ?;
1478- return Ok ( owned_stack) ;
1479- } else {
1480- return Err ( Error :: trap ( FUNC_NO_IMPL ) ) ;
1481- }
1482- }
1483- RuntimeFunction :: Host { callback, runtime_sig, .. } => {
1484- Self :: call_host ( callback. as_ref ( ) , * runtime_sig, & mut stack) ;
1485- }
1466+ if let Some ( pc) = self . dispatch_call ( func, 0 , & mut stack, & mut control, & mut call_frames) ? {
1467+ self . interpret ( pc, & mut stack, & mut control, & mut call_frames) ?;
14861468 }
14871469 Ok ( stack)
14881470 }
0 commit comments