wasmtime/
func.rs

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