@@ -371,17 +371,16 @@ impl Func {
371371 /// Panics if the given function type is not associated with this store's
372372 /// engine.
373373 pub fn new < T : ' static > (
374- store : impl AsContextMut < Data = T > ,
374+ mut store : impl AsContextMut < Data = T > ,
375375 ty : FuncType ,
376376 func : impl Fn ( Caller < ' _ , T > , & [ Val ] , & mut [ Val ] ) -> Result < ( ) > + Send + Sync + ' static ,
377377 ) -> Self {
378- assert ! ( ty. comes_from_same_engine( store. as_context( ) . engine( ) ) ) ;
379- let ty_clone = ty. clone ( ) ;
380- unsafe {
381- Func :: new_unchecked ( store, ty, move |caller, values| {
382- Func :: invoke_host_func_for_wasm ( caller, & ty_clone, values, & func)
383- } )
384- }
378+ let store = store. as_context_mut ( ) . 0 ;
379+ let host = HostFunc :: new ( store. engine ( ) , ty, func) ;
380+
381+ // SAFETY: the `T` used by `func` matches the `T` of the store we're
382+ // inserting into via this function's type signature.
383+ unsafe { host. into_func ( store) }
385384 }
386385
387386 /// Creates a new [`Func`] with the given arguments, although has fewer
@@ -417,7 +416,6 @@ impl Func {
417416 ty : FuncType ,
418417 func : impl Fn ( Caller < ' _ , T > , & mut [ ValRaw ] ) -> Result < ( ) > + Send + Sync + ' static ,
419418 ) -> Self {
420- assert ! ( ty. comes_from_same_engine( store. as_context( ) . engine( ) ) ) ;
421419 let store = store. as_context_mut ( ) . 0 ;
422420
423421 // SAFETY: the contract required by `new_unchecked` is the same as the
@@ -502,7 +500,7 @@ impl Func {
502500 /// # }
503501 /// ```
504502 #[ cfg( feature = "async" ) ]
505- pub fn new_async < T , F > ( store : impl AsContextMut < Data = T > , ty : FuncType , func : F ) -> Func
503+ pub fn new_async < T , F > ( mut store : impl AsContextMut < Data = T > , ty : FuncType , func : F ) -> Func
506504 where
507505 F : for < ' a > Fn (
508506 Caller < ' a , T > ,
@@ -514,24 +512,16 @@ impl Func {
514512 + ' static ,
515513 T : ' static ,
516514 {
515+ let store = store. as_context_mut ( ) . 0 ;
517516 assert ! (
518- store. as_context ( ) . async_support( ) ,
517+ store. async_support( ) ,
519518 "cannot use `new_async` without enabling async support in the config"
520519 ) ;
521- assert ! ( ty. comes_from_same_engine( store. as_context( ) . engine( ) ) ) ;
522- return Func :: new (
523- store,
524- ty,
525- move |Caller { store, caller } , params, results| {
526- store. with_blocking ( |store, cx| {
527- cx. block_on ( core:: pin:: Pin :: from ( func (
528- Caller { store, caller } ,
529- params,
530- results,
531- ) ) )
532- } ) ?
533- } ,
534- ) ;
520+ let host = HostFunc :: new_async ( store. engine ( ) , ty, func) ;
521+
522+ // SAFETY: the `T` used by `func` matches the `T` of the store we're
523+ // inserting into via this function's type signature.
524+ unsafe { host. into_func ( store) }
535525 }
536526
537527 /// Creates a new `Func` from a store and a funcref within that store.
@@ -812,22 +802,6 @@ impl Func {
812802 unsafe { host. into_func ( store) }
813803 }
814804
815- #[ cfg( feature = "async" ) ]
816- fn wrap_inner < F , T , Params , Results > ( mut store : impl AsContextMut < Data = T > , func : F ) -> Func
817- where
818- F : Fn ( Caller < ' _ , T > , Params ) -> Results + Send + Sync + ' static ,
819- Params : WasmTyList ,
820- Results : WasmRet ,
821- T : ' static ,
822- {
823- let store = store. as_context_mut ( ) . 0 ;
824- let host = HostFunc :: wrap_inner ( store. engine ( ) , func) ;
825-
826- // SAFETY: The `T` the closure takes is the same as the `T` of the store
827- // we're inserting into via the type signature above.
828- unsafe { host. into_func ( store) }
829- }
830-
831805 /// Same as [`Func::wrap`], except the closure asynchronously produces the
832806 /// result and the arguments are passed within a tuple. For more information
833807 /// see the [`Func`] documentation.
@@ -836,7 +810,7 @@ impl Func {
836810 ///
837811 /// This function will panic if called with a non-asynchronous store.
838812 #[ cfg( feature = "async" ) ]
839- pub fn wrap_async < T , F , P , R > ( store : impl AsContextMut < Data = T > , func : F ) -> Func
813+ pub fn wrap_async < T , F , P , R > ( mut store : impl AsContextMut < Data = T > , func : F ) -> Func
840814 where
841815 F : for < ' a > Fn ( Caller < ' a , T > , P ) -> Box < dyn Future < Output = R > + Send + ' a >
842816 + Send
@@ -846,16 +820,16 @@ impl Func {
846820 R : WasmRet ,
847821 T : ' static ,
848822 {
823+ let store = store. as_context_mut ( ) . 0 ;
849824 assert ! (
850- store. as_context ( ) . async_support( ) ,
825+ store. async_support( ) ,
851826 concat!( "cannot use `wrap_async` without enabling async support on the config" )
852827 ) ;
853- Func :: wrap_inner ( store, move |Caller { store, caller } , args| {
854- match store. block_on ( |store| func ( Caller { store, caller } , args) . into ( ) ) {
855- Ok ( ret) => ret. into_fallible ( ) ,
856- Err ( e) => R :: fallible_from_error ( e) ,
857- }
858- } )
828+ let host = HostFunc :: wrap_async ( store. engine ( ) , func) ;
829+
830+ // SAFETY: The `T` the closure takes is the same as the `T` of the store
831+ // we're inserting into via the type signature above.
832+ unsafe { host. into_func ( store) }
859833 }
860834
861835 /// Returns the underlying wasm type that this `Func` has.
@@ -1949,7 +1923,7 @@ macro_rules! impl_into_func {
19491923for_each_function_signature ! ( impl_into_func) ;
19501924
19511925/// Trait implemented for various tuples made up of types which implement
1952- /// [`WasmTy`] that can be passed to [`Func::wrap_inner `] and
1926+ /// [`WasmTy`] that can be passed to [`Func::wrap_async `] and
19531927/// [`HostContext::from_closure`].
19541928pub unsafe trait WasmTyList {
19551929 /// Get the value type that each Type in the list represents.
@@ -2028,16 +2002,6 @@ pub struct Caller<'a, T: 'static> {
20282002}
20292003
20302004impl < T > Caller < ' _ , T > {
2031- #[ cfg( feature = "async" ) ]
2032- pub ( crate ) fn new ( store : StoreContextMut < ' _ , T > , caller : Instance ) -> Caller < ' _ , T > {
2033- Caller { store, caller }
2034- }
2035-
2036- #[ cfg( feature = "async" ) ]
2037- pub ( crate ) fn caller ( & self ) -> Instance {
2038- self . caller
2039- }
2040-
20412005 /// Executes `f` with an appropriate `Caller`.
20422006 ///
20432007 /// This is the entrypoint for host functions in core wasm. The `store` and
@@ -2257,6 +2221,12 @@ impl<T: 'static> AsContextMut for Caller<'_, T> {
22572221 }
22582222}
22592223
2224+ impl < ' a , T : ' static > From < Caller < ' a , T > > for StoreContextMut < ' a , T > {
2225+ fn from ( caller : Caller < ' a , T > ) -> Self {
2226+ caller. store
2227+ }
2228+ }
2229+
22602230// State stored inside a `VMArrayCallHostFuncContext`.
22612231struct HostFuncState < F > {
22622232 // The actual host function.
@@ -2457,6 +2427,40 @@ impl HostFunc {
24572427 }
24582428 }
24592429
2430+ /// Analog of [`Func::new_async`]
2431+ ///
2432+ /// # Panics
2433+ ///
2434+ /// Panics if the given function type is not associated with the given
2435+ /// engine.
2436+ #[ cfg( feature = "async" ) ]
2437+ pub fn new_async < T , F > ( engine : & Engine , ty : FuncType , func : F ) -> Self
2438+ where
2439+ F : for < ' a > Fn (
2440+ Caller < ' a , T > ,
2441+ & ' a [ Val ] ,
2442+ & ' a mut [ Val ] ,
2443+ ) -> Box < dyn Future < Output = Result < ( ) > > + Send + ' a >
2444+ + Send
2445+ + Sync
2446+ + ' static ,
2447+ T : ' static ,
2448+ {
2449+ HostFunc :: new (
2450+ engine,
2451+ ty,
2452+ move |Caller { store, caller } , params, results| {
2453+ store. with_blocking ( |store, cx| {
2454+ cx. block_on ( core:: pin:: Pin :: from ( func (
2455+ Caller { store, caller } ,
2456+ params,
2457+ results,
2458+ ) ) )
2459+ } ) ?
2460+ } ,
2461+ )
2462+ }
2463+
24602464 /// Analog of [`Func::new_unchecked`]
24612465 ///
24622466 /// # Panics
@@ -2498,19 +2502,6 @@ impl HostFunc {
24982502 HostFunc :: _new ( engine, ctx. into ( ) )
24992503 }
25002504
2501- /// Analog of [`Func::wrap_inner`]
2502- #[ cfg( any( feature = "component-model" , feature = "async" ) ) ]
2503- pub fn wrap_inner < F , T , Params , Results > ( engine : & Engine , func : F ) -> Self
2504- where
2505- F : Fn ( Caller < ' _ , T > , Params ) -> Results + Send + Sync + ' static ,
2506- Params : WasmTyList ,
2507- Results : WasmRet ,
2508- T : ' static ,
2509- {
2510- let ctx = HostContext :: from_closure ( engine, func) ;
2511- HostFunc :: _new ( engine, ctx)
2512- }
2513-
25142505 /// Analog of [`Func::wrap`]
25152506 pub fn wrap < T , Params , Results > (
25162507 engine : & Engine ,
@@ -2523,6 +2514,29 @@ impl HostFunc {
25232514 HostFunc :: _new ( engine, ctx)
25242515 }
25252516
2517+ /// Analog of [`Func::wrap_async`]
2518+ #[ cfg( feature = "async" ) ]
2519+ pub fn wrap_async < T , F , P , R > ( engine : & Engine , func : F ) -> Self
2520+ where
2521+ F : for < ' a > Fn ( Caller < ' a , T > , P ) -> Box < dyn Future < Output = R > + Send + ' a >
2522+ + Send
2523+ + Sync
2524+ + ' static ,
2525+ P : WasmTyList ,
2526+ R : WasmRet ,
2527+ T : ' static ,
2528+ {
2529+ HostFunc :: _new (
2530+ engine,
2531+ HostContext :: from_closure ( engine, move |Caller { store, caller } , args| {
2532+ match store. block_on ( |store| func ( Caller { store, caller } , args) . into ( ) ) {
2533+ Ok ( ret) => ret. into_fallible ( ) ,
2534+ Err ( e) => R :: fallible_from_error ( e) ,
2535+ }
2536+ } ) ,
2537+ )
2538+ }
2539+
25262540 /// Requires that this function's signature is already registered within
25272541 /// `Engine`. This happens automatically during the above two constructors.
25282542 fn _new ( engine : & Engine , ctx : HostContext ) -> Self {
0 commit comments