wasmtime/runtime/vm/vmcontext/
vm_host_func_context.rs1use super::{VMArrayCallNative, VMOpaqueContext};
6use crate::error::OutOfMemory;
7use crate::prelude::*;
8use crate::runtime::vm::{StoreBox, VMFuncRef};
9use core::any::Any;
10use core::ptr::NonNull;
11use wasmtime_environ::{VM_ARRAY_CALL_HOST_FUNC_MAGIC, VMSharedTypeIndex};
12
13#[repr(C)]
20pub struct VMArrayCallHostFuncContext {
21 magic: u32,
22 pub(crate) func_ref: VMFuncRef,
24 host_state: Box<dyn Any + Send + Sync>,
25}
26
27impl VMArrayCallHostFuncContext {
28 pub unsafe fn new(
35 host_func: VMArrayCallNative,
36 type_index: VMSharedTypeIndex,
37 host_state: Box<dyn Any + Send + Sync>,
38 ) -> Result<StoreBox<VMArrayCallHostFuncContext>, OutOfMemory> {
39 let ctx = StoreBox::new(VMArrayCallHostFuncContext {
40 magic: wasmtime_environ::VM_ARRAY_CALL_HOST_FUNC_MAGIC,
41 func_ref: VMFuncRef {
42 array_call: NonNull::new(host_func as *mut u8).unwrap().cast().into(),
43 type_index,
44 wasm_call: None,
45 vmctx: NonNull::dangling().into(),
46 },
47 host_state,
48 })?;
49 let vmctx = VMOpaqueContext::from_vm_array_call_host_func_context(ctx.get());
50 unsafe {
51 ctx.get().as_mut().func_ref.vmctx = vmctx.into();
52 }
53 Ok(ctx)
54 }
55
56 #[inline]
58 pub fn host_state(&self) -> &(dyn Any + Send + Sync) {
59 &*self.host_state
60 }
61
62 #[inline]
64 pub fn func_ref(&self) -> &VMFuncRef {
65 &self.func_ref
66 }
67
68 #[inline]
71 pub unsafe fn from_opaque(
72 opaque: NonNull<VMOpaqueContext>,
73 ) -> NonNull<VMArrayCallHostFuncContext> {
74 unsafe {
76 debug_assert_eq!(opaque.as_ref().magic, VM_ARRAY_CALL_HOST_FUNC_MAGIC);
77 }
78 opaque.cast()
79 }
80}
81
82#[test]
83fn vmarray_call_host_func_context_offsets() {
84 use core::mem::offset_of;
85 use wasmtime_environ::{HostPtr, PtrSize};
86 assert_eq!(
87 usize::from(HostPtr.vmarray_call_host_func_context_func_ref()),
88 offset_of!(VMArrayCallHostFuncContext, func_ref)
89 );
90}