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