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