wasmtime/runtime/trampoline/
func.rs1use crate::prelude::*;
4use crate::runtime::vm::{
5 Instance, StoreBox, VMArrayCallHostFuncContext, VMContext, VMOpaqueContext, VMStore,
6};
7use crate::store::InstanceId;
8use crate::type_registry::RegisteredType;
9use crate::{FuncType, ValRaw};
10use core::ptr::NonNull;
11
12struct TrampolineState<F> {
13 func: F,
14
15 _sig: RegisteredType,
17}
18
19unsafe extern "C" fn array_call_shim<F>(
32 vmctx: NonNull<VMOpaqueContext>,
33 caller_vmctx: NonNull<VMContext>,
34 values_vec: NonNull<ValRaw>,
35 values_vec_len: usize,
36) -> bool
37where
38 F: Fn(&mut dyn VMStore, InstanceId, &mut [ValRaw]) -> Result<()> + 'static,
39{
40 unsafe {
44 Instance::enter_host_from_wasm(caller_vmctx, |store, instance| {
45 let state = {
48 let vmctx = VMArrayCallHostFuncContext::from_opaque(vmctx);
49 vmctx.as_ref().host_state()
50 };
51
52 let state = {
58 debug_assert!(state.is::<TrampolineState<F>>());
59 &*(state as *const _ as *const TrampolineState<F>)
60 };
61 let mut values_vec = NonNull::slice_from_raw_parts(values_vec, values_vec_len);
62 let values_vec = values_vec.as_mut();
65 (state.func)(store, instance, values_vec)
66 })
67 }
68}
69
70pub fn create_array_call_function<F>(
71 ft: &FuncType,
72 func: F,
73) -> Result<StoreBox<VMArrayCallHostFuncContext>>
74where
75 F: Fn(&mut dyn VMStore, InstanceId, &mut [ValRaw]) -> Result<()> + Send + Sync + 'static,
76{
77 let array_call = array_call_shim::<F>;
78
79 let sig = ft.clone().into_registered_type();
80
81 unsafe {
82 Ok(VMArrayCallHostFuncContext::new(
83 array_call,
84 sig.index(),
85 Box::new(TrampolineState { func, _sig: sig }),
86 ))
87 }
88}