@@ -21,16 +21,18 @@ use crate::{
2121 ShiftAmount ,
2222 } ,
2323 engine:: {
24+ CodeView ,
2425 DedupFuncType ,
2526 FuncEntry ,
27+ InOutParams ,
2628 executor:: {
2729 LoadFromCellsByValue ,
2830 StoreToCells ,
2931 handler:: { Break , Control , DoneReason , args:: Args } ,
3032 } ,
3133 utils:: unreachable_unchecked,
3234 } ,
33- func:: { FuncEntity , HostFuncEntity } ,
35+ func:: { FuncEntity , HostFuncEntity , Trampoline } ,
3436 instance:: { DataAddr , ElemAddr , FuncAddr , GlobalAddr , InstanceEntity , MemoryAddr , TableAddr } ,
3537 ir:: { self , Address , BoundedSlotSpan , Local , Offset , Offset16 , Slot , SlotAndReg , SlotSpan } ,
3638 memory:: DataSegmentEntity ,
@@ -816,6 +818,38 @@ pub fn return_call_func_entry(
816818 Control :: Continue ( ( callee_ip, callee_sp) )
817819}
818820
821+ /// Invokes the host function behind `trampoline`.
822+ ///
823+ /// Returns the host provided error if the host function trapped.
824+ ///
825+ /// # Note
826+ ///
827+ /// Takes `store` and `code` instead of the whole [`VmState`] since `inout` already
828+ /// borrows its [`Stack`].
829+ ///
830+ /// [`Stack`]: crate::engine::executor::Stack
831+ #[ inline]
832+ fn invoke_host (
833+ store : & mut PrunedStore ,
834+ code : & mut CodeView ,
835+ trampoline : Trampoline ,
836+ instance : Option < Inst > ,
837+ inout : InOutParams < ' _ > ,
838+ call_hooks : CallHooks ,
839+ ) -> Result < ( ) , Error > {
840+ match store. call_host_func ( trampoline, instance, inout, call_hooks) {
841+ Ok ( ( ) ) => { }
842+ Err ( StoreError :: External ( error) ) => return Err ( error) ,
843+ Err ( StoreError :: Internal ( error) ) => unsafe {
844+ unreachable_unchecked ! (
845+ "internal interpreter error while executing host function: {error}"
846+ )
847+ } ,
848+ }
849+ code. refresh ( ) ;
850+ Ok ( ( ) )
851+ }
852+
819853pub fn call_host (
820854 state : & mut VmState ,
821855 func : Func ,
@@ -831,21 +865,16 @@ pub fn call_host(
831865 . stack
832866 . prepare_host_frame ( caller_ip, params, host_func. len_result_cells ( ) )
833867 . into_control ( ) ?;
834- match state
835- . store
836- . call_host_func ( trampoline, instance, inout, call_hooks)
837- {
838- Ok ( ( ) ) => { }
839- Err ( StoreError :: External ( error) ) => {
840- done ! ( state, DoneReason :: host_error( error, func, params. span( ) ) )
841- }
842- Err ( StoreError :: Internal ( error) ) => unsafe {
843- unreachable_unchecked ! (
844- "internal interpreter error while executing host function: {error}"
845- )
846- } ,
868+ if let Err ( error) = invoke_host (
869+ state. store ,
870+ & mut state. code ,
871+ trampoline,
872+ instance,
873+ inout,
874+ call_hooks,
875+ ) {
876+ done ! ( state, DoneReason :: host_error( error, func, params. span( ) ) )
847877 }
848- state. code . refresh ( ) ;
849878 Control :: Continue ( sp)
850879}
851880
@@ -862,27 +891,22 @@ pub fn return_call_host(
862891 . stack
863892 . return_prepare_host_frame ( params, host_func. len_result_cells ( ) , instance)
864893 . into_control ( ) ?;
865- match state
866- . store
867- . call_host_func ( trampoline, Some ( instance) , inout, CallHooks :: Call )
868- {
869- Ok ( ( ) ) => { }
870- Err ( StoreError :: External ( error) ) => {
871- // Note: we won't allow resumption in case the execution would
872- // have returned with this the host function tail call.
873- let reason = match control {
874- Control :: Continue ( _) => DoneReason :: host_error ( error, func, params. span ( ) ) ,
875- Control :: Break ( _) => DoneReason :: error ( error) ,
876- } ;
877- done ! ( state, reason)
878- }
879- Err ( StoreError :: Internal ( error) ) => unsafe {
880- unreachable_unchecked ! (
881- "internal interpreter error while executing host function: {error}"
882- )
883- } ,
894+ if let Err ( error) = invoke_host (
895+ state. store ,
896+ & mut state. code ,
897+ trampoline,
898+ Some ( instance) ,
899+ inout,
900+ CallHooks :: Call ,
901+ ) {
902+ // Note: we won't allow resumption in case the execution would
903+ // have returned with this the host function tail call.
904+ let reason = match control {
905+ Control :: Continue ( _) => DoneReason :: host_error ( error, func, params. span ( ) ) ,
906+ Control :: Break ( _) => DoneReason :: error ( error) ,
907+ } ;
908+ done ! ( state, reason)
884909 }
885- state. code . refresh ( ) ;
886910 match control {
887911 Control :: Continue ( ( ip, sp, instance) ) => Control :: Continue ( ( ip, sp, instance) ) ,
888912 Control :: Break ( sp) => done ! ( state, DoneReason :: Return ( sp) ) ,
@@ -965,9 +989,8 @@ pub fn return_call_wasm_or_host(
965989 } ;
966990 // Hot path: tail-calling a Wasm function. See `call_wasm_or_host` for the shape.
967991 let callee_instance: Inst = resolve_instance ( state. store , wasm_func. instance ( ) ) . into ( ) ;
968- let changed_instance = ( callee_instance != instance) . then_some ( callee_instance) ;
969992 let ( callee_ip, callee_sp) =
970- return_call_func_entry ( state, params, wasm_func. func_entry ( ) , changed_instance ) ?;
993+ return_call_func_entry ( state, params, wasm_func. func_entry ( ) , Some ( callee_instance ) ) ?;
971994 let ( instance, mem0, mem0_len) =
972995 update_instance ( state. store , instance, callee_instance, mem0, mem0_len) ;
973996 Control :: Continue ( ( callee_ip, callee_sp, mem0, mem0_len, instance) )
0 commit comments