@@ -21,8 +21,9 @@ use core::mem::{self, MaybeUninit};
2121use core:: pin:: Pin ;
2222use core:: ptr:: NonNull ;
2323use wasmtime_environ:: component:: {
24- CanonicalAbiInfo , ComponentTypes , InterfaceType , MAX_FLAT_ASYNC_PARAMS , MAX_FLAT_PARAMS ,
25- MAX_FLAT_RESULTS , OptionsIndex , RuntimeComponentInstanceIndex , TypeFuncIndex , TypeTuple ,
24+ CanonicalAbiInfo , ComponentTypes , FlatFuncTypeContext , FlatTypesStorage , InterfaceType ,
25+ MAX_FLAT_ASYNC_PARAMS , MAX_FLAT_PARAMS , MAX_FLAT_RESULTS , OptionsIndex ,
26+ RuntimeComponentInstanceIndex , TypeFunc , TypeFuncIndex , TypeTuple ,
2627} ;
2728
2829pub struct HostFunc {
@@ -213,6 +214,27 @@ where
213214 Ok ( ( ) )
214215}
215216
217+ #[ cfg( feature = "rr" ) ]
218+ #[ inline( always) ]
219+ fn flat_func_type (
220+ types : & ComponentTypes ,
221+ ty : & TypeFunc ,
222+ context : FlatFuncTypeContext ,
223+ ) -> ( FlatTypesStorage , FlatTypesStorage ) {
224+ types. flat_func_type ( ty, context)
225+ }
226+
227+ #[ cfg( not( feature = "rr" ) ) ]
228+ #[ inline( always) ]
229+ /// This will get DCEd when RR is disabled
230+ fn flat_func_type (
231+ _types : & ComponentTypes ,
232+ _ty : & TypeFunc ,
233+ _context : FlatFuncTypeContext ,
234+ ) -> ( FlatTypesStorage , FlatTypesStorage ) {
235+ ( FlatTypesStorage :: new ( ) , FlatTypesStorage :: new ( ) )
236+ }
237+
216238/// The "meat" of calling a host function from wasm.
217239///
218240/// This function is delegated to from implementations of
@@ -267,7 +289,10 @@ where
267289 let param_tys = InterfaceType :: Tuple ( ty. params ) ;
268290 let result_tys = InterfaceType :: Tuple ( ty. results ) ;
269291
270- rr:: component_hooks:: record_validate_host_func_entry ( storage, & types, & param_tys, store. 0 ) ?;
292+ let ( param_flat_types, result_flat_types) =
293+ flat_func_type ( types, & ty, FlatFuncTypeContext :: Lower ) ;
294+
295+ rr:: component_hooks:: record_validate_host_func_entry ( storage, param_flat_types, store. 0 ) ?;
271296
272297 if async_ {
273298 #[ cfg( feature = "component-model-async" ) ]
@@ -338,7 +363,7 @@ where
338363 } ;
339364
340365 let mut lower = LowerContext :: new ( store, options, instance) ;
341- storage. lower_results ( & mut lower, InterfaceType :: U32 , status) ?;
366+ storage. lower_results ( & mut lower, InterfaceType :: U32 , result_flat_types , status) ?;
342367 }
343368 #[ cfg( not( feature = "component-model-async" ) ) ]
344369 {
@@ -366,7 +391,7 @@ where
366391 flags. set_may_leave ( false ) ;
367392 }
368393 let mut lower = LowerContext :: new ( store, options, instance) ;
369- storage. lower_results ( & mut lower, result_tys, ret) ?;
394+ storage. lower_results ( & mut lower, result_tys, result_flat_types , ret) ?;
370395 unsafe {
371396 flags. set_may_leave ( true ) ;
372397 }
@@ -590,6 +615,7 @@ where
590615 & mut self ,
591616 cx : & mut LowerContext < ' _ , T > ,
592617 ty : InterfaceType ,
618+ result_flat_types : FlatTypesStorage ,
593619 ret : R ,
594620 ) -> Result < ( ) > {
595621 match self . lower_dst ( ) {
@@ -601,8 +627,7 @@ where
601627 ) ;
602628 rr:: component_hooks:: record_host_func_return (
603629 unsafe { storage_as_slice_mut ( storage) } ,
604- cx. types ,
605- & ty,
630+ result_flat_types,
606631 cx. store . 0 ,
607632 ) ?;
608633 result
@@ -615,11 +640,10 @@ where
615640 ty,
616641 offset,
617642 ) ;
618- // Record the pointer
643+ // Pointer will be recorded by params; not necessary here
619644 rr:: component_hooks:: record_host_func_return (
620- & [ MaybeUninit :: new ( * ptr) ] ,
621- cx. types ,
622- & InterfaceType :: U32 ,
645+ & [ ] ,
646+ result_flat_types,
623647 cx. store . 0 ,
624648 ) ?;
625649 result
@@ -846,10 +870,12 @@ where
846870 params_and_results. push ( Val :: Bool ( false ) ) ;
847871 }
848872
873+ let ( param_flat_types, result_flat_types) =
874+ flat_func_type ( types, func_ty, FlatFuncTypeContext :: Lower ) ;
875+
849876 rr:: component_hooks:: record_validate_host_func_entry (
850877 storage,
851- types,
852- & InterfaceType :: Tuple ( func_ty. params ) ,
878+ param_flat_types,
853879 store. 0 . store_opaque_mut ( ) ,
854880 ) ?;
855881
@@ -928,12 +954,7 @@ where
928954 ) ?;
929955 }
930956 assert ! ( dst. next( ) . is_none( ) ) ;
931- rr:: component_hooks:: record_host_func_return (
932- storage,
933- cx. types ,
934- & InterfaceType :: Tuple ( func_ty. results ) ,
935- cx. store . 0 ,
936- ) ?;
957+ rr:: component_hooks:: record_host_func_return ( storage, result_flat_types, cx. store . 0 ) ?;
937958 } else {
938959 let ret_ptr = unsafe { storage[ ret_index] . assume_init_ref ( ) } ;
939960 let mut ptr = validate_inbounds_dynamic ( & result_tys. abi , cx. as_slice_mut ( ) , ret_ptr) ?;
@@ -946,13 +967,8 @@ where
946967 offset,
947968 ) ?;
948969 }
949- // Lower store into pointer
950- rr:: component_hooks:: record_host_func_return (
951- & storage[ ret_index..ret_index + 1 ] ,
952- cx. types ,
953- & InterfaceType :: U32 ,
954- cx. store . 0 ,
955- ) ?;
970+ // Ret ptr is passed through params, and doesn't need to be recorded.
971+ rr:: component_hooks:: record_host_func_return ( & [ ] , result_flat_types, cx. store . 0 ) ?;
956972 }
957973
958974 unsafe {
@@ -977,43 +993,31 @@ unsafe fn call_host_dynamic_replay<T>(
977993 #[ cfg( feature = "rr" ) ]
978994 {
979995 use crate :: rr:: component_hooks:: ReplayLoweringPhase ;
980- // Mirror of `dynamic_params_load` for replay. Keep in sync
981- fn dynamic_params_load_replay ( param_tys : & TypeTuple , max_flat_params : usize ) -> usize {
982- if let Some ( param_count) = param_tys. abi . flat_count ( max_flat_params) {
983- param_count
984- } else {
985- 1
986- }
987- }
988996
989997 if async_ {
990998 unreachable ! (
991999 "Replay logic should be unreachable with component async-ABI (currently unsupported)"
9921000 ) ;
9931001 }
9941002 let func_ty = & types[ ty] ;
995- let param_tys = & types[ func_ty. params ] ;
1003+ let ( param_flat_types , _ ) = flat_func_type ( types, func_ty, FlatFuncTypeContext :: Lower ) ;
9961004 let result_tys = & types[ func_ty. results ] ;
9971005
9981006 rr:: component_hooks:: replay_validate_host_func_entry (
9991007 storage,
1000- types,
1001- & InterfaceType :: Tuple ( func_ty. params ) ,
1008+ param_flat_types,
10021009 store. 0 . store_opaque_mut ( ) ,
10031010 ) ?;
10041011
10051012 let mut cx = LowerContext :: new ( store, options, instance) ;
10061013
10071014 // Skip lifting/lowering logic, and just replaying the lowering state
1008- let ret_index = dynamic_params_load_replay ( param_tys, MAX_FLAT_PARAMS ) ;
1009- // Copy the entire contiguous storage slice instead of looping
10101015 if let Some ( _cnt) = result_tys. abi . flat_count ( MAX_FLAT_RESULTS ) {
1016+ // Copy the entire contiguous storage slice instead of looping
10111017 cx. replay_lowering ( Some ( storage) , ReplayLoweringPhase :: HostFuncReturn ) ?;
10121018 } else {
1013- cx. replay_lowering (
1014- Some ( & mut storage[ ret_index..ret_index + 1 ] ) ,
1015- ReplayLoweringPhase :: HostFuncReturn ,
1016- ) ?;
1019+ // The retptr is passed through params for lowering
1020+ cx. replay_lowering ( None , ReplayLoweringPhase :: HostFuncReturn ) ?;
10171021 }
10181022 Ok ( ( ) )
10191023 }
0 commit comments