dusk_wasmtime/runtime/
func.rs

1use crate::runtime::Uninhabited;
2use crate::store::{AutoAssertNoGc, StoreData, StoreOpaque, Stored};
3use crate::type_registry::RegisteredType;
4use crate::{
5    AsContext, AsContextMut, CallHook, Engine, Extern, FuncType, Instance, Module, Ref,
6    StoreContext, StoreContextMut, Val, ValRaw, ValType,
7};
8use anyhow::{bail, Context as _, Error, Result};
9use std::ffi::c_void;
10use std::future::Future;
11use std::mem;
12use std::num::NonZeroUsize;
13use std::pin::Pin;
14use std::ptr::{self, NonNull};
15use std::sync::Arc;
16use wasmtime_runtime::{
17    ExportFunction, SendSyncPtr, StoreBox, VMArrayCallHostFuncContext, VMContext, VMFuncRef,
18    VMFunctionImport, VMNativeCallHostFuncContext, VMOpaqueContext, VMSharedTypeIndex,
19};
20
21/// A reference to the abstract `nofunc` heap value.
22///
23/// The are no instances of `(ref nofunc)`: it is an uninhabited type.
24///
25/// There is precisely one instance of `(ref null nofunc)`, aka `nullfuncref`:
26/// the null reference.
27///
28/// This `NoFunc` Rust type's sole purpose is for use with [`Func::wrap`]- and
29/// [`Func::typed`]-style APIs for statically typing a function as taking or
30/// returning a `(ref null nofunc)` (aka `Option<NoFunc>`) which is always
31/// `None`.
32///
33/// # Example
34///
35/// ```
36/// # use wasmtime::*;
37/// # fn _foo() -> Result<()> {
38/// let mut config = Config::new();
39/// config.wasm_function_references(true);
40/// let engine = Engine::new(&config)?;
41///
42/// let module = Module::new(
43///     &engine,
44///     r#"
45///         (module
46///             (func (export "f") (param (ref null nofunc))
47///                 ;; If the reference is null, return.
48///                 local.get 0
49///                 ref.is_null nofunc
50///                 br_if 0
51///
52///                 ;; If the reference was not null (which is impossible)
53///                 ;; then raise a trap.
54///                 unreachable
55///             )
56///         )
57///     "#,
58/// )?;
59///
60/// let mut store = Store::new(&engine, ());
61/// let instance = Instance::new(&mut store, &module, &[])?;
62/// let f = instance.get_func(&mut store, "f").unwrap();
63///
64/// // We can cast a `(ref null nofunc)`-taking function into a typed function that
65/// // takes an `Option<NoFunc>` via the `Func::typed` method.
66/// let f = f.typed::<Option<NoFunc>, ()>(&store)?;
67///
68/// // We can call the typed function, passing the null `nofunc` reference.
69/// let result = f.call(&mut store, NoFunc::null());
70///
71/// // The function should not have trapped, because the reference we gave it was
72/// // null (as it had to be, since `NoFunc` is uninhabited).
73/// assert!(result.is_ok());
74/// # Ok(())
75/// # }
76/// ```
77#[derive(Copy, Clone, Debug, PartialEq, Eq)]
78pub struct NoFunc {
79    _inner: Uninhabited,
80}
81
82impl NoFunc {
83    /// Get the null `(ref null nofunc)` (aka `nullfuncref`) reference.
84    #[inline]
85    pub fn null() -> Option<NoFunc> {
86        None
87    }
88
89    /// Get the null `(ref null nofunc)` (aka `nullfuncref`) reference as a
90    /// [`Ref`].
91    pub fn null_ref() -> Ref {
92        Ref::Func(None)
93    }
94
95    /// Get the null `(ref null nofunc)` (aka `nullfuncref`) reference as a
96    /// [`Val`].
97    pub fn null_val() -> Val {
98        Val::FuncRef(None)
99    }
100}
101
102/// A WebAssembly function which can be called.
103///
104/// This type typically represents an exported function from a WebAssembly
105/// module instance. In this case a [`Func`] belongs to an [`Instance`] and is
106/// loaded from there. A [`Func`] may also represent a host function as well in
107/// some cases, too.
108///
109/// Functions can be called in a few different ways, either synchronous or async
110/// and either typed or untyped (more on this below). Note that host functions
111/// are normally inserted directly into a [`Linker`](crate::Linker) rather than
112/// using this directly, but both options are available.
113///
114/// # `Func` and `async`
115///
116/// Functions from the perspective of WebAssembly are always synchronous. You
117/// might have an `async` function in Rust, however, which you'd like to make
118/// available from WebAssembly. Wasmtime supports asynchronously calling
119/// WebAssembly through native stack switching. You can get some more
120/// information about [asynchronous configs](crate::Config::async_support), but
121/// from the perspective of `Func` it's important to know that whether or not
122/// your [`Store`](crate::Store) is asynchronous will dictate whether you call
123/// functions through [`Func::call`] or [`Func::call_async`] (or the typed
124/// wrappers such as [`TypedFunc::call`] vs [`TypedFunc::call_async`]).
125///
126/// # To `Func::call` or to `Func::typed().call()`
127///
128/// There's a 2x2 matrix of methods to call [`Func`]. Invocations can either be
129/// asynchronous or synchronous. They can also be statically typed or not.
130/// Whether or not an invocation is asynchronous is indicated via the method
131/// being `async` and [`call_async`](Func::call_async) being the entry point.
132/// Otherwise for statically typed or not your options are:
133///
134/// * Dynamically typed - if you don't statically know the signature of the
135///   function that you're calling you'll be using [`Func::call`] or
136///   [`Func::call_async`]. These functions take a variable-length slice of
137///   "boxed" arguments in their [`Val`] representation. Additionally the
138///   results are returned as an owned slice of [`Val`]. These methods are not
139///   optimized due to the dynamic type checks that must occur, in addition to
140///   some dynamic allocations for where to put all the arguments. While this
141///   allows you to call all possible wasm function signatures, if you're
142///   looking for a speedier alternative you can also use...
143///
144/// * Statically typed - if you statically know the type signature of the wasm
145///   function you're calling, then you'll want to use the [`Func::typed`]
146///   method to acquire an instance of [`TypedFunc`]. This structure is static proof
147///   that the underlying wasm function has the ascripted type, and type
148///   validation is only done once up-front. The [`TypedFunc::call`] and
149///   [`TypedFunc::call_async`] methods are much more efficient than [`Func::call`]
150///   and [`Func::call_async`] because the type signature is statically known.
151///   This eschews runtime checks as much as possible to get into wasm as fast
152///   as possible.
153///
154/// # Examples
155///
156/// One way to get a `Func` is from an [`Instance`] after you've instantiated
157/// it:
158///
159/// ```
160/// # use wasmtime::*;
161/// # fn main() -> anyhow::Result<()> {
162/// let engine = Engine::default();
163/// let module = Module::new(&engine, r#"(module (func (export "foo")))"#)?;
164/// let mut store = Store::new(&engine, ());
165/// let instance = Instance::new(&mut store, &module, &[])?;
166/// let foo = instance.get_func(&mut store, "foo").expect("export wasn't a function");
167///
168/// // Work with `foo` as a `Func` at this point, such as calling it
169/// // dynamically...
170/// match foo.call(&mut store, &[], &mut []) {
171///     Ok(()) => { /* ... */ }
172///     Err(trap) => {
173///         panic!("execution of `foo` resulted in a wasm trap: {}", trap);
174///     }
175/// }
176/// foo.call(&mut store, &[], &mut [])?;
177///
178/// // ... or we can make a static assertion about its signature and call it.
179/// // Our first call here can fail if the signatures don't match, and then the
180/// // second call can fail if the function traps (like the `match` above).
181/// let foo = foo.typed::<(), ()>(&store)?;
182/// foo.call(&mut store, ())?;
183/// # Ok(())
184/// # }
185/// ```
186///
187/// You can also use the [`wrap` function](Func::wrap) to create a
188/// `Func`
189///
190/// ```
191/// # use wasmtime::*;
192/// # fn main() -> anyhow::Result<()> {
193/// let mut store = Store::<()>::default();
194///
195/// // Create a custom `Func` which can execute arbitrary code inside of the
196/// // closure.
197/// let add = Func::wrap(&mut store, |a: i32, b: i32| -> i32 { a + b });
198///
199/// // Next we can hook that up to a wasm module which uses it.
200/// let module = Module::new(
201///     store.engine(),
202///     r#"
203///         (module
204///             (import "" "" (func $add (param i32 i32) (result i32)))
205///             (func (export "call_add_twice") (result i32)
206///                 i32.const 1
207///                 i32.const 2
208///                 call $add
209///                 i32.const 3
210///                 i32.const 4
211///                 call $add
212///                 i32.add))
213///     "#,
214/// )?;
215/// let instance = Instance::new(&mut store, &module, &[add.into()])?;
216/// let call_add_twice = instance.get_typed_func::<(), i32>(&mut store, "call_add_twice")?;
217///
218/// assert_eq!(call_add_twice.call(&mut store, ())?, 10);
219/// # Ok(())
220/// # }
221/// ```
222///
223/// Or you could also create an entirely dynamic `Func`!
224///
225/// ```
226/// # use wasmtime::*;
227/// # fn main() -> anyhow::Result<()> {
228/// let mut store = Store::<()>::default();
229///
230/// // Here we need to define the type signature of our `Double` function and
231/// // then wrap it up in a `Func`
232/// let double_type = wasmtime::FuncType::new(
233///     store.engine(),
234///     [wasmtime::ValType::I32].iter().cloned(),
235///     [wasmtime::ValType::I32].iter().cloned(),
236/// );
237/// let double = Func::new(&mut store, double_type, |_, params, results| {
238///     let mut value = params[0].unwrap_i32();
239///     value *= 2;
240///     results[0] = value.into();
241///     Ok(())
242/// });
243///
244/// let module = Module::new(
245///     store.engine(),
246///     r#"
247///         (module
248///             (import "" "" (func $double (param i32) (result i32)))
249///             (func $start
250///                 i32.const 1
251///                 call $double
252///                 drop)
253///             (start $start))
254///     "#,
255/// )?;
256/// let instance = Instance::new(&mut store, &module, &[double.into()])?;
257/// // .. work with `instance` if necessary
258/// # Ok(())
259/// # }
260/// ```
261#[derive(Copy, Clone, Debug)]
262#[repr(transparent)] // here for the C API
263pub struct Func(Stored<FuncData>);
264
265pub(crate) struct FuncData {
266    kind: FuncKind,
267
268    // A pointer to the in-store `VMFuncRef` for this function, if
269    // any.
270    //
271    // When a function is passed to Wasm but doesn't have a Wasm-to-native
272    // trampoline, we have to patch it in. But that requires mutating the
273    // `VMFuncRef`, and this function could be shared across
274    // threads. So we instead copy and pin the `VMFuncRef` into
275    // `StoreOpaque::func_refs`, where we can safely patch the field without
276    // worrying about synchronization and we hold a pointer to it here so we can
277    // reuse it rather than re-copy if it is passed to Wasm again.
278    in_store_func_ref: Option<SendSyncPtr<VMFuncRef>>,
279
280    // This is somewhat expensive to load from the `Engine` and in most
281    // optimized use cases (e.g. `TypedFunc`) it's not actually needed or it's
282    // only needed rarely. To handle that this is an optionally-contained field
283    // which is lazily loaded into as part of `Func::call`.
284    //
285    // Also note that this is intentionally placed behind a pointer to keep it
286    // small as `FuncData` instances are often inserted into a `Store`.
287    ty: Option<Box<FuncType>>,
288}
289
290/// The three ways that a function can be created and referenced from within a
291/// store.
292enum FuncKind {
293    /// A function already owned by the store via some other means. This is
294    /// used, for example, when creating a `Func` from an instance's exported
295    /// function. The instance's `InstanceHandle` is already owned by the store
296    /// and we just have some pointers into that which represent how to call the
297    /// function.
298    StoreOwned { export: ExportFunction },
299
300    /// A function is shared across possibly other stores, hence the `Arc`. This
301    /// variant happens when a `Linker`-defined function is instantiated within
302    /// a `Store` (e.g. via `Linker::get` or similar APIs). The `Arc` here
303    /// indicates that there's some number of other stores holding this function
304    /// too, so dropping this may not deallocate the underlying
305    /// `InstanceHandle`.
306    SharedHost(Arc<HostFunc>),
307
308    /// A uniquely-owned host function within a `Store`. This comes about with
309    /// `Func::new` or similar APIs. The `HostFunc` internally owns the
310    /// `InstanceHandle` and that will get dropped when this `HostFunc` itself
311    /// is dropped.
312    ///
313    /// Note that this is intentionally placed behind a `Box` to minimize the
314    /// size of this enum since the most common variant for high-peformance
315    /// situations is `SharedHost` and `StoreOwned`, so this ideally isn't
316    /// larger than those two.
317    Host(Box<HostFunc>),
318
319    /// A reference to a `HostFunc`, but one that's "rooted" in the `Store`
320    /// itself.
321    ///
322    /// This variant is created when an `InstancePre<T>` is instantiated in to a
323    /// `Store<T>`. In that situation the `InstancePre<T>` already has a list of
324    /// host functions that are packaged up in an `Arc`, so the `Arc<[T]>` is
325    /// cloned once into the `Store` to avoid each individual function requiring
326    /// an `Arc::clone`.
327    ///
328    /// The lifetime management of this type is `unsafe` because
329    /// `RootedHostFunc` is a small wrapper around `NonNull<HostFunc>`. To be
330    /// safe this is required that the memory of the host function is pinned
331    /// elsewhere (e.g. the `Arc` in the `Store`).
332    RootedHost(RootedHostFunc),
333}
334
335macro_rules! for_each_function_signature {
336    ($mac:ident) => {
337        $mac!(0);
338        $mac!(1 A1);
339        $mac!(2 A1 A2);
340        $mac!(3 A1 A2 A3);
341        $mac!(4 A1 A2 A3 A4);
342        $mac!(5 A1 A2 A3 A4 A5);
343        $mac!(6 A1 A2 A3 A4 A5 A6);
344        $mac!(7 A1 A2 A3 A4 A5 A6 A7);
345        $mac!(8 A1 A2 A3 A4 A5 A6 A7 A8);
346        $mac!(9 A1 A2 A3 A4 A5 A6 A7 A8 A9);
347        $mac!(10 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10);
348        $mac!(11 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11);
349        $mac!(12 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12);
350        $mac!(13 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13);
351        $mac!(14 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14);
352        $mac!(15 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15);
353        $mac!(16 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16);
354    };
355}
356
357mod typed;
358pub use typed::*;
359
360macro_rules! generate_wrap_async_func {
361    ($num:tt $($args:ident)*) => (paste::paste!{
362        /// Same as [`Func::wrap`], except the closure asynchronously produces
363        /// its result. For more information see the [`Func`] documentation.
364        ///
365        /// # Panics
366        ///
367        /// This function will panic if called with a non-asynchronous store.
368        #[allow(non_snake_case)]
369        #[cfg(feature = "async")]
370        #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
371        pub fn [<wrap $num _async>]<T, $($args,)* R>(
372            store: impl AsContextMut<Data = T>,
373            func: impl for<'a> Fn(Caller<'a, T>, $($args),*) -> Box<dyn Future<Output = R> + Send + 'a> + Send + Sync + 'static,
374        ) -> Func
375        where
376            $($args: WasmTy,)*
377            R: WasmRet,
378        {
379            assert!(store.as_context().async_support(), concat!("cannot use `wrap", $num, "_async` without enabling async support on the config"));
380            Func::wrap(store, move |mut caller: Caller<'_, T>, $($args: $args),*| {
381                let async_cx = caller.store.as_context_mut().0.async_cx().expect("Attempt to start async function on dying fiber");
382                let mut future = Pin::from(func(caller, $($args),*));
383
384                match unsafe { async_cx.block_on(future.as_mut()) } {
385                    Ok(ret) => ret.into_fallible(),
386                    Err(e) => R::fallible_from_error(e),
387                }
388            })
389        }
390    })
391}
392
393impl Func {
394    /// Creates a new `Func` with the given arguments, typically to create a
395    /// host-defined function to pass as an import to a module.
396    ///
397    /// * `store` - the store in which to create this [`Func`], which will own
398    ///   the return value.
399    ///
400    /// * `ty` - the signature of this function, used to indicate what the
401    ///   inputs and outputs are.
402    ///
403    /// * `func` - the native code invoked whenever this `Func` will be called.
404    ///   This closure is provided a [`Caller`] as its first argument to learn
405    ///   information about the caller, and then it's passed a list of
406    ///   parameters as a slice along with a mutable slice of where to write
407    ///   results.
408    ///
409    /// Note that the implementation of `func` must adhere to the `ty` signature
410    /// given, error or traps may occur if it does not respect the `ty`
411    /// signature. For example if the function type declares that it returns one
412    /// i32 but the `func` closures does not write anything into the results
413    /// slice then a trap may be generated.
414    ///
415    /// Additionally note that this is quite a dynamic function since signatures
416    /// are not statically known. For a more performant and ergonomic `Func`
417    /// it's recommended to use [`Func::wrap`] if you can because with
418    /// statically known signatures Wasmtime can optimize the implementation
419    /// much more.
420    ///
421    /// For more information about `Send + Sync + 'static` requirements on the
422    /// `func`, see [`Func::wrap`](#why-send--sync--static).
423    ///
424    /// # Errors
425    ///
426    /// The host-provided function here returns a
427    /// [`Result<()>`](anyhow::Result). If the function returns `Ok(())` then
428    /// that indicates that the host function completed successfully and wrote
429    /// the result into the `&mut [Val]` argument.
430    ///
431    /// If the function returns `Err(e)`, however, then this is equivalent to
432    /// the host function triggering a trap for wasm. WebAssembly execution is
433    /// immediately halted and the original caller of [`Func::call`], for
434    /// example, will receive the error returned here (possibly with
435    /// [`WasmBacktrace`](crate::WasmBacktrace) context information attached).
436    ///
437    /// For more information about errors in Wasmtime see the [`Trap`]
438    /// documentation.
439    ///
440    /// [`Trap`]: crate::Trap
441    ///
442    /// # Panics
443    ///
444    /// Panics if the given function type is not associated with this store's
445    /// engine.
446    #[cfg(any(feature = "cranelift", feature = "winch"))]
447    #[cfg_attr(docsrs, doc(cfg(any(feature = "cranelift", feature = "winch"))))]
448    pub fn new<T>(
449        store: impl AsContextMut<Data = T>,
450        ty: FuncType,
451        func: impl Fn(Caller<'_, T>, &[Val], &mut [Val]) -> Result<()> + Send + Sync + 'static,
452    ) -> Self {
453        assert!(ty.comes_from_same_engine(store.as_context().engine()));
454        let ty_clone = ty.clone();
455        unsafe {
456            Func::new_unchecked(store, ty, move |caller, values| {
457                Func::invoke_host_func_for_wasm(caller, &ty_clone, values, &func)
458            })
459        }
460    }
461
462    /// Creates a new [`Func`] with the given arguments, although has fewer
463    /// runtime checks than [`Func::new`].
464    ///
465    /// This function takes a callback of a different signature than
466    /// [`Func::new`], instead receiving a raw pointer with a list of [`ValRaw`]
467    /// structures. These values have no type information associated with them
468    /// so it's up to the caller to provide a function that will correctly
469    /// interpret the list of values as those coming from the `ty` specified.
470    ///
471    /// If you're calling this from Rust it's recommended to either instead use
472    /// [`Func::new`] or [`Func::wrap`]. The [`Func::wrap`] API, in particular,
473    /// is both safer and faster than this API.
474    ///
475    /// # Errors
476    ///
477    /// See [`Func::new`] for the behavior of returning an error from the host
478    /// function provided here.
479    ///
480    /// # Unsafety
481    ///
482    /// This function is not safe because it's not known at compile time that
483    /// the `func` provided correctly interprets the argument types provided to
484    /// it, or that the results it produces will be of the correct type.
485    ///
486    /// # Panics
487    ///
488    /// Panics if the given function type is not associated with this store's
489    /// engine.
490    #[cfg(any(feature = "cranelift", feature = "winch"))]
491    #[cfg_attr(docsrs, doc(cfg(any(feature = "cranelift", feature = "winch"))))]
492    pub unsafe fn new_unchecked<T>(
493        mut store: impl AsContextMut<Data = T>,
494        ty: FuncType,
495        func: impl Fn(Caller<'_, T>, &mut [ValRaw]) -> Result<()> + Send + Sync + 'static,
496    ) -> Self {
497        assert!(ty.comes_from_same_engine(store.as_context().engine()));
498        let store = store.as_context_mut().0;
499        let host = HostFunc::new_unchecked(store.engine(), ty, func);
500        host.into_func(store)
501    }
502
503    /// Creates a new host-defined WebAssembly function which, when called,
504    /// will run the asynchronous computation defined by `func` to completion
505    /// and then return the result to WebAssembly.
506    ///
507    /// This function is the asynchronous analogue of [`Func::new`] and much of
508    /// that documentation applies to this as well. The key difference is that
509    /// `func` returns a future instead of simply a `Result`. Note that the
510    /// returned future can close over any of the arguments, but it cannot close
511    /// over the state of the closure itself. It's recommended to store any
512    /// necessary async state in the `T` of the [`Store<T>`](crate::Store) which
513    /// can be accessed through [`Caller::data`] or [`Caller::data_mut`].
514    ///
515    /// For more information on `Send + Sync + 'static`, see
516    /// [`Func::wrap`](#why-send--sync--static).
517    ///
518    /// # Panics
519    ///
520    /// This function will panic if `store` is not associated with an [async
521    /// config](crate::Config::async_support).
522    ///
523    /// Panics if the given function type is not associated with this store's
524    /// engine.
525    ///
526    /// # Errors
527    ///
528    /// See [`Func::new`] for the behavior of returning an error from the host
529    /// function provided here.
530    ///
531    /// # Examples
532    ///
533    /// ```
534    /// # use wasmtime::*;
535    /// # fn main() -> anyhow::Result<()> {
536    /// // Simulate some application-specific state as well as asynchronous
537    /// // functions to query that state.
538    /// struct MyDatabase {
539    ///     // ...
540    /// }
541    ///
542    /// impl MyDatabase {
543    ///     async fn get_row_count(&self) -> u32 {
544    ///         // ...
545    /// #       100
546    ///     }
547    /// }
548    ///
549    /// let my_database = MyDatabase {
550    ///     // ...
551    /// };
552    ///
553    /// // Using `new_async` we can hook up into calling our async
554    /// // `get_row_count` function.
555    /// let engine = Engine::new(Config::new().async_support(true))?;
556    /// let mut store = Store::new(&engine, MyDatabase {
557    ///     // ...
558    /// });
559    /// let get_row_count_type = wasmtime::FuncType::new(
560    ///     &engine,
561    ///     None,
562    ///     Some(wasmtime::ValType::I32),
563    /// );
564    /// let get = Func::new_async(&mut store, get_row_count_type, |caller, _params, results| {
565    ///     Box::new(async move {
566    ///         let count = caller.data().get_row_count().await;
567    ///         results[0] = Val::I32(count as i32);
568    ///         Ok(())
569    ///     })
570    /// });
571    /// // ...
572    /// # Ok(())
573    /// # }
574    /// ```
575    #[cfg(all(feature = "async", feature = "cranelift"))]
576    #[cfg_attr(docsrs, doc(cfg(all(feature = "async", feature = "cranelift"))))]
577    pub fn new_async<T, F>(store: impl AsContextMut<Data = T>, ty: FuncType, func: F) -> Func
578    where
579        F: for<'a> Fn(
580                Caller<'a, T>,
581                &'a [Val],
582                &'a mut [Val],
583            ) -> Box<dyn Future<Output = Result<()>> + Send + 'a>
584            + Send
585            + Sync
586            + 'static,
587    {
588        assert!(
589            store.as_context().async_support(),
590            "cannot use `new_async` without enabling async support in the config"
591        );
592        assert!(ty.comes_from_same_engine(store.as_context().engine()));
593        Func::new(store, ty, move |mut caller, params, results| {
594            let async_cx = caller
595                .store
596                .as_context_mut()
597                .0
598                .async_cx()
599                .expect("Attempt to spawn new action on dying fiber");
600            let mut future = Pin::from(func(caller, params, results));
601            match unsafe { async_cx.block_on(future.as_mut()) } {
602                Ok(Ok(())) => Ok(()),
603                Ok(Err(trap)) | Err(trap) => Err(trap),
604            }
605        })
606    }
607
608    pub(crate) unsafe fn from_vm_func_ref(
609        store: &mut StoreOpaque,
610        raw: *mut VMFuncRef,
611    ) -> Option<Func> {
612        let func_ref = NonNull::new(raw)?;
613        debug_assert!(func_ref.as_ref().type_index != VMSharedTypeIndex::default());
614        let export = ExportFunction { func_ref };
615        Some(Func::from_wasmtime_function(export, store))
616    }
617
618    /// Creates a new `Func` from the given Rust closure.
619    ///
620    /// This function will create a new `Func` which, when called, will
621    /// execute the given Rust closure. Unlike [`Func::new`] the target
622    /// function being called is known statically so the type signature can
623    /// be inferred. Rust types will map to WebAssembly types as follows:
624    ///
625    /// | Rust Argument Type                | WebAssembly Type                      |
626    /// |-----------------------------------|---------------------------------------|
627    /// | `i32`                             | `i32`                                 |
628    /// | `u32`                             | `i32`                                 |
629    /// | `i64`                             | `i64`                                 |
630    /// | `u64`                             | `i64`                                 |
631    /// | `f32`                             | `f32`                                 |
632    /// | `f64`                             | `f64`                                 |
633    /// | `V128` on x86-64 and aarch64 only | `v128`                                |
634    /// | `Option<Func>`                    | `funcref` aka `(ref null func)`       |
635    /// | `Func`                            | `(ref func)`                          |
636    /// | `Option<Nofunc>`                  | `nullfuncref` aka `(ref null nofunc)` |
637    /// | `NoFunc`                          | `(ref nofunc)`                        |
638    /// | `Option<ExternRef>`               | `externref` aka `(ref null extern)`   |
639    /// | `ExternRef`                       | `(ref extern)`                        |
640    /// | `Option<AnyRef>`                  | `anyref` aka `(ref null any)`         |
641    /// | `AnyRef`                          | `(ref any)`                           |
642    /// | `Option<I31>`                     | `i31ref` aka `(ref null i31)`         |
643    /// | `I31`                             | `(ref i31)`                           |
644    ///
645    /// Any of the Rust types can be returned from the closure as well, in
646    /// addition to some extra types
647    ///
648    /// | Rust Return Type  | WebAssembly Return Type | Meaning               |
649    /// |-------------------|-------------------------|-----------------------|
650    /// | `()`              | nothing                 | no return value       |
651    /// | `T`               | `T`                     | a single return value |
652    /// | `(T1, T2, ...)`   | `T1 T2 ...`             | multiple returns      |
653    ///
654    /// Note that all return types can also be wrapped in `Result<_>` to
655    /// indicate that the host function can generate a trap as well as possibly
656    /// returning a value.
657    ///
658    /// Finally you can also optionally take [`Caller`] as the first argument of
659    /// your closure. If inserted then you're able to inspect the caller's
660    /// state, for example the [`Memory`](crate::Memory) it has exported so you
661    /// can read what pointers point to.
662    ///
663    /// Note that when using this API, the intention is to create as thin of a
664    /// layer as possible for when WebAssembly calls the function provided. With
665    /// sufficient inlining and optimization the WebAssembly will call straight
666    /// into `func` provided, with no extra fluff entailed.
667    ///
668    /// # Why `Send + Sync + 'static`?
669    ///
670    /// All host functions defined in a [`Store`](crate::Store) (including
671    /// those from [`Func::new`] and other constructors) require that the
672    /// `func` provided is `Send + Sync + 'static`. Additionally host functions
673    /// always are `Fn` as opposed to `FnMut` or `FnOnce`. This can at-a-glance
674    /// feel restrictive since the closure cannot close over as many types as
675    /// before. The reason for this, though, is to ensure that
676    /// [`Store<T>`](crate::Store) can implement both the `Send` and `Sync`
677    /// traits.
678    ///
679    /// Fear not, however, because this isn't as restrictive as it seems! Host
680    /// functions are provided a [`Caller<'_, T>`](crate::Caller) argument which
681    /// allows access to the host-defined data within the
682    /// [`Store`](crate::Store). The `T` type is not required to be any of
683    /// `Send`, `Sync`, or `'static`! This means that you can store whatever
684    /// you'd like in `T` and have it accessible by all host functions.
685    /// Additionally mutable access to `T` is allowed through
686    /// [`Caller::data_mut`].
687    ///
688    /// Most host-defined [`Func`] values provide closures that end up not
689    /// actually closing over any values. These zero-sized types will use the
690    /// context from [`Caller`] for host-defined information.
691    ///
692    /// # Errors
693    ///
694    /// The closure provided here to `wrap` can optionally return a
695    /// [`Result<T>`](anyhow::Result). Returning `Ok(t)` represents the host
696    /// function successfully completing with the `t` result. Returning
697    /// `Err(e)`, however, is equivalent to raising a custom wasm trap.
698    /// Execution of WebAssembly does not resume and the stack is unwound to the
699    /// original caller of the function where the error is returned.
700    ///
701    /// For more information about errors in Wasmtime see the [`Trap`]
702    /// documentation.
703    ///
704    /// [`Trap`]: crate::Trap
705    ///
706    /// # Examples
707    ///
708    /// First up we can see how simple wasm imports can be implemented, such
709    /// as a function that adds its two arguments and returns the result.
710    ///
711    /// ```
712    /// # use wasmtime::*;
713    /// # fn main() -> anyhow::Result<()> {
714    /// # let mut store = Store::<()>::default();
715    /// let add = Func::wrap(&mut store, |a: i32, b: i32| a + b);
716    /// let module = Module::new(
717    ///     store.engine(),
718    ///     r#"
719    ///         (module
720    ///             (import "" "" (func $add (param i32 i32) (result i32)))
721    ///             (func (export "foo") (param i32 i32) (result i32)
722    ///                 local.get 0
723    ///                 local.get 1
724    ///                 call $add))
725    ///     "#,
726    /// )?;
727    /// let instance = Instance::new(&mut store, &module, &[add.into()])?;
728    /// let foo = instance.get_typed_func::<(i32, i32), i32>(&mut store, "foo")?;
729    /// assert_eq!(foo.call(&mut store, (1, 2))?, 3);
730    /// # Ok(())
731    /// # }
732    /// ```
733    ///
734    /// We can also do the same thing, but generate a trap if the addition
735    /// overflows:
736    ///
737    /// ```
738    /// # use wasmtime::*;
739    /// # fn main() -> anyhow::Result<()> {
740    /// # let mut store = Store::<()>::default();
741    /// let add = Func::wrap(&mut store, |a: i32, b: i32| {
742    ///     match a.checked_add(b) {
743    ///         Some(i) => Ok(i),
744    ///         None => anyhow::bail!("overflow"),
745    ///     }
746    /// });
747    /// let module = Module::new(
748    ///     store.engine(),
749    ///     r#"
750    ///         (module
751    ///             (import "" "" (func $add (param i32 i32) (result i32)))
752    ///             (func (export "foo") (param i32 i32) (result i32)
753    ///                 local.get 0
754    ///                 local.get 1
755    ///                 call $add))
756    ///     "#,
757    /// )?;
758    /// let instance = Instance::new(&mut store, &module, &[add.into()])?;
759    /// let foo = instance.get_typed_func::<(i32, i32), i32>(&mut store, "foo")?;
760    /// assert_eq!(foo.call(&mut store, (1, 2))?, 3);
761    /// assert!(foo.call(&mut store, (i32::max_value(), 1)).is_err());
762    /// # Ok(())
763    /// # }
764    /// ```
765    ///
766    /// And don't forget all the wasm types are supported!
767    ///
768    /// ```
769    /// # use wasmtime::*;
770    /// # fn main() -> anyhow::Result<()> {
771    /// # let mut store = Store::<()>::default();
772    /// let debug = Func::wrap(&mut store, |a: i32, b: u32, c: f32, d: i64, e: u64, f: f64| {
773    ///
774    ///     println!("a={}", a);
775    ///     println!("b={}", b);
776    ///     println!("c={}", c);
777    ///     println!("d={}", d);
778    ///     println!("e={}", e);
779    ///     println!("f={}", f);
780    /// });
781    /// let module = Module::new(
782    ///     store.engine(),
783    ///     r#"
784    ///         (module
785    ///             (import "" "" (func $debug (param i32 i32 f32 i64 i64 f64)))
786    ///             (func (export "foo")
787    ///                 i32.const -1
788    ///                 i32.const 1
789    ///                 f32.const 2
790    ///                 i64.const -3
791    ///                 i64.const 3
792    ///                 f64.const 4
793    ///                 call $debug))
794    ///     "#,
795    /// )?;
796    /// let instance = Instance::new(&mut store, &module, &[debug.into()])?;
797    /// let foo = instance.get_typed_func::<(), ()>(&mut store, "foo")?;
798    /// foo.call(&mut store, ())?;
799    /// # Ok(())
800    /// # }
801    /// ```
802    ///
803    /// Finally if you want to get really fancy you can also implement
804    /// imports that read/write wasm module's memory
805    ///
806    /// ```
807    /// use std::str;
808    ///
809    /// # use wasmtime::*;
810    /// # fn main() -> anyhow::Result<()> {
811    /// # let mut store = Store::default();
812    /// let log_str = Func::wrap(&mut store, |mut caller: Caller<'_, ()>, ptr: i32, len: i32| {
813    ///     let mem = match caller.get_export("memory") {
814    ///         Some(Extern::Memory(mem)) => mem,
815    ///         _ => anyhow::bail!("failed to find host memory"),
816    ///     };
817    ///     let data = mem.data(&caller)
818    ///         .get(ptr as u32 as usize..)
819    ///         .and_then(|arr| arr.get(..len as u32 as usize));
820    ///     let string = match data {
821    ///         Some(data) => match str::from_utf8(data) {
822    ///             Ok(s) => s,
823    ///             Err(_) => anyhow::bail!("invalid utf-8"),
824    ///         },
825    ///         None => anyhow::bail!("pointer/length out of bounds"),
826    ///     };
827    ///     assert_eq!(string, "Hello, world!");
828    ///     println!("{}", string);
829    ///     Ok(())
830    /// });
831    /// let module = Module::new(
832    ///     store.engine(),
833    ///     r#"
834    ///         (module
835    ///             (import "" "" (func $log_str (param i32 i32)))
836    ///             (func (export "foo")
837    ///                 i32.const 4   ;; ptr
838    ///                 i32.const 13  ;; len
839    ///                 call $log_str)
840    ///             (memory (export "memory") 1)
841    ///             (data (i32.const 4) "Hello, world!"))
842    ///     "#,
843    /// )?;
844    /// let instance = Instance::new(&mut store, &module, &[log_str.into()])?;
845    /// let foo = instance.get_typed_func::<(), ()>(&mut store, "foo")?;
846    /// foo.call(&mut store, ())?;
847    /// # Ok(())
848    /// # }
849    /// ```
850    pub fn wrap<T, Params, Results>(
851        mut store: impl AsContextMut<Data = T>,
852        func: impl IntoFunc<T, Params, Results>,
853    ) -> Func {
854        let store = store.as_context_mut().0;
855        // part of this unsafety is about matching the `T` to a `Store<T>`,
856        // which is done through the `AsContextMut` bound above.
857        unsafe {
858            let host = HostFunc::wrap(store.engine(), func);
859            host.into_func(store)
860        }
861    }
862
863    for_each_function_signature!(generate_wrap_async_func);
864
865    /// Returns the underlying wasm type that this `Func` has.
866    ///
867    /// # Panics
868    ///
869    /// Panics if `store` does not own this function.
870    pub fn ty(&self, store: impl AsContext) -> FuncType {
871        self.load_ty(&store.as_context().0)
872    }
873
874    /// Forcibly loads the type of this function from the `Engine`.
875    ///
876    /// Note that this is a somewhat expensive method since it requires taking a
877    /// lock as well as cloning a type.
878    pub(crate) fn load_ty(&self, store: &StoreOpaque) -> FuncType {
879        assert!(self.comes_from_same_store(store));
880        FuncType::from_shared_type_index(store.engine(), self.type_index(store.store_data()))
881    }
882
883    /// Does this function match the given type?
884    ///
885    /// That is, is this function's type a subtype of the given type?
886    pub fn matches_ty(&self, store: impl AsContext, func_ty: &FuncType) -> bool {
887        self._matches_ty(store.as_context().0, func_ty)
888    }
889
890    pub(crate) fn _matches_ty(&self, store: &StoreOpaque, func_ty: &FuncType) -> bool {
891        let actual_ty = self.load_ty(store);
892        actual_ty.matches(func_ty)
893    }
894
895    pub(crate) fn ensure_matches_ty(&self, store: &StoreOpaque, func_ty: &FuncType) -> Result<()> {
896        if !self.comes_from_same_store(store) {
897            bail!("function used with wrong store");
898        }
899        if self._matches_ty(store, func_ty) {
900            Ok(())
901        } else {
902            let actual_ty = self.load_ty(store);
903            bail!("type mismatch: expected {func_ty}, found {actual_ty}")
904        }
905    }
906
907    /// Gets a reference to the `FuncType` for this function.
908    ///
909    /// Note that this returns both a reference to the type of this function as
910    /// well as a reference back to the store itself. This enables using the
911    /// `StoreOpaque` while the `FuncType` is also being used (from the
912    /// perspective of the borrow-checker) because otherwise the signature would
913    /// consider `StoreOpaque` borrowed mutable while `FuncType` is in use.
914    fn ty_ref<'a>(&self, store: &'a mut StoreOpaque) -> (&'a FuncType, &'a StoreOpaque) {
915        // If we haven't loaded our type into the store yet then do so lazily at
916        // this time.
917        if store.store_data()[self.0].ty.is_none() {
918            let ty = self.load_ty(store);
919            store.store_data_mut()[self.0].ty = Some(Box::new(ty));
920        }
921
922        (store.store_data()[self.0].ty.as_ref().unwrap(), store)
923    }
924
925    pub(crate) fn type_index(&self, data: &StoreData) -> VMSharedTypeIndex {
926        data[self.0].sig_index()
927    }
928
929    /// Invokes this function with the `params` given and writes returned values
930    /// to `results`.
931    ///
932    /// The `params` here must match the type signature of this `Func`, or an
933    /// error will occur. Additionally `results` must have the same
934    /// length as the number of results for this function. Calling this function
935    /// will synchronously execute the WebAssembly function referenced to get
936    /// the results.
937    ///
938    /// This function will return `Ok(())` if execution completed without a trap
939    /// or error of any kind. In this situation the results will be written to
940    /// the provided `results` array.
941    ///
942    /// # Errors
943    ///
944    /// Any error which occurs throughout the execution of the function will be
945    /// returned as `Err(e)`. The [`Error`](anyhow::Error) type can be inspected
946    /// for the precise error cause such as:
947    ///
948    /// * [`Trap`] - indicates that a wasm trap happened and execution was
949    ///   halted.
950    /// * [`WasmBacktrace`] - optionally included on errors for backtrace
951    ///   information of the trap/error.
952    /// * Other string-based errors to indicate issues such as type errors with
953    ///   `params`.
954    /// * Any host-originating error originally returned from a function defined
955    ///   via [`Func::new`], for example.
956    ///
957    /// Errors typically indicate that execution of WebAssembly was halted
958    /// mid-way and did not complete after the error condition happened.
959    ///
960    /// [`Trap`]: crate::Trap
961    ///
962    /// # Panics
963    ///
964    /// This function will panic if called on a function belonging to an async
965    /// store. Asynchronous stores must always use `call_async`.
966    /// initiates a panic. Also panics if `store` does not own this function.
967    ///
968    /// [`WasmBacktrace`]: crate::WasmBacktrace
969    pub fn call(
970        &self,
971        mut store: impl AsContextMut,
972        params: &[Val],
973        results: &mut [Val],
974    ) -> Result<()> {
975        assert!(
976            !store.as_context().async_support(),
977            "must use `call_async` when async support is enabled on the config",
978        );
979        let mut store = store.as_context_mut();
980        let need_gc = self.call_impl_check_args(&mut store, params, results)?;
981        if need_gc {
982            store.0.gc();
983        }
984        unsafe { self.call_impl_do_call(&mut store, params, results) }
985    }
986
987    /// Invokes this function in an "unchecked" fashion, reading parameters and
988    /// writing results to `params_and_returns`.
989    ///
990    /// This function is the same as [`Func::call`] except that the arguments
991    /// and results both use a different representation. If possible it's
992    /// recommended to use [`Func::call`] if safety isn't necessary or to use
993    /// [`Func::typed`] in conjunction with [`TypedFunc::call`] since that's
994    /// both safer and faster than this method of invoking a function.
995    ///
996    /// Note that if this function takes `externref` arguments then it will
997    /// **not** automatically GC unlike the [`Func::call`] and
998    /// [`TypedFunc::call`] functions. This means that if this function is
999    /// invoked many times with new `ExternRef` values and no other GC happens
1000    /// via any other means then no values will get collected.
1001    ///
1002    /// # Errors
1003    ///
1004    /// For more information about errors see the [`Func::call`] documentation.
1005    ///
1006    /// # Unsafety
1007    ///
1008    /// This function is unsafe because the `params_and_returns` argument is not
1009    /// validated at all. It must uphold invariants such as:
1010    ///
1011    /// * It's a valid pointer to an array
1012    /// * It has enough space to store all parameters
1013    /// * It has enough space to store all results (not at the same time as
1014    ///   parameters)
1015    /// * Parameters are initially written to the array and have the correct
1016    ///   types and such.
1017    /// * Reference types like `externref` and `funcref` are valid at the
1018    ///   time of this call and for the `store` specified.
1019    ///
1020    /// These invariants are all upheld for you with [`Func::call`] and
1021    /// [`TypedFunc::call`].
1022    pub unsafe fn call_unchecked(
1023        &self,
1024        mut store: impl AsContextMut,
1025        params_and_returns: *mut ValRaw,
1026        params_and_returns_capacity: usize,
1027    ) -> Result<()> {
1028        let mut store = store.as_context_mut();
1029        let data = &store.0.store_data()[self.0];
1030        let func_ref = data.export().func_ref;
1031        Self::call_unchecked_raw(
1032            &mut store,
1033            func_ref,
1034            params_and_returns,
1035            params_and_returns_capacity,
1036        )
1037    }
1038
1039    pub(crate) unsafe fn call_unchecked_raw<T>(
1040        store: &mut StoreContextMut<'_, T>,
1041        func_ref: NonNull<VMFuncRef>,
1042        params_and_returns: *mut ValRaw,
1043        params_and_returns_capacity: usize,
1044    ) -> Result<()> {
1045        invoke_wasm_and_catch_traps(store, |caller| {
1046            let func_ref = func_ref.as_ref();
1047            (func_ref.array_call)(
1048                func_ref.vmctx,
1049                caller.cast::<VMOpaqueContext>(),
1050                params_and_returns,
1051                params_and_returns_capacity,
1052            )
1053        })
1054    }
1055
1056    /// Converts the raw representation of a `funcref` into an `Option<Func>`
1057    ///
1058    /// This is intended to be used in conjunction with [`Func::new_unchecked`],
1059    /// [`Func::call_unchecked`], and [`ValRaw`] with its `funcref` field.
1060    ///
1061    /// # Unsafety
1062    ///
1063    /// This function is not safe because `raw` is not validated at all. The
1064    /// caller must guarantee that `raw` is owned by the `store` provided and is
1065    /// valid within the `store`.
1066    pub unsafe fn from_raw(mut store: impl AsContextMut, raw: *mut c_void) -> Option<Func> {
1067        Self::_from_raw(store.as_context_mut().0, raw)
1068    }
1069
1070    pub(crate) unsafe fn _from_raw(store: &mut StoreOpaque, raw: *mut c_void) -> Option<Func> {
1071        Func::from_vm_func_ref(store, raw.cast())
1072    }
1073
1074    /// Extracts the raw value of this `Func`, which is owned by `store`.
1075    ///
1076    /// This function returns a value that's suitable for writing into the
1077    /// `funcref` field of the [`ValRaw`] structure.
1078    ///
1079    /// # Unsafety
1080    ///
1081    /// The returned value is only valid for as long as the store is alive and
1082    /// this function is properly rooted within it. Additionally this function
1083    /// should not be liberally used since it's a very low-level knob.
1084    pub unsafe fn to_raw(&self, mut store: impl AsContextMut) -> *mut c_void {
1085        self.vm_func_ref(store.as_context_mut().0).as_ptr().cast()
1086    }
1087
1088    /// Invokes this function with the `params` given, returning the results
1089    /// asynchronously.
1090    ///
1091    /// This function is the same as [`Func::call`] except that it is
1092    /// asynchronous. This is only compatible with stores associated with an
1093    /// [asynchronous config](crate::Config::async_support).
1094    ///
1095    /// It's important to note that the execution of WebAssembly will happen
1096    /// synchronously in the `poll` method of the future returned from this
1097    /// function. Wasmtime does not manage its own thread pool or similar to
1098    /// execute WebAssembly in. Future `poll` methods are generally expected to
1099    /// resolve quickly, so it's recommended that you run or poll this future
1100    /// in a "blocking context".
1101    ///
1102    /// For more information see the documentation on [asynchronous
1103    /// configs](crate::Config::async_support).
1104    ///
1105    /// # Errors
1106    ///
1107    /// For more information on errors see the [`Func::call`] documentation.
1108    ///
1109    /// # Panics
1110    ///
1111    /// Panics if this is called on a function in a synchronous store. This
1112    /// only works with functions defined within an asynchronous store. Also
1113    /// panics if `store` does not own this function.
1114    #[cfg(feature = "async")]
1115    #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
1116    pub async fn call_async<T>(
1117        &self,
1118        mut store: impl AsContextMut<Data = T>,
1119        params: &[Val],
1120        results: &mut [Val],
1121    ) -> Result<()>
1122    where
1123        T: Send,
1124    {
1125        let mut store = store.as_context_mut();
1126        assert!(
1127            store.0.async_support(),
1128            "cannot use `call_async` without enabling async support in the config",
1129        );
1130        let need_gc = self.call_impl_check_args(&mut store, params, results)?;
1131        if need_gc {
1132            store.0.gc_async().await;
1133        }
1134        let result = store
1135            .on_fiber(|store| unsafe { self.call_impl_do_call(store, params, results) })
1136            .await??;
1137        Ok(result)
1138    }
1139
1140    /// Perform dynamic checks that the arguments given to us match
1141    /// the signature of this function and are appropriate to pass to this
1142    /// function.
1143    ///
1144    /// This involves checking to make sure we have the right number and types
1145    /// of arguments as well as making sure everything is from the same `Store`.
1146    ///
1147    /// This must be called just before `call_impl_do_call`.
1148    ///
1149    /// Returns whether we need to GC before calling `call_impl_do_call`.
1150    fn call_impl_check_args<T>(
1151        &self,
1152        store: &mut StoreContextMut<'_, T>,
1153        params: &[Val],
1154        results: &mut [Val],
1155    ) -> Result<bool> {
1156        let (ty, opaque) = self.ty_ref(store.0);
1157        if ty.params().len() != params.len() {
1158            bail!(
1159                "expected {} arguments, got {}",
1160                ty.params().len(),
1161                params.len()
1162            );
1163        }
1164        if ty.results().len() != results.len() {
1165            bail!(
1166                "expected {} results, got {}",
1167                ty.results().len(),
1168                results.len()
1169            );
1170        }
1171        for (ty, arg) in ty.params().zip(params) {
1172            arg.ensure_matches_ty(opaque, &ty)
1173                .context("argument type mismatch")?;
1174            if !arg.comes_from_same_store(opaque) {
1175                bail!("cross-`Store` values are not currently supported");
1176            }
1177        }
1178
1179        #[cfg(feature = "gc")]
1180        {
1181            // Check whether we need to GC before calling into Wasm.
1182            //
1183            // For example, with the DRC collector, whenever we pass GC refs
1184            // from host code to Wasm code, they go into the
1185            // `VMGcRefActivationsTable`. But the table might be at capacity
1186            // already. If it is at capacity (unlikely) then we need to do a GC
1187            // to free up space.
1188            let num_gc_refs = ty.as_wasm_func_type().non_i31_gc_ref_params_count();
1189            if let Some(num_gc_refs) = NonZeroUsize::new(num_gc_refs) {
1190                return Ok(opaque
1191                    .gc_store()?
1192                    .gc_heap
1193                    .need_gc_before_entering_wasm(num_gc_refs));
1194            }
1195        }
1196
1197        Ok(false)
1198    }
1199
1200    /// Do the actual call into Wasm.
1201    ///
1202    /// # Safety
1203    ///
1204    /// You must have type checked the arguments by calling
1205    /// `call_impl_check_args` immediately before calling this function. It is
1206    /// only safe to call this function if that one did not return an error.
1207    unsafe fn call_impl_do_call<T>(
1208        &self,
1209        store: &mut StoreContextMut<'_, T>,
1210        params: &[Val],
1211        results: &mut [Val],
1212    ) -> Result<()> {
1213        // Store the argument values into `values_vec`.
1214        let (ty, _) = self.ty_ref(store.0);
1215        let values_vec_size = params.len().max(ty.results().len());
1216        let mut values_vec = store.0.take_wasm_val_raw_storage();
1217        debug_assert!(values_vec.is_empty());
1218        values_vec.resize_with(values_vec_size, || ValRaw::v128(0));
1219        for (arg, slot) in params.iter().cloned().zip(&mut values_vec) {
1220            unsafe {
1221                *slot = arg.to_raw(&mut *store)?;
1222            }
1223        }
1224
1225        unsafe {
1226            self.call_unchecked(&mut *store, values_vec.as_mut_ptr(), values_vec_size)?;
1227        }
1228
1229        for ((i, slot), val) in results.iter_mut().enumerate().zip(&values_vec) {
1230            let ty = self.ty_ref(store.0).0.results().nth(i).unwrap();
1231            *slot = unsafe { Val::from_raw(&mut *store, *val, ty) };
1232        }
1233        values_vec.truncate(0);
1234        store.0.save_wasm_val_raw_storage(values_vec);
1235        Ok(())
1236    }
1237
1238    #[inline]
1239    pub(crate) fn vm_func_ref(&self, store: &mut StoreOpaque) -> NonNull<VMFuncRef> {
1240        let func_data = &mut store.store_data_mut()[self.0];
1241        let func_ref = func_data.export().func_ref;
1242        if unsafe { func_ref.as_ref().wasm_call.is_some() } {
1243            return func_ref;
1244        }
1245
1246        if let Some(in_store) = func_data.in_store_func_ref {
1247            in_store.as_non_null()
1248        } else {
1249            unsafe {
1250                // Move this uncommon/slow path out of line.
1251                self.copy_func_ref_into_store_and_fill(store, func_ref)
1252            }
1253        }
1254    }
1255
1256    unsafe fn copy_func_ref_into_store_and_fill(
1257        &self,
1258        store: &mut StoreOpaque,
1259        func_ref: NonNull<VMFuncRef>,
1260    ) -> NonNull<VMFuncRef> {
1261        let func_ref = store.func_refs().push(func_ref.as_ref().clone());
1262        store.store_data_mut()[self.0].in_store_func_ref = Some(SendSyncPtr::new(func_ref));
1263        store.fill_func_refs();
1264        func_ref
1265    }
1266
1267    pub(crate) unsafe fn from_wasmtime_function(
1268        export: ExportFunction,
1269        store: &mut StoreOpaque,
1270    ) -> Self {
1271        Func::from_func_kind(FuncKind::StoreOwned { export }, store)
1272    }
1273
1274    fn from_func_kind(kind: FuncKind, store: &mut StoreOpaque) -> Self {
1275        Func(store.store_data_mut().insert(FuncData {
1276            kind,
1277            in_store_func_ref: None,
1278            ty: None,
1279        }))
1280    }
1281
1282    pub(crate) fn vmimport(&self, store: &mut StoreOpaque, module: &Module) -> VMFunctionImport {
1283        unsafe {
1284            let f = {
1285                let func_data = &mut store.store_data_mut()[self.0];
1286                // If we already patched this `funcref.wasm_call` and saved a
1287                // copy in the store, use the patched version. Otherwise, use
1288                // the potentially un-patched version.
1289                if let Some(func_ref) = func_data.in_store_func_ref {
1290                    func_ref.as_non_null()
1291                } else {
1292                    func_data.export().func_ref
1293                }
1294            };
1295            VMFunctionImport {
1296                wasm_call: if let Some(wasm_call) = f.as_ref().wasm_call {
1297                    wasm_call
1298                } else {
1299                    // Assert that this is a native-call function, since those
1300                    // are the only ones that could be missing a `wasm_call`
1301                    // trampoline.
1302                    let _ = VMNativeCallHostFuncContext::from_opaque(f.as_ref().vmctx);
1303
1304                    let sig = self.type_index(store.store_data());
1305                    module.runtime_info().wasm_to_native_trampoline(sig).expect(
1306                        "must have a wasm-to-native trampoline for this signature if the Wasm \
1307                         module is importing a function of this signature",
1308                    )
1309                },
1310                native_call: f.as_ref().native_call,
1311                array_call: f.as_ref().array_call,
1312                vmctx: f.as_ref().vmctx,
1313            }
1314        }
1315    }
1316
1317    pub(crate) fn comes_from_same_store(&self, store: &StoreOpaque) -> bool {
1318        store.store_data().contains(self.0)
1319    }
1320
1321    fn invoke_host_func_for_wasm<T>(
1322        mut caller: Caller<'_, T>,
1323        ty: &FuncType,
1324        values_vec: &mut [ValRaw],
1325        func: &dyn Fn(Caller<'_, T>, &[Val], &mut [Val]) -> Result<()>,
1326    ) -> Result<()> {
1327        // Translate the raw JIT arguments in `values_vec` into a `Val` which
1328        // we'll be passing as a slice. The storage for our slice-of-`Val` we'll
1329        // be taking from the `Store`. We preserve our slice back into the
1330        // `Store` after the hostcall, ideally amortizing the cost of allocating
1331        // the storage across wasm->host calls.
1332        //
1333        // Note that we have a dynamic guarantee that `values_vec` is the
1334        // appropriate length to both read all arguments from as well as store
1335        // all results into.
1336        let mut val_vec = caller.store.0.take_hostcall_val_storage();
1337        debug_assert!(val_vec.is_empty());
1338        let nparams = ty.params().len();
1339        val_vec.reserve(nparams + ty.results().len());
1340        for (i, ty) in ty.params().enumerate() {
1341            val_vec.push(unsafe { Val::from_raw(&mut caller.store, values_vec[i], ty) })
1342        }
1343
1344        val_vec.extend((0..ty.results().len()).map(|_| Val::null_func_ref()));
1345        let (params, results) = val_vec.split_at_mut(nparams);
1346        func(caller.sub_caller(), params, results)?;
1347
1348        // Unlike our arguments we need to dynamically check that the return
1349        // values produced are correct. There could be a bug in `func` that
1350        // produces the wrong number, wrong types, or wrong stores of
1351        // values, and we need to catch that here.
1352        for (i, (ret, ty)) in results.iter().zip(ty.results()).enumerate() {
1353            ret.ensure_matches_ty(caller.store.0, &ty)
1354                .context("function attempted to return an incompatible value")?;
1355            unsafe {
1356                values_vec[i] = ret.to_raw(&mut caller.store)?;
1357            }
1358        }
1359
1360        // Restore our `val_vec` back into the store so it's usable for the next
1361        // hostcall to reuse our own storage.
1362        val_vec.truncate(0);
1363        caller.store.0.save_hostcall_val_storage(val_vec);
1364        Ok(())
1365    }
1366
1367    /// Attempts to extract a typed object from this `Func` through which the
1368    /// function can be called.
1369    ///
1370    /// This function serves as an alternative to [`Func::call`] and
1371    /// [`Func::call_async`]. This method performs a static type check (using
1372    /// the `Params` and `Results` type parameters on the underlying wasm
1373    /// function. If the type check passes then a `TypedFunc` object is returned,
1374    /// otherwise an error is returned describing the typecheck failure.
1375    ///
1376    /// The purpose of this relative to [`Func::call`] is that it's much more
1377    /// efficient when used to invoke WebAssembly functions. With the types
1378    /// statically known far less setup/teardown is required when invoking
1379    /// WebAssembly. If speed is desired then this function is recommended to be
1380    /// used instead of [`Func::call`] (which is more general, hence its
1381    /// slowdown).
1382    ///
1383    /// The `Params` type parameter is used to describe the parameters of the
1384    /// WebAssembly function. This can either be a single type (like `i32`), or
1385    /// a tuple of types representing the list of parameters (like `(i32, f32,
1386    /// f64)`). Additionally you can use `()` to represent that the function has
1387    /// no parameters.
1388    ///
1389    /// The `Results` type parameter is used to describe the results of the
1390    /// function. This behaves the same way as `Params`, but just for the
1391    /// results of the function.
1392    ///
1393    /// # Translating Between WebAssembly and Rust Types
1394    ///
1395    /// Translation between Rust types and WebAssembly types looks like:
1396    ///
1397    /// | WebAssembly                           | Rust                                  |
1398    /// |---------------------------------------|---------------------------------------|
1399    /// | `i32`                                 | `i32` or `u32`                        |
1400    /// | `i64`                                 | `i64` or `u64`                        |
1401    /// | `f32`                                 | `f32`                                 |
1402    /// | `f64`                                 | `f64`                                 |
1403    /// | `externref` aka `(ref null extern)`   | `Option<ExternRef>`                   |
1404    /// | `(ref extern)`                        | `ExternRef`                           |
1405    /// | `anyref` aka `(ref null any)`         | `Option<AnyRef>`                      |
1406    /// | `(ref any)`                           | `AnyRef`                              |
1407    /// | `i31ref` aka `(ref null i31)`         | `Option<I31>`                         |
1408    /// | `(ref i31)`                           | `I31`                                 |
1409    /// | `funcref` aka `(ref null func)`       | `Option<Func>`                        |
1410    /// | `(ref func)`                          | `Func`                                |
1411    /// | `(ref null <func type index>)`        | `Option<Func>`                        |
1412    /// | `(ref <func type index>)`             | `Func`                                |
1413    /// | `nullfuncref` aka `(ref null nofunc)` | `Option<NoFunc>`                      |
1414    /// | `(ref nofunc)`                        | `NoFunc`                              |
1415    /// | `v128`                                | `V128` on `x86-64` and `aarch64` only |
1416    ///
1417    /// (Note that this mapping is the same as that of [`Func::wrap`]).
1418    ///
1419    /// Note that once the [`TypedFunc`] return value is acquired you'll use either
1420    /// [`TypedFunc::call`] or [`TypedFunc::call_async`] as necessary to actually invoke
1421    /// the function. This method does not invoke any WebAssembly code, it
1422    /// simply performs a typecheck before returning the [`TypedFunc`] value.
1423    ///
1424    /// This method also has a convenience wrapper as
1425    /// [`Instance::get_typed_func`](crate::Instance::get_typed_func) to
1426    /// directly get a typed function value from an
1427    /// [`Instance`](crate::Instance).
1428    ///
1429    /// ## Subtyping
1430    ///
1431    /// For result types, you can always use a supertype of the WebAssembly
1432    /// function's actual declared result type. For example, if the WebAssembly
1433    /// function was declared with type `(func (result nullfuncref))` you could
1434    /// successfully call `f.typed::<(), Option<Func>>()` because `Option<Func>`
1435    /// corresponds to `funcref`, which is a supertype of `nullfuncref`.
1436    ///
1437    /// For parameter types, you can always use a subtype of the WebAssembly
1438    /// function's actual declared parameter type. For example, if the
1439    /// WebAssembly function was declared with type `(func (param (ref null
1440    /// func)))` you could successfully call `f.typed::<Func, ()>()` because
1441    /// `Func` corresponds to `(ref func)`, which is a subtype of `(ref null
1442    /// func)`.
1443    ///
1444    /// Additionally, for functions which take a reference to a concrete type as
1445    /// a parameter, you can also use the concrete type's supertype. Consider a
1446    /// WebAssembly function that takes a reference to a function with a
1447    /// concrete type: `(ref null <func type index>)`. In this scenario, there
1448    /// is no static `wasmtime::Foo` Rust type that corresponds to that
1449    /// particular Wasm-defined concrete reference type because Wasm modules are
1450    /// loaded dynamically at runtime. You *could* do `f.typed::<Option<NoFunc>,
1451    /// ()>()`, and while that is correctly typed and valid, it is often overly
1452    /// restrictive. The only value you could call the resulting typed function
1453    /// with is the null function reference, but we'd like to call it with
1454    /// non-null function references that happen to be of the correct
1455    /// type. Therefore, `f.typed<Option<Func>, ()>()` is also allowed in this
1456    /// case, even though `Option<Func>` represents `(ref null func)` which is
1457    /// the supertype, not subtype, of `(ref null <func type index>)`. This does
1458    /// imply some minimal dynamic type checks in this case, but it is supported
1459    /// for better ergonomics, to enable passing non-null references into the
1460    /// function.
1461    ///
1462    /// # Errors
1463    ///
1464    /// This function will return an error if `Params` or `Results` does not
1465    /// match the native type of this WebAssembly function.
1466    ///
1467    /// # Panics
1468    ///
1469    /// This method will panic if `store` does not own this function.
1470    ///
1471    /// # Examples
1472    ///
1473    /// An end-to-end example of calling a function which takes no parameters
1474    /// and has no results:
1475    ///
1476    /// ```
1477    /// # use wasmtime::*;
1478    /// # fn main() -> anyhow::Result<()> {
1479    /// let engine = Engine::default();
1480    /// let mut store = Store::new(&engine, ());
1481    /// let module = Module::new(&engine, r#"(module (func (export "foo")))"#)?;
1482    /// let instance = Instance::new(&mut store, &module, &[])?;
1483    /// let foo = instance.get_func(&mut store, "foo").expect("export wasn't a function");
1484    ///
1485    /// // Note that this call can fail due to the typecheck not passing, but
1486    /// // in our case we statically know the module so we know this should
1487    /// // pass.
1488    /// let typed = foo.typed::<(), ()>(&store)?;
1489    ///
1490    /// // Note that this can fail if the wasm traps at runtime.
1491    /// typed.call(&mut store, ())?;
1492    /// # Ok(())
1493    /// # }
1494    /// ```
1495    ///
1496    /// You can also pass in multiple parameters and get a result back
1497    ///
1498    /// ```
1499    /// # use wasmtime::*;
1500    /// # fn foo(add: &Func, mut store: Store<()>) -> anyhow::Result<()> {
1501    /// let typed = add.typed::<(i32, i64), f32>(&store)?;
1502    /// assert_eq!(typed.call(&mut store, (1, 2))?, 3.0);
1503    /// # Ok(())
1504    /// # }
1505    /// ```
1506    ///
1507    /// and similarly if a function has multiple results you can bind that too
1508    ///
1509    /// ```
1510    /// # use wasmtime::*;
1511    /// # fn foo(add_with_overflow: &Func, mut store: Store<()>) -> anyhow::Result<()> {
1512    /// let typed = add_with_overflow.typed::<(u32, u32), (u32, i32)>(&store)?;
1513    /// let (result, overflow) = typed.call(&mut store, (u32::max_value(), 2))?;
1514    /// assert_eq!(result, 1);
1515    /// assert_eq!(overflow, 1);
1516    /// # Ok(())
1517    /// # }
1518    /// ```
1519    pub fn typed<Params, Results>(
1520        &self,
1521        store: impl AsContext,
1522    ) -> Result<TypedFunc<Params, Results>>
1523    where
1524        Params: WasmParams,
1525        Results: WasmResults,
1526    {
1527        // Type-check that the params/results are all valid
1528        let store = store.as_context().0;
1529        let ty = self.load_ty(store);
1530        Params::typecheck(store.engine(), ty.params(), TypeCheckPosition::Param)
1531            .context("type mismatch with parameters")?;
1532        Results::typecheck(store.engine(), ty.results(), TypeCheckPosition::Result)
1533            .context("type mismatch with results")?;
1534
1535        // and then we can construct the typed version of this function
1536        // (unsafely), which should be safe since we just did the type check above.
1537        unsafe { Ok(TypedFunc::_new_unchecked(store, *self)) }
1538    }
1539
1540    /// Get a stable hash key for this function.
1541    ///
1542    /// Even if the same underlying function is added to the `StoreData`
1543    /// multiple times and becomes multiple `wasmtime::Func`s, this hash key
1544    /// will be consistent across all of these functions.
1545    #[allow(dead_code)] // Not used yet, but added for consistency.
1546    pub(crate) fn hash_key(&self, store: &mut StoreOpaque) -> impl std::hash::Hash + Eq {
1547        self.vm_func_ref(store).as_ptr() as usize
1548    }
1549}
1550
1551/// Prepares for entrance into WebAssembly.
1552///
1553/// This function will set up context such that `closure` is allowed to call a
1554/// raw trampoline or a raw WebAssembly function. This *must* be called to do
1555/// things like catch traps and set up GC properly.
1556///
1557/// The `closure` provided receives a default "caller" `VMContext` parameter it
1558/// can pass to the called wasm function, if desired.
1559pub(crate) fn invoke_wasm_and_catch_traps<T>(
1560    store: &mut StoreContextMut<'_, T>,
1561    closure: impl FnMut(*mut VMContext),
1562) -> Result<()> {
1563    unsafe {
1564        let exit = enter_wasm(store);
1565
1566        if let Err(trap) = store.0.call_hook(CallHook::CallingWasm) {
1567            exit_wasm(store, exit);
1568            return Err(trap);
1569        }
1570        let result = wasmtime_runtime::catch_traps(
1571            store.0.signal_handler(),
1572            store.0.engine().config().wasm_backtrace,
1573            store.0.engine().config().coredump_on_trap,
1574            store.0.default_caller(),
1575            closure,
1576        );
1577        exit_wasm(store, exit);
1578        store.0.call_hook(CallHook::ReturningFromWasm)?;
1579        result.map_err(|t| crate::trap::from_runtime_box(store.0, t))
1580    }
1581}
1582
1583/// This function is called to register state within `Store` whenever
1584/// WebAssembly is entered within the `Store`.
1585///
1586/// This function sets up various limits such as:
1587///
1588/// * The stack limit. This is what ensures that we limit the stack space
1589///   allocated by WebAssembly code and it's relative to the initial stack
1590///   pointer that called into wasm.
1591///
1592/// This function may fail if the the stack limit can't be set because an
1593/// interrupt already happened.
1594fn enter_wasm<T>(store: &mut StoreContextMut<'_, T>) -> Option<usize> {
1595    // If this is a recursive call, e.g. our stack limit is already set, then
1596    // we may be able to skip this function.
1597    //
1598    // For synchronous stores there's nothing else to do because all wasm calls
1599    // happen synchronously and on the same stack. This means that the previous
1600    // stack limit will suffice for the next recursive call.
1601    //
1602    // For asynchronous stores then each call happens on a separate native
1603    // stack. This means that the previous stack limit is no longer relevant
1604    // because we're on a separate stack.
1605    if unsafe { *store.0.runtime_limits().stack_limit.get() } != usize::MAX
1606        && !store.0.async_support()
1607    {
1608        return None;
1609    }
1610
1611    // Ignore this stack pointer business on miri since we can't execute wasm
1612    // anyway and the concept of a stack pointer on miri is a bit nebulous
1613    // regardless.
1614    if cfg!(miri) {
1615        return None;
1616    }
1617
1618    let stack_pointer = wasmtime_runtime::get_stack_pointer();
1619
1620    // Determine the stack pointer where, after which, any wasm code will
1621    // immediately trap. This is checked on the entry to all wasm functions.
1622    //
1623    // Note that this isn't 100% precise. We are requested to give wasm
1624    // `max_wasm_stack` bytes, but what we're actually doing is giving wasm
1625    // probably a little less than `max_wasm_stack` because we're
1626    // calculating the limit relative to this function's approximate stack
1627    // pointer. Wasm will be executed on a frame beneath this one (or next
1628    // to it). In any case it's expected to be at most a few hundred bytes
1629    // of slop one way or another. When wasm is typically given a MB or so
1630    // (a million bytes) the slop shouldn't matter too much.
1631    //
1632    // After we've got the stack limit then we store it into the `stack_limit`
1633    // variable.
1634    let wasm_stack_limit = stack_pointer - store.engine().config().max_wasm_stack;
1635    let prev_stack = unsafe {
1636        mem::replace(
1637            &mut *store.0.runtime_limits().stack_limit.get(),
1638            wasm_stack_limit,
1639        )
1640    };
1641
1642    Some(prev_stack)
1643}
1644
1645fn exit_wasm<T>(store: &mut StoreContextMut<'_, T>, prev_stack: Option<usize>) {
1646    // If we don't have a previous stack pointer to restore, then there's no
1647    // cleanup we need to perform here.
1648    let prev_stack = match prev_stack {
1649        Some(stack) => stack,
1650        None => return,
1651    };
1652
1653    unsafe {
1654        *store.0.runtime_limits().stack_limit.get() = prev_stack;
1655    }
1656}
1657
1658/// A trait implemented for types which can be returned from closures passed to
1659/// [`Func::wrap`] and friends.
1660///
1661/// This trait should not be implemented by user types. This trait may change at
1662/// any time internally. The types which implement this trait, however, are
1663/// stable over time.
1664///
1665/// For more information see [`Func::wrap`]
1666pub unsafe trait WasmRet {
1667    // Same as `WasmTy::Abi`.
1668    #[doc(hidden)]
1669    type Abi: 'static + Copy;
1670    #[doc(hidden)]
1671    type Retptr: Copy;
1672
1673    // Same as `WasmTy::compatible_with_store`.
1674    #[doc(hidden)]
1675    fn compatible_with_store(&self, store: &StoreOpaque) -> bool;
1676
1677    // Similar to `WasmTy::into_abi_for_arg` but used when host code is
1678    // returning a value into Wasm, rather than host code passing an argument to
1679    // a Wasm call. Unlike `into_abi_for_arg`, implementors of this method can
1680    // raise traps, which means that callers must ensure that
1681    // `invoke_wasm_and_catch_traps` is on the stack, and therefore this method
1682    // is unsafe.
1683    #[doc(hidden)]
1684    unsafe fn into_abi_for_ret(
1685        self,
1686        store: &mut AutoAssertNoGc<'_>,
1687        ptr: Self::Retptr,
1688    ) -> Result<Self::Abi>;
1689
1690    #[doc(hidden)]
1691    fn func_type(engine: &Engine, params: impl Iterator<Item = ValType>) -> FuncType;
1692
1693    #[doc(hidden)]
1694    unsafe fn wrap_trampoline(ptr: *mut ValRaw, f: impl FnOnce(Self::Retptr) -> Self::Abi);
1695
1696    // Utilities used to convert an instance of this type to a `Result`
1697    // explicitly, used when wrapping async functions which always bottom-out
1698    // in a function that returns a trap because futures can be cancelled.
1699    #[doc(hidden)]
1700    type Fallible: WasmRet<Abi = Self::Abi, Retptr = Self::Retptr>;
1701    #[doc(hidden)]
1702    fn into_fallible(self) -> Self::Fallible;
1703    #[doc(hidden)]
1704    fn fallible_from_error(error: Error) -> Self::Fallible;
1705}
1706
1707unsafe impl<T> WasmRet for T
1708where
1709    T: WasmTy,
1710{
1711    type Abi = <T as WasmTy>::Abi;
1712    type Retptr = ();
1713    type Fallible = Result<T>;
1714
1715    fn compatible_with_store(&self, store: &StoreOpaque) -> bool {
1716        <Self as WasmTy>::compatible_with_store(self, store)
1717    }
1718
1719    unsafe fn into_abi_for_ret(
1720        self,
1721        store: &mut AutoAssertNoGc<'_>,
1722        _retptr: (),
1723    ) -> Result<Self::Abi> {
1724        <Self as WasmTy>::into_abi(self, store)
1725    }
1726
1727    fn func_type(engine: &Engine, params: impl Iterator<Item = ValType>) -> FuncType {
1728        FuncType::new(engine, params, Some(<Self as WasmTy>::valtype()))
1729    }
1730
1731    unsafe fn wrap_trampoline(ptr: *mut ValRaw, f: impl FnOnce(Self::Retptr) -> Self::Abi) {
1732        T::abi_into_raw(f(()), ptr);
1733    }
1734
1735    fn into_fallible(self) -> Result<T> {
1736        Ok(self)
1737    }
1738
1739    fn fallible_from_error(error: Error) -> Result<T> {
1740        Err(error)
1741    }
1742}
1743
1744unsafe impl<T> WasmRet for Result<T>
1745where
1746    T: WasmRet,
1747{
1748    type Abi = <T as WasmRet>::Abi;
1749    type Retptr = <T as WasmRet>::Retptr;
1750    type Fallible = Self;
1751
1752    fn compatible_with_store(&self, store: &StoreOpaque) -> bool {
1753        match self {
1754            Ok(x) => <T as WasmRet>::compatible_with_store(x, store),
1755            Err(_) => true,
1756        }
1757    }
1758
1759    unsafe fn into_abi_for_ret(
1760        self,
1761        store: &mut AutoAssertNoGc<'_>,
1762        retptr: Self::Retptr,
1763    ) -> Result<Self::Abi> {
1764        self.and_then(|val| val.into_abi_for_ret(store, retptr))
1765    }
1766
1767    fn func_type(engine: &Engine, params: impl Iterator<Item = ValType>) -> FuncType {
1768        T::func_type(engine, params)
1769    }
1770
1771    unsafe fn wrap_trampoline(ptr: *mut ValRaw, f: impl FnOnce(Self::Retptr) -> Self::Abi) {
1772        T::wrap_trampoline(ptr, f)
1773    }
1774
1775    fn into_fallible(self) -> Result<T> {
1776        self
1777    }
1778
1779    fn fallible_from_error(error: Error) -> Result<T> {
1780        Err(error)
1781    }
1782}
1783
1784macro_rules! impl_wasm_host_results {
1785    ($n:tt $($t:ident)*) => (
1786        #[allow(non_snake_case)]
1787        unsafe impl<$($t),*> WasmRet for ($($t,)*)
1788        where
1789            $($t: WasmTy,)*
1790            ($($t::Abi,)*): HostAbi,
1791        {
1792            type Abi = <($($t::Abi,)*) as HostAbi>::Abi;
1793            type Retptr = <($($t::Abi,)*) as HostAbi>::Retptr;
1794            type Fallible = Result<Self>;
1795
1796            #[inline]
1797            fn compatible_with_store(&self, _store: &StoreOpaque) -> bool {
1798                let ($($t,)*) = self;
1799                $( $t.compatible_with_store(_store) && )* true
1800            }
1801
1802            #[inline]
1803            unsafe fn into_abi_for_ret(
1804                self,
1805                _store: &mut AutoAssertNoGc<'_>,
1806                ptr: Self::Retptr,
1807            ) -> Result<Self::Abi> {
1808                let ($($t,)*) = self;
1809                let abi = ($($t.into_abi(_store)?,)*);
1810                Ok(<($($t::Abi,)*) as HostAbi>::into_abi(abi, ptr))
1811            }
1812
1813            fn func_type(engine: &Engine, params: impl Iterator<Item = ValType>) -> FuncType {
1814                FuncType::new(
1815                    engine,
1816                    params,
1817                    IntoIterator::into_iter([$($t::valtype(),)*]),
1818                )
1819            }
1820
1821            #[allow(unused_assignments)]
1822            unsafe fn wrap_trampoline(mut _ptr: *mut ValRaw, f: impl FnOnce(Self::Retptr) -> Self::Abi) {
1823                let ($($t,)*) = <($($t::Abi,)*) as HostAbi>::call(f);
1824                $(
1825                    $t::abi_into_raw($t, _ptr);
1826                    _ptr = _ptr.add(1);
1827                )*
1828            }
1829
1830            #[inline]
1831            fn into_fallible(self) -> Result<Self> {
1832                Ok(self)
1833            }
1834
1835            #[inline]
1836            fn fallible_from_error(error: Error) -> Result<Self> {
1837                Err(error)
1838            }
1839        }
1840    )
1841}
1842
1843for_each_function_signature!(impl_wasm_host_results);
1844
1845// Internal trait representing how to communicate tuples of return values across
1846// an ABI boundary. This internally corresponds to the "wasmtime" ABI inside of
1847// cranelift itself. Notably the first element of each tuple is returned via the
1848// typical system ABI (e.g. systemv or fastcall depending on platform) and all
1849// other values are returned packed via the stack.
1850//
1851// This trait helps to encapsulate all the details of that.
1852#[doc(hidden)]
1853pub trait HostAbi {
1854    // A value returned from native functions which return `Self`
1855    type Abi: Copy;
1856    // A return pointer, added to the end of the argument list, for native
1857    // functions that return `Self`. Note that a 0-sized type here should get
1858    // elided at the ABI level.
1859    type Retptr: Copy;
1860
1861    // Converts a value of `self` into its components. Stores necessary values
1862    // into `ptr` and then returns whatever needs to be returned from the
1863    // function.
1864    unsafe fn into_abi(self, ptr: Self::Retptr) -> Self::Abi;
1865
1866    // Calls `f` with a suitably sized return area and requires `f` to return
1867    // the raw abi value of the first element of our tuple. This will then
1868    // unpack the `Retptr` and assemble it with `Self::Abi` to return an
1869    // instance of the whole tuple.
1870    unsafe fn call(f: impl FnOnce(Self::Retptr) -> Self::Abi) -> Self;
1871}
1872
1873macro_rules! impl_host_abi {
1874    // Base case, everything is `()`
1875    (0) => {
1876        impl HostAbi for () {
1877            type Abi = ();
1878            type Retptr = ();
1879
1880            #[inline]
1881            unsafe fn into_abi(self, _ptr: Self::Retptr) -> Self::Abi {}
1882
1883            #[inline]
1884            unsafe fn call(f: impl FnOnce(Self::Retptr) -> Self::Abi) -> Self {
1885                f(())
1886            }
1887        }
1888    };
1889
1890    // In the 1-case the retptr is not present, so it's a 0-sized value.
1891    (1 $a:ident) => {
1892        impl<$a: Copy> HostAbi for ($a,) {
1893            type Abi = $a;
1894            type Retptr = ();
1895
1896            unsafe fn into_abi(self, _ptr: Self::Retptr) -> Self::Abi {
1897                self.0
1898            }
1899
1900            unsafe fn call(f: impl FnOnce(Self::Retptr) -> Self::Abi) -> Self {
1901                (f(()),)
1902            }
1903        }
1904    };
1905
1906    // This is where the more interesting case happens. The first element of the
1907    // tuple is returned via `Abi` and all other elements are returned via
1908    // `Retptr`. We create a `TupleRetNN` structure to represent all of the
1909    // return values here.
1910    //
1911    // Also note that this isn't implemented for the old backend right now due
1912    // to the original author not really being sure how to implement this in the
1913    // old backend.
1914    ($n:tt $t:ident $($u:ident)*) => {paste::paste!{
1915        #[doc(hidden)]
1916        #[allow(non_snake_case)]
1917        #[repr(C)]
1918        pub struct [<TupleRet $n>]<$($u,)*> {
1919            $($u: $u,)*
1920        }
1921
1922        #[allow(non_snake_case, unused_assignments)]
1923        impl<$t: Copy, $($u: Copy,)*> HostAbi for ($t, $($u,)*) {
1924            type Abi = $t;
1925            type Retptr = *mut [<TupleRet $n>]<$($u,)*>;
1926
1927            unsafe fn into_abi(self, ptr: Self::Retptr) -> Self::Abi {
1928                let ($t, $($u,)*) = self;
1929                // Store the tail of our tuple into the return pointer...
1930                $((*ptr).$u = $u;)*
1931                // ... and return the head raw.
1932                $t
1933            }
1934
1935            unsafe fn call(f: impl FnOnce(Self::Retptr) -> Self::Abi) -> Self {
1936                // Create space to store all the return values and then invoke
1937                // the function.
1938                let mut space = std::mem::MaybeUninit::uninit();
1939                let t = f(space.as_mut_ptr());
1940                let space = space.assume_init();
1941
1942                // Use the return value as the head of the tuple and unpack our
1943                // return area to get the rest of the tuple.
1944                (t, $(space.$u,)*)
1945            }
1946        }
1947    }};
1948}
1949
1950for_each_function_signature!(impl_host_abi);
1951
1952/// Internal trait implemented for all arguments that can be passed to
1953/// [`Func::wrap`] and [`Linker::func_wrap`](crate::Linker::func_wrap).
1954///
1955/// This trait should not be implemented by external users, it's only intended
1956/// as an implementation detail of this crate.
1957pub trait IntoFunc<T, Params, Results>: Send + Sync + 'static {
1958    /// Convert this function into a `VM{Array,Native}CallHostFuncContext` and
1959    /// internal `VMFuncRef`.
1960    #[doc(hidden)]
1961    fn into_func(self, engine: &Engine) -> HostContext;
1962}
1963
1964/// A structure representing the caller's context when creating a function
1965/// via [`Func::wrap`].
1966///
1967/// This structure can be taken as the first parameter of a closure passed to
1968/// [`Func::wrap`] or other constructors, and serves two purposes:
1969///
1970/// * First consumers can use [`Caller<'_, T>`](crate::Caller) to get access to
1971///   [`StoreContextMut<'_, T>`](crate::StoreContextMut) and/or get access to
1972///   `T` itself. This means that the [`Caller`] type can serve as a proxy to
1973///   the original [`Store`](crate::Store) itself and is used to satisfy
1974///   [`AsContext`] and [`AsContextMut`] bounds.
1975///
1976/// * Second a [`Caller`] can be used as the name implies, learning about the
1977///   caller's context, namely it's exported memory and exported functions. This
1978///   allows functions which take pointers as arguments to easily read the
1979///   memory the pointers point into, or if a function is expected to call
1980///   malloc in the wasm module to reserve space for the output you can do that.
1981///
1982/// Host functions which want access to [`Store`](crate::Store)-level state are
1983/// recommended to use this type.
1984pub struct Caller<'a, T> {
1985    pub(crate) store: StoreContextMut<'a, T>,
1986    caller: &'a wasmtime_runtime::Instance,
1987}
1988
1989impl<T> Caller<'_, T> {
1990    unsafe fn with<F, R>(caller: *mut VMContext, f: F) -> R
1991    where
1992        // The closure must be valid for any `Caller` it is given; it doesn't
1993        // get to choose the `Caller`'s lifetime.
1994        F: for<'a> FnOnce(Caller<'a, T>) -> R,
1995        // And the return value must not borrow from the caller/store.
1996        R: 'static,
1997    {
1998        assert!(!caller.is_null());
1999        wasmtime_runtime::Instance::from_vmctx(caller, |instance| {
2000            let store = StoreContextMut::from_raw(instance.store());
2001            let gc_lifo_scope = store.0.gc_roots().enter_lifo_scope();
2002
2003            let ret = f(Caller {
2004                store,
2005                caller: &instance,
2006            });
2007
2008            // Safe to recreate a mutable borrow of the store because `ret`
2009            // cannot be borrowing from the store.
2010            let store = StoreContextMut::<T>::from_raw(instance.store());
2011            store.0.exit_gc_lifo_scope(gc_lifo_scope);
2012
2013            ret
2014        })
2015    }
2016
2017    fn sub_caller(&mut self) -> Caller<'_, T> {
2018        Caller {
2019            store: self.store.as_context_mut(),
2020            caller: self.caller,
2021        }
2022    }
2023
2024    /// Looks up an export from the caller's module by the `name` given.
2025    ///
2026    /// This is a low-level function that's typically used to implement passing
2027    /// of pointers or indices between core Wasm instances, where the callee
2028    /// needs to consult the caller's exports to perform memory management and
2029    /// resolve the references.
2030    ///
2031    /// For comparison, in components, the component model handles translating
2032    /// arguments from one component instance to another and managing memory, so
2033    /// that callees don't need to be aware of their callers, which promotes
2034    /// virtualizability of APIs.
2035    ///
2036    /// # Return
2037    ///
2038    /// If an export with the `name` provided was found, then it is returned as an
2039    /// `Extern`. There are a number of situations, however, where the export may not
2040    /// be available:
2041    ///
2042    /// * The caller instance may not have an export named `name`
2043    /// * There may not be a caller available, for example if `Func` was called
2044    ///   directly from host code.
2045    ///
2046    /// It's recommended to take care when calling this API and gracefully
2047    /// handling a `None` return value.
2048    pub fn get_export(&mut self, name: &str) -> Option<Extern> {
2049        // All instances created have a `host_state` with a pointer pointing
2050        // back to themselves. If this caller doesn't have that `host_state`
2051        // then it probably means it was a host-created object like `Func::new`
2052        // which doesn't have any exports we want to return anyway.
2053        self.caller
2054            .host_state()
2055            .downcast_ref::<Instance>()?
2056            .get_export(&mut self.store, name)
2057    }
2058
2059    /// Access the underlying data owned by this `Store`.
2060    ///
2061    /// Same as [`Store::data`](crate::Store::data)
2062    pub fn data(&self) -> &T {
2063        self.store.data()
2064    }
2065
2066    /// Access the underlying data owned by this `Store`.
2067    ///
2068    /// Same as [`Store::data_mut`](crate::Store::data_mut)
2069    pub fn data_mut(&mut self) -> &mut T {
2070        self.store.data_mut()
2071    }
2072
2073    /// Returns the underlying [`Engine`] this store is connected to.
2074    pub fn engine(&self) -> &Engine {
2075        self.store.engine()
2076    }
2077
2078    /// Perform garbage collection.
2079    ///
2080    /// Same as [`Store::gc`](crate::Store::gc).
2081    #[cfg(feature = "gc")]
2082    #[cfg_attr(docsrs, doc(cfg(feature = "gc")))]
2083    pub fn gc(&mut self) {
2084        self.store.gc()
2085    }
2086
2087    /// Perform garbage collection asynchronously.
2088    ///
2089    /// Same as [`Store::gc_async`](crate::Store::gc_async).
2090    #[cfg(all(feature = "async", feature = "gc"))]
2091    #[cfg_attr(docsrs, doc(cfg(feature = "gc")))]
2092    pub async fn gc_async(&mut self)
2093    where
2094        T: Send,
2095    {
2096        self.store.gc_async().await;
2097    }
2098
2099    /// Returns the remaining fuel in the store.
2100    ///
2101    /// For more information see [`Store::get_fuel`](crate::Store::get_fuel)
2102    pub fn get_fuel(&self) -> Result<u64> {
2103        self.store.get_fuel()
2104    }
2105
2106    /// Set the amount of fuel in this store to be consumed when executing wasm code.
2107    ///
2108    /// For more information see [`Store::set_fuel`](crate::Store::set_fuel)
2109    pub fn set_fuel(&mut self, fuel: u64) -> Result<()> {
2110        self.store.set_fuel(fuel)
2111    }
2112
2113    /// Configures this `Store` to yield while executing futures every N units of fuel.
2114    ///
2115    /// For more information see
2116    /// [`Store::fuel_async_yield_interval`](crate::Store::fuel_async_yield_interval)
2117    pub fn fuel_async_yield_interval(&mut self, interval: Option<u64>) -> Result<()> {
2118        self.store.fuel_async_yield_interval(interval)
2119    }
2120}
2121
2122impl<T> AsContext for Caller<'_, T> {
2123    type Data = T;
2124    fn as_context(&self) -> StoreContext<'_, T> {
2125        self.store.as_context()
2126    }
2127}
2128
2129impl<T> AsContextMut for Caller<'_, T> {
2130    fn as_context_mut(&mut self) -> StoreContextMut<'_, T> {
2131        self.store.as_context_mut()
2132    }
2133}
2134
2135// State stored inside a `VMNativeCallHostFuncContext`.
2136struct HostFuncState<F> {
2137    // The actual host function.
2138    func: F,
2139
2140    // NB: We have to keep our `VMSharedTypeIndex` registered in the engine for
2141    // as long as this function exists.
2142    #[allow(dead_code)]
2143    ty: RegisteredType,
2144}
2145
2146macro_rules! impl_into_func {
2147    ($num:tt $($args:ident)*) => {
2148        // Implement for functions without a leading `&Caller` parameter,
2149        // delegating to the implementation below which does have the leading
2150        // `Caller` parameter.
2151        #[allow(non_snake_case)]
2152        impl<T, F, $($args,)* R> IntoFunc<T, ($($args,)*), R> for F
2153        where
2154            F: Fn($($args),*) -> R + Send + Sync + 'static,
2155            $($args: WasmTy,)*
2156            R: WasmRet,
2157        {
2158            fn into_func(self, engine: &Engine) -> HostContext {
2159                let f = move |_: Caller<'_, T>, $($args:$args),*| {
2160                    self($($args),*)
2161                };
2162
2163                f.into_func(engine)
2164            }
2165        }
2166
2167        #[allow(non_snake_case)]
2168        impl<T, F, $($args,)* R> IntoFunc<T, (Caller<'_, T>, $($args,)*), R> for F
2169        where
2170            F: Fn(Caller<'_, T>, $($args),*) -> R + Send + Sync + 'static,
2171            $($args: WasmTy,)*
2172            R: WasmRet,
2173        {
2174            fn into_func(self, engine: &Engine) -> HostContext {
2175                /// This shim is a regular, non-closure function we can stuff
2176                /// inside `VMFuncRef::native_call`.
2177                ///
2178                /// It reads the actual callee closure out of
2179                /// `VMNativeCallHostFuncContext::host_state`, forwards
2180                /// arguments to that function, and finally forwards the results
2181                /// back out to the caller. It also handles traps and panics
2182                /// along the way.
2183                unsafe extern "C" fn native_call_shim<T, F, $($args,)* R>(
2184                    vmctx: *mut VMOpaqueContext,
2185                    caller_vmctx: *mut VMOpaqueContext,
2186                    $( $args: $args::Abi, )*
2187                    retptr: R::Retptr,
2188                ) -> R::Abi
2189                where
2190                    F: Fn(Caller<'_, T>, $( $args ),*) -> R + 'static,
2191                    $( $args: WasmTy, )*
2192                    R: WasmRet,
2193                {
2194                    // Note that this function is intentionally scoped into a
2195                    // separate closure. Handling traps and panics will involve
2196                    // longjmp-ing from this function which means we won't run
2197                    // destructors. As a result anything requiring a destructor
2198                    // should be part of this closure, and the long-jmp-ing
2199                    // happens after the closure in handling the result.
2200                    let run = move |mut caller: Caller<'_, T>| {
2201                        let vmctx = VMNativeCallHostFuncContext::from_opaque(vmctx);
2202                        let state = (*vmctx).host_state();
2203
2204                        // Double-check ourselves in debug mode, but we control
2205                        // the `Any` here so an unsafe downcast should also
2206                        // work.
2207                        debug_assert!(state.is::<HostFuncState<F>>());
2208                        let state = &*(state as *const _ as *const HostFuncState<F>);
2209                        let func = &state.func;
2210
2211                        let ret = 'ret: {
2212                            if let Err(trap) = caller.store.0.call_hook(CallHook::CallingHost) {
2213                                break 'ret R::fallible_from_error(trap);
2214                            }
2215
2216                            let mut store = AutoAssertNoGc::new(caller.store.0);
2217                            $(let $args = $args::from_abi($args, &mut store);)*
2218                            let _ = &mut store;
2219                            drop(store);
2220
2221                            let r = func(
2222                                caller.sub_caller(),
2223                                $( $args, )*
2224                            );
2225                            if let Err(trap) = caller.store.0.call_hook(CallHook::ReturningFromHost) {
2226                                break 'ret R::fallible_from_error(trap);
2227                            }
2228                            r.into_fallible()
2229                        };
2230
2231                        if !ret.compatible_with_store(caller.store.0) {
2232                            bail!("host function attempted to return cross-`Store` value to Wasm")
2233                        } else {
2234                            let mut store = AutoAssertNoGc::new(&mut **caller.store.0);
2235                            let ret = ret.into_abi_for_ret(&mut store, retptr)?;
2236                            Ok(ret)
2237                        }
2238                    };
2239
2240                    // With nothing else on the stack move `run` into this
2241                    // closure and then run it as part of `Caller::with`.
2242                    let result = wasmtime_runtime::catch_unwind_and_longjmp(move || {
2243                        let caller_vmctx = VMContext::from_opaque(caller_vmctx);
2244                        Caller::with(caller_vmctx, run)
2245                    });
2246
2247                    match result {
2248                        Ok(val) => val,
2249                        Err(err) => crate::trap::raise(err),
2250                    }
2251                }
2252
2253                /// This trampoline allows host code to indirectly call the
2254                /// wrapped function (e.g. via `Func::call` on a `funcref` that
2255                /// happens to reference our wrapped function).
2256                ///
2257                /// It reads the arguments out of the incoming `args` array,
2258                /// calls the given function pointer, and then stores the result
2259                /// back into the `args` array.
2260                unsafe extern "C" fn array_call_trampoline<T, F, $($args,)* R>(
2261                    callee_vmctx: *mut VMOpaqueContext,
2262                    caller_vmctx: *mut VMOpaqueContext,
2263                    args: *mut ValRaw,
2264                    _args_len: usize
2265                )
2266                where
2267                    F: Fn(Caller<'_, T>, $( $args ),*) -> R + 'static,
2268                    $($args: WasmTy,)*
2269                    R: WasmRet,
2270                {
2271                    let mut _n = 0;
2272                    $(
2273                        debug_assert!(_n < _args_len);
2274                        let $args = $args::abi_from_raw(args.add(_n));
2275                        _n += 1;
2276                    )*
2277
2278                    R::wrap_trampoline(args, |retptr| {
2279                        native_call_shim::<T, F, $( $args, )* R>(callee_vmctx, caller_vmctx, $( $args, )* retptr)
2280                    });
2281                }
2282
2283                let ty = R::func_type(
2284                    engine,
2285                    None::<ValType>.into_iter()
2286                        $(.chain(Some($args::valtype())))*
2287                );
2288                let type_index = ty.type_index();
2289
2290                let array_call = array_call_trampoline::<T, F, $($args,)* R>;
2291                let native_call = NonNull::new(native_call_shim::<T, F, $($args,)* R> as *mut _).unwrap();
2292
2293                let ctx = unsafe {
2294                    VMNativeCallHostFuncContext::new(
2295                        VMFuncRef {
2296                            native_call,
2297                            array_call,
2298                            wasm_call: None,
2299                            type_index,
2300                            vmctx: ptr::null_mut(),
2301                        },
2302                        Box::new(HostFuncState {
2303                            func: self,
2304                            ty: ty.into_registered_type(),
2305                        }),
2306                    )
2307                };
2308
2309                ctx.into()
2310            }
2311        }
2312    }
2313}
2314
2315for_each_function_signature!(impl_into_func);
2316
2317#[doc(hidden)]
2318pub enum HostContext {
2319    Native(StoreBox<VMNativeCallHostFuncContext>),
2320    Array(StoreBox<VMArrayCallHostFuncContext>),
2321}
2322
2323impl From<StoreBox<VMNativeCallHostFuncContext>> for HostContext {
2324    fn from(ctx: StoreBox<VMNativeCallHostFuncContext>) -> Self {
2325        HostContext::Native(ctx)
2326    }
2327}
2328
2329impl From<StoreBox<VMArrayCallHostFuncContext>> for HostContext {
2330    fn from(ctx: StoreBox<VMArrayCallHostFuncContext>) -> Self {
2331        HostContext::Array(ctx)
2332    }
2333}
2334
2335/// Representation of a host-defined function.
2336///
2337/// This is used for `Func::new` but also for `Linker`-defined functions. For
2338/// `Func::new` this is stored within a `Store`, and for `Linker`-defined
2339/// functions they wrap this up in `Arc` to enable shared ownership of this
2340/// across many stores.
2341///
2342/// Technically this structure needs a `<T>` type parameter to connect to the
2343/// `Store<T>` itself, but that's an unsafe contract of using this for now
2344/// rather than part of the struct type (to avoid `Func<T>` in the API).
2345pub(crate) struct HostFunc {
2346    ctx: HostContext,
2347
2348    // Stored to unregister this function's signature with the engine when this
2349    // is dropped.
2350    engine: Engine,
2351}
2352
2353impl HostFunc {
2354    /// Analog of [`Func::new`]
2355    ///
2356    /// # Panics
2357    ///
2358    /// Panics if the given function type is not associated with the given
2359    /// engine.
2360    #[cfg(any(feature = "cranelift", feature = "winch"))]
2361    pub fn new<T>(
2362        engine: &Engine,
2363        ty: FuncType,
2364        func: impl Fn(Caller<'_, T>, &[Val], &mut [Val]) -> Result<()> + Send + Sync + 'static,
2365    ) -> Self {
2366        assert!(ty.comes_from_same_engine(engine));
2367        let ty_clone = ty.clone();
2368        unsafe {
2369            HostFunc::new_unchecked(engine, ty, move |caller, values| {
2370                Func::invoke_host_func_for_wasm(caller, &ty_clone, values, &func)
2371            })
2372        }
2373    }
2374
2375    /// Analog of [`Func::new_unchecked`]
2376    ///
2377    /// # Panics
2378    ///
2379    /// Panics if the given function type is not associated with the given
2380    /// engine.
2381    #[cfg(any(feature = "cranelift", feature = "winch"))]
2382    pub unsafe fn new_unchecked<T>(
2383        engine: &Engine,
2384        ty: FuncType,
2385        func: impl Fn(Caller<'_, T>, &mut [ValRaw]) -> Result<()> + Send + Sync + 'static,
2386    ) -> Self {
2387        assert!(ty.comes_from_same_engine(engine));
2388        let func = move |caller_vmctx, values: &mut [ValRaw]| {
2389            Caller::<T>::with(caller_vmctx, |mut caller| {
2390                caller.store.0.call_hook(CallHook::CallingHost)?;
2391                let result = func(caller.sub_caller(), values)?;
2392                caller.store.0.call_hook(CallHook::ReturningFromHost)?;
2393                Ok(result)
2394            })
2395        };
2396        let ctx = crate::trampoline::create_array_call_function(&ty, func, engine)
2397            .expect("failed to create function");
2398        HostFunc::_new(engine, ctx.into())
2399    }
2400
2401    /// Analog of [`Func::wrap`]
2402    pub fn wrap<T, Params, Results>(
2403        engine: &Engine,
2404        func: impl IntoFunc<T, Params, Results>,
2405    ) -> Self {
2406        let ctx = func.into_func(engine);
2407        HostFunc::_new(engine, ctx)
2408    }
2409
2410    /// Requires that this function's signature is already registered within
2411    /// `Engine`. This happens automatically during the above two constructors.
2412    fn _new(engine: &Engine, ctx: HostContext) -> Self {
2413        HostFunc {
2414            ctx,
2415            engine: engine.clone(),
2416        }
2417    }
2418
2419    /// Inserts this `HostFunc` into a `Store`, returning the `Func` pointing to
2420    /// it.
2421    ///
2422    /// # Unsafety
2423    ///
2424    /// Can only be inserted into stores with a matching `T` relative to when
2425    /// this `HostFunc` was first created.
2426    pub unsafe fn to_func(self: &Arc<Self>, store: &mut StoreOpaque) -> Func {
2427        self.validate_store(store);
2428        let me = self.clone();
2429        Func::from_func_kind(FuncKind::SharedHost(me), store)
2430    }
2431
2432    /// Inserts this `HostFunc` into a `Store`, returning the `Func` pointing to
2433    /// it.
2434    ///
2435    /// This function is similar to, but not equivalent, to `HostFunc::to_func`.
2436    /// Notably this function requires that the `Arc<Self>` pointer is otherwise
2437    /// rooted within the `StoreOpaque` via another means. When in doubt use
2438    /// `to_func` above as it's safer.
2439    ///
2440    /// # Unsafety
2441    ///
2442    /// Can only be inserted into stores with a matching `T` relative to when
2443    /// this `HostFunc` was first created.
2444    ///
2445    /// Additionally the `&Arc<Self>` is not cloned in this function. Instead a
2446    /// raw pointer to `Self` is stored within the `Store` for this function.
2447    /// The caller must arrange for the `Arc<Self>` to be "rooted" in the store
2448    /// provided via another means, probably by pushing to
2449    /// `StoreOpaque::rooted_host_funcs`.
2450    ///
2451    /// Similarly, the caller must arrange for `rooted_func_ref` to be rooted in
2452    /// the same store.
2453    pub unsafe fn to_func_store_rooted(
2454        self: &Arc<Self>,
2455        store: &mut StoreOpaque,
2456        rooted_func_ref: Option<NonNull<VMFuncRef>>,
2457    ) -> Func {
2458        self.validate_store(store);
2459
2460        if rooted_func_ref.is_some() {
2461            debug_assert!(self.func_ref().wasm_call.is_none());
2462            debug_assert!(matches!(self.ctx, HostContext::Native(_)));
2463        }
2464
2465        Func::from_func_kind(
2466            FuncKind::RootedHost(RootedHostFunc::new(self, rooted_func_ref)),
2467            store,
2468        )
2469    }
2470
2471    /// Same as [`HostFunc::to_func`], different ownership.
2472    unsafe fn into_func(self, store: &mut StoreOpaque) -> Func {
2473        self.validate_store(store);
2474        Func::from_func_kind(FuncKind::Host(Box::new(self)), store)
2475    }
2476
2477    fn validate_store(&self, store: &mut StoreOpaque) {
2478        // This assert is required to ensure that we can indeed safely insert
2479        // `self` into the `store` provided, otherwise the type information we
2480        // have listed won't be correct. This is possible to hit with the public
2481        // API of Wasmtime, and should be documented in relevant functions.
2482        assert!(
2483            Engine::same(&self.engine, store.engine()),
2484            "cannot use a store with a different engine than a linker was created with",
2485        );
2486    }
2487
2488    pub(crate) fn sig_index(&self) -> VMSharedTypeIndex {
2489        self.func_ref().type_index
2490    }
2491
2492    pub(crate) fn func_ref(&self) -> &VMFuncRef {
2493        match &self.ctx {
2494            HostContext::Native(ctx) => unsafe { (*ctx.get()).func_ref() },
2495            HostContext::Array(ctx) => unsafe { (*ctx.get()).func_ref() },
2496        }
2497    }
2498
2499    pub(crate) fn host_ctx(&self) -> &HostContext {
2500        &self.ctx
2501    }
2502
2503    fn export_func(&self) -> ExportFunction {
2504        ExportFunction {
2505            func_ref: NonNull::from(self.func_ref()),
2506        }
2507    }
2508}
2509
2510impl FuncData {
2511    #[inline]
2512    fn export(&self) -> ExportFunction {
2513        self.kind.export()
2514    }
2515
2516    pub(crate) fn sig_index(&self) -> VMSharedTypeIndex {
2517        unsafe { self.export().func_ref.as_ref().type_index }
2518    }
2519}
2520
2521impl FuncKind {
2522    #[inline]
2523    fn export(&self) -> ExportFunction {
2524        match self {
2525            FuncKind::StoreOwned { export, .. } => *export,
2526            FuncKind::SharedHost(host) => host.export_func(),
2527            FuncKind::RootedHost(rooted) => ExportFunction {
2528                func_ref: NonNull::from(rooted.func_ref()),
2529            },
2530            FuncKind::Host(host) => host.export_func(),
2531        }
2532    }
2533}
2534
2535use self::rooted::*;
2536
2537/// An inner module is used here to force unsafe construction of
2538/// `RootedHostFunc` instead of accidentally safely allowing access to its
2539/// constructor.
2540mod rooted {
2541    use wasmtime_runtime::{SendSyncPtr, VMFuncRef};
2542
2543    use super::HostFunc;
2544    use std::ptr::NonNull;
2545    use std::sync::Arc;
2546
2547    /// A variant of a pointer-to-a-host-function used in `FuncKind::RootedHost`
2548    /// above.
2549    ///
2550    /// For more documentation see `FuncKind::RootedHost`, `InstancePre`, and
2551    /// `HostFunc::to_func_store_rooted`.
2552    pub(crate) struct RootedHostFunc {
2553        func: SendSyncPtr<HostFunc>,
2554        func_ref: Option<SendSyncPtr<VMFuncRef>>,
2555    }
2556
2557    impl RootedHostFunc {
2558        /// Note that this is `unsafe` because this wrapper type allows safe
2559        /// access to the pointer given at any time, including outside the
2560        /// window of validity of `func`, so callers must not use the return
2561        /// value past the lifetime of the provided `func`.
2562        ///
2563        /// Similarly, callers must ensure that the given `func_ref` is valid
2564        /// for the liftime of the return value.
2565        pub(crate) unsafe fn new(
2566            func: &Arc<HostFunc>,
2567            func_ref: Option<NonNull<VMFuncRef>>,
2568        ) -> RootedHostFunc {
2569            RootedHostFunc {
2570                func: NonNull::from(&**func).into(),
2571                func_ref: func_ref.map(|p| p.into()),
2572            }
2573        }
2574
2575        pub(crate) fn func(&self) -> &HostFunc {
2576            // Safety invariants are upheld by the `RootedHostFunc::new` caller.
2577            unsafe { self.func.as_ref() }
2578        }
2579
2580        pub(crate) fn func_ref(&self) -> &VMFuncRef {
2581            if let Some(f) = self.func_ref {
2582                // Safety invariants are upheld by the `RootedHostFunc::new` caller.
2583                unsafe { f.as_ref() }
2584            } else {
2585                self.func().func_ref()
2586            }
2587        }
2588    }
2589}
2590
2591#[cfg(test)]
2592mod tests {
2593    use super::*;
2594    use crate::Store;
2595
2596    #[test]
2597    fn hash_key_is_stable_across_duplicate_store_data_entries() -> Result<()> {
2598        let mut store = Store::<()>::default();
2599        let module = Module::new(
2600            store.engine(),
2601            r#"
2602                (module
2603                    (func (export "f")
2604                        nop
2605                    )
2606                )
2607            "#,
2608        )?;
2609        let instance = Instance::new(&mut store, &module, &[])?;
2610
2611        // Each time we `get_func`, we call `Func::from_wasmtime` which adds a
2612        // new entry to `StoreData`, so `f1` and `f2` will have different
2613        // indices into `StoreData`.
2614        let f1 = instance.get_func(&mut store, "f").unwrap();
2615        let f2 = instance.get_func(&mut store, "f").unwrap();
2616
2617        // But their hash keys are the same.
2618        assert!(
2619            f1.hash_key(&mut store.as_context_mut().0)
2620                == f2.hash_key(&mut store.as_context_mut().0)
2621        );
2622
2623        // But the hash keys are different from different funcs.
2624        let instance2 = Instance::new(&mut store, &module, &[])?;
2625        let f3 = instance2.get_func(&mut store, "f").unwrap();
2626        assert!(
2627            f1.hash_key(&mut store.as_context_mut().0)
2628                != f3.hash_key(&mut store.as_context_mut().0)
2629        );
2630
2631        Ok(())
2632    }
2633}