diff --git a/crates/wasmtime/src/runtime/component/func.rs b/crates/wasmtime/src/runtime/component/func.rs index 087a93dcbbb6..6643f6ecef7b 100644 --- a/crates/wasmtime/src/runtime/component/func.rs +++ b/crates/wasmtime/src/runtime/component/func.rs @@ -470,8 +470,10 @@ impl Func { crate::Func::call_unchecked_raw( store, export.func_ref, - space.as_mut_ptr().cast(), - mem::size_of_val(space) / mem::size_of::(), + core::ptr::slice_from_raw_parts_mut( + space.as_mut_ptr().cast(), + mem::size_of_val(space) / mem::size_of::(), + ), )?; // Note that `.assume_init_ref()` here is unsafe but we're relying @@ -620,8 +622,7 @@ impl Func { crate::Func::call_unchecked_raw( &mut store, func.func_ref, - &post_return_arg as *const ValRaw as *mut ValRaw, - 1, + core::ptr::slice_from_raw_parts(&post_return_arg, 1).cast_mut(), )?; } diff --git a/crates/wasmtime/src/runtime/component/resources.rs b/crates/wasmtime/src/runtime/component/resources.rs index 312c8216ccd9..b8384b633cfe 100644 --- a/crates/wasmtime/src/runtime/component/resources.rs +++ b/crates/wasmtime/src/runtime/component/resources.rs @@ -1034,7 +1034,7 @@ impl ResourceAny { // destructors have al been previously type-checked and are guaranteed // to take one i32 argument and return no results, so the parameters // here should be configured correctly. - unsafe { crate::Func::call_unchecked_raw(store, dtor, args.as_mut_ptr(), args.len()) } + unsafe { crate::Func::call_unchecked_raw(store, dtor, &mut args) } } fn lower_to_index(&self, cx: &mut LowerContext<'_, U>, ty: InterfaceType) -> Result { diff --git a/crates/wasmtime/src/runtime/func.rs b/crates/wasmtime/src/runtime/func.rs index fa4dadbc08dd..eb5b13724272 100644 --- a/crates/wasmtime/src/runtime/func.rs +++ b/crates/wasmtime/src/runtime/func.rs @@ -1056,34 +1056,23 @@ impl Func { pub unsafe fn call_unchecked( &self, mut store: impl AsContextMut, - params_and_returns: *mut ValRaw, - params_and_returns_capacity: usize, + params_and_returns: *mut [ValRaw], ) -> Result<()> { let mut store = store.as_context_mut(); let data = &store.0.store_data()[self.0]; let func_ref = data.export().func_ref; - Self::call_unchecked_raw( - &mut store, - func_ref, - params_and_returns, - params_and_returns_capacity, - ) + Self::call_unchecked_raw(&mut store, func_ref, params_and_returns) } pub(crate) unsafe fn call_unchecked_raw( store: &mut StoreContextMut<'_, T>, func_ref: NonNull, - params_and_returns: *mut ValRaw, - params_and_returns_capacity: usize, + params_and_returns: *mut [ValRaw], ) -> Result<()> { invoke_wasm_and_catch_traps(store, |caller| { - let func_ref = func_ref.as_ref(); - (func_ref.array_call)( - func_ref.vmctx, - caller.cast::(), - params_and_returns, - params_and_returns_capacity, - ) + func_ref + .as_ref() + .array_call(caller.cast::(), params_and_returns) }) } @@ -1256,7 +1245,10 @@ impl Func { } unsafe { - self.call_unchecked(&mut *store, values_vec.as_mut_ptr(), values_vec_size)?; + self.call_unchecked( + &mut *store, + core::ptr::slice_from_raw_parts_mut(values_vec.as_mut_ptr(), values_vec_size), + )?; } for ((i, slot), val) in results.iter_mut().enumerate().zip(&values_vec) { diff --git a/crates/wasmtime/src/runtime/func/typed.rs b/crates/wasmtime/src/runtime/func/typed.rs index f021909ae7bc..a7b86b5078cd 100644 --- a/crates/wasmtime/src/runtime/func/typed.rs +++ b/crates/wasmtime/src/runtime/func/typed.rs @@ -213,13 +213,13 @@ where let result = invoke_wasm_and_catch_traps(store, |caller| { let (func_ref, storage) = &mut captures; - let func_ref = func_ref.as_ref(); - (func_ref.array_call)( - func_ref.vmctx, - VMOpaqueContext::from_vmcontext(caller), - (storage as *mut Storage<_, _>) as *mut ValRaw, - mem::size_of_val::>(storage) / mem::size_of::(), - ); + let storage_len = mem::size_of_val::>(storage) / mem::size_of::(); + let storage: *mut Storage<_, _> = storage; + let storage = storage.cast::(); + let storage = core::ptr::slice_from_raw_parts_mut(storage, storage_len); + func_ref + .as_ref() + .array_call(VMOpaqueContext::from_vmcontext(caller), storage); }); let (_, storage) = captures; diff --git a/crates/wasmtime/src/runtime/instance.rs b/crates/wasmtime/src/runtime/instance.rs index b4d00ae4e904..ab8e12d16d01 100644 --- a/crates/wasmtime/src/runtime/instance.rs +++ b/crates/wasmtime/src/runtime/instance.rs @@ -362,13 +362,9 @@ impl Instance { let caller_vmctx = instance.vmctx(); unsafe { super::func::invoke_wasm_and_catch_traps(store, |_default_caller| { - let func = f.func_ref.as_ref().array_call; - func( - f.func_ref.as_ref().vmctx, - VMOpaqueContext::from_vmcontext(caller_vmctx), - [].as_mut_ptr(), - 0, - ) + f.func_ref + .as_ref() + .array_call(VMOpaqueContext::from_vmcontext(caller_vmctx), &mut []) })?; } Ok(()) diff --git a/crates/wasmtime/src/runtime/vm/vmcontext.rs b/crates/wasmtime/src/runtime/vm/vmcontext.rs index ddc33e468906..08ea929e539d 100644 --- a/crates/wasmtime/src/runtime/vm/vmcontext.rs +++ b/crates/wasmtime/src/runtime/vm/vmcontext.rs @@ -690,6 +690,34 @@ pub struct VMFuncRef { unsafe impl Send for VMFuncRef {} unsafe impl Sync for VMFuncRef {} +impl VMFuncRef { + /// Invokes the `array_call` field of this `VMFuncRef` with the supplied + /// arguments. + /// + /// This will invoke the function pointer in the `array_call` field with: + /// + /// * the `callee` vmctx as `self.vmctx` + /// * the `caller` as `caller` specified here + /// * the args pointer as `args_and_results` + /// * the args length as `args_and_results` + /// + /// The `args_and_results` area must be large enough to both load all + /// arguments from and store all results to. + /// + /// # Unsafety + /// + /// This method is unsafe because it can be called with any pointers. They + /// must all be valid for this wasm function call to proceed. + pub unsafe fn array_call(&self, caller: *mut VMOpaqueContext, args_and_results: *mut [ValRaw]) { + (self.array_call)( + self.vmctx, + caller, + args_and_results.cast(), + args_and_results.len(), + ) + } +} + #[cfg(test)] mod test_vm_func_ref { use super::VMFuncRef;