Skip to content

Commit

Permalink
Use a helper method to invoke VMFuncRef::array_call
Browse files Browse the repository at this point in the history
This is intended to encapsulate the usage of a native raw pointer and in
the future act as a dispatch point for invoking Pulley instead of native
code.
  • Loading branch information
alexcrichton committed Nov 20, 2024
1 parent 3e0b7e5 commit ca4833a
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 37 deletions.
9 changes: 5 additions & 4 deletions crates/wasmtime/src/runtime/component/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<ValRaw>(),
core::ptr::slice_from_raw_parts_mut(
space.as_mut_ptr().cast(),
mem::size_of_val(space) / mem::size_of::<ValRaw>(),
),
)?;

// Note that `.assume_init_ref()` here is unsafe but we're relying
Expand Down Expand Up @@ -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(),
)?;
}

Expand Down
2 changes: 1 addition & 1 deletion crates/wasmtime/src/runtime/component/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<U>(&self, cx: &mut LowerContext<'_, U>, ty: InterfaceType) -> Result<u32> {
Expand Down
28 changes: 10 additions & 18 deletions crates/wasmtime/src/runtime/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(
store: &mut StoreContextMut<'_, T>,
func_ref: NonNull<VMFuncRef>,
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::<VMOpaqueContext>(),
params_and_returns,
params_and_returns_capacity,
)
func_ref
.as_ref()
.array_call(caller.cast::<VMOpaqueContext>(), params_and_returns)
})
}

Expand Down Expand Up @@ -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) {
Expand Down
14 changes: 7 additions & 7 deletions crates/wasmtime/src/runtime/func/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<_, _>>(storage) / mem::size_of::<ValRaw>(),
);
let storage_len = mem::size_of_val::<Storage<_, _>>(storage) / mem::size_of::<ValRaw>();
let storage: *mut Storage<_, _> = storage;
let storage = storage.cast::<ValRaw>();
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;
Expand Down
10 changes: 3 additions & 7 deletions crates/wasmtime/src/runtime/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
Expand Down
28 changes: 28 additions & 0 deletions crates/wasmtime/src/runtime/vm/vmcontext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit ca4833a

Please sign in to comment.