1 //! Definition of `VM*Context` variant for host functions. 2 //! 3 //! Keep in sync with `wasmtime_environ::VMHostFuncOffsets`. 4 5 use super::VMOpaqueContext; 6 use crate::prelude::*; 7 use crate::runtime::vm::{StoreBox, VMFuncRef}; 8 use core::any::Any; 9 use wasmtime_environ::VM_ARRAY_CALL_HOST_FUNC_MAGIC; 10 11 /// The `VM*Context` for array-call host functions. 12 /// 13 /// Its `magic` field must always be 14 /// `wasmtime_environ::VM_ARRAY_CALL_HOST_FUNC_MAGIC`, and this is how you can 15 /// determine whether a `VM*Context` is a `VMArrayCallHostFuncContext` versus a 16 /// different kind of context. 17 #[repr(C)] 18 pub struct VMArrayCallHostFuncContext { 19 magic: u32, 20 // _padding: u32, // (on 64-bit systems) 21 pub(crate) func_ref: VMFuncRef, 22 host_state: Box<dyn Any + Send + Sync>, 23 } 24 25 impl VMArrayCallHostFuncContext { 26 /// Create the context for the given host function. 27 /// 28 /// # Safety 29 /// 30 /// The `host_func` must be a pointer to a host (not Wasm) function and it 31 /// must be `Send` and `Sync`. 32 pub unsafe fn new( 33 func_ref: VMFuncRef, 34 host_state: Box<dyn Any + Send + Sync>, 35 ) -> StoreBox<VMArrayCallHostFuncContext> { 36 debug_assert!(func_ref.vmctx.is_null()); 37 let ctx = StoreBox::new(VMArrayCallHostFuncContext { 38 magic: wasmtime_environ::VM_ARRAY_CALL_HOST_FUNC_MAGIC, 39 func_ref, 40 host_state, 41 }); 42 let vmctx = VMOpaqueContext::from_vm_array_call_host_func_context(ctx.get()); 43 unsafe { 44 (*ctx.get()).func_ref.vmctx = vmctx; 45 } 46 ctx 47 } 48 49 /// Get the host state for this host function context. 50 #[inline] 51 pub fn host_state(&self) -> &(dyn Any + Send + Sync) { 52 &*self.host_state 53 } 54 55 /// Get this context's `VMFuncRef`. 56 #[inline] 57 pub fn func_ref(&self) -> &VMFuncRef { 58 &self.func_ref 59 } 60 61 /// Helper function to cast between context types using a debug assertion to 62 /// protect against some mistakes. 63 #[inline] 64 pub unsafe fn from_opaque(opaque: *mut VMOpaqueContext) -> *mut VMArrayCallHostFuncContext { 65 // See comments in `VMContext::from_opaque` for this debug assert 66 debug_assert_eq!((*opaque).magic, VM_ARRAY_CALL_HOST_FUNC_MAGIC); 67 opaque.cast() 68 } 69 } 70 71 #[test] 72 fn vmarray_call_host_func_context_offsets() { 73 use core::mem::offset_of; 74 use wasmtime_environ::{HostPtr, PtrSize}; 75 assert_eq!( 76 usize::from(HostPtr.vmarray_call_host_func_context_func_ref()), 77 offset_of!(VMArrayCallHostFuncContext, func_ref) 78 ); 79 } 80