wasmtime/runtime/trampoline/
func.rs1use crate::prelude::*;
4use crate::runtime::vm::{StoreBox, VMArrayCallHostFuncContext, VMContext, VMOpaqueContext};
5use crate::type_registry::RegisteredType;
6use crate::{FuncType, ValRaw};
7use core::ptr::NonNull;
8
9struct TrampolineState<F> {
10 func: F,
11
12 #[allow(dead_code)]
14 sig: RegisteredType,
15}
16
17unsafe extern "C" fn array_call_shim<F>(
25 vmctx: NonNull<VMOpaqueContext>,
26 caller_vmctx: NonNull<VMOpaqueContext>,
27 values_vec: NonNull<ValRaw>,
28 values_vec_len: usize,
29) -> bool
30where
31 F: Fn(NonNull<VMContext>, &mut [ValRaw]) -> Result<()> + 'static,
32{
33 crate::runtime::vm::catch_unwind_and_record_trap(|| {
36 let vmctx = VMArrayCallHostFuncContext::from_opaque(vmctx);
37 let state = vmctx.as_ref().host_state();
41 debug_assert!(state.is::<TrampolineState<F>>());
42 let state = &*(state as *const _ as *const TrampolineState<F>);
43 let mut values_vec = NonNull::slice_from_raw_parts(values_vec, values_vec_len);
44 (state.func)(VMContext::from_opaque(caller_vmctx), values_vec.as_mut())
45 })
46}
47
48pub fn create_array_call_function<F>(
49 ft: &FuncType,
50 func: F,
51) -> Result<StoreBox<VMArrayCallHostFuncContext>>
52where
53 F: Fn(NonNull<VMContext>, &mut [ValRaw]) -> Result<()> + Send + Sync + 'static,
54{
55 let array_call = array_call_shim::<F>;
56
57 let sig = ft.clone().into_registered_type();
58
59 unsafe {
60 Ok(VMArrayCallHostFuncContext::new(
61 array_call,
62 sig.index(),
63 Box::new(TrampolineState { func, sig }),
64 ))
65 }
66}