Skip to content

Commit 2e6b18f

Browse files
authored
Change VMArrayCallFunction to be an opaque pointer (#9638)
This pointer is technically not safe to be a function pointer because it will get unloaded when the module is dropped. Additionally with Pulley this isn't actually a native function pointer. This builds on #9630 to prepare for future integration with Pulley to ensure that the number of locations that have to deal with bytecode-vs-native-code are minimized.
1 parent 9a90021 commit 2e6b18f

File tree

7 files changed

+45
-42
lines changed

7 files changed

+45
-42
lines changed

crates/wasmtime/src/runtime/component/component.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use crate::{
1515
use crate::{FuncType, ValType};
1616
use alloc::sync::Arc;
1717
use core::any::Any;
18-
use core::mem;
1918
use core::ops::Range;
2019
use core::ptr::NonNull;
2120
#[cfg(feature = "std")]
@@ -98,7 +97,7 @@ struct ComponentInner {
9897

9998
pub(crate) struct AllCallFuncPointers {
10099
pub wasm_call: NonNull<VMWasmCallFunction>,
101-
pub array_call: VMArrayCallFunction,
100+
pub array_call: NonNull<VMArrayCallFunction>,
102101
}
103102

104103
impl Component {
@@ -469,11 +468,7 @@ impl Component {
469468
} = &self.inner.info.trampolines[index];
470469
AllCallFuncPointers {
471470
wasm_call: self.func(wasm_call).cast(),
472-
array_call: unsafe {
473-
mem::transmute::<NonNull<VMFunctionBody>, VMArrayCallFunction>(
474-
self.func(array_call),
475-
)
476-
},
471+
array_call: self.func(array_call).cast(),
477472
}
478473
}
479474

crates/wasmtime/src/runtime/func.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use core::future::Future;
1616
use core::mem::{self, MaybeUninit};
1717
use core::num::NonZeroUsize;
1818
use core::pin::Pin;
19-
use core::ptr::{self, NonNull};
19+
use core::ptr::NonNull;
2020
use wasmtime_environ::VMSharedTypeIndex;
2121

2222
/// A reference to the abstract `nofunc` heap value.
@@ -2287,12 +2287,8 @@ impl HostContext {
22872287

22882288
let ctx = unsafe {
22892289
VMArrayCallHostFuncContext::new(
2290-
VMFuncRef {
2291-
array_call,
2292-
wasm_call: None,
2293-
type_index,
2294-
vmctx: ptr::null_mut(),
2295-
},
2290+
array_call,
2291+
type_index,
22962292
Box::new(HostFuncState {
22972293
func,
22982294
ty: ty.into_registered_type(),

crates/wasmtime/src/runtime/trampoline/func.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
//! Support for a calling of an imported function.
22
33
use crate::prelude::*;
4-
use crate::runtime::vm::{
5-
StoreBox, VMArrayCallHostFuncContext, VMContext, VMFuncRef, VMOpaqueContext,
6-
};
4+
use crate::runtime::vm::{StoreBox, VMArrayCallHostFuncContext, VMContext, VMOpaqueContext};
75
use crate::type_registry::RegisteredType;
86
use crate::{FuncType, ValRaw};
9-
use core::ptr;
107

118
struct TrampolineState<F> {
129
func: F,
@@ -81,12 +78,8 @@ where
8178

8279
unsafe {
8380
Ok(VMArrayCallHostFuncContext::new(
84-
VMFuncRef {
85-
array_call,
86-
wasm_call: None,
87-
type_index: sig.index(),
88-
vmctx: ptr::null_mut(),
89-
},
81+
array_call,
82+
sig.index(),
9083
Box::new(TrampolineState { func, sig }),
9184
))
9285
}

crates/wasmtime/src/runtime/vm.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use crate::prelude::*;
99
use crate::store::StoreOpaque;
1010
use alloc::sync::Arc;
1111
use core::fmt;
12-
use core::mem;
1312
use core::ops::Deref;
1413
use core::ops::DerefMut;
1514
use core::ptr::NonNull;
@@ -278,16 +277,16 @@ impl ModuleRuntimeInfo {
278277
///
279278
/// Returns `None` for Wasm functions which do not escape, and therefore are
280279
/// not callable from outside the Wasm module itself.
281-
fn array_to_wasm_trampoline(&self, index: DefinedFuncIndex) -> Option<VMArrayCallFunction> {
280+
fn array_to_wasm_trampoline(
281+
&self,
282+
index: DefinedFuncIndex,
283+
) -> Option<NonNull<VMArrayCallFunction>> {
282284
let m = match self {
283285
ModuleRuntimeInfo::Module(m) => m,
284286
ModuleRuntimeInfo::Bare(_) => unreachable!(),
285287
};
286-
let ptr = m
287-
.compiled_module()
288-
.array_to_wasm_trampoline(index)?
289-
.as_ptr();
290-
Some(unsafe { mem::transmute::<*const u8, VMArrayCallFunction>(ptr) })
288+
let ptr = NonNull::from(m.compiled_module().array_to_wasm_trampoline(index)?);
289+
Some(ptr.cast())
291290
}
292291

293292
/// Returns the `MemoryImage` structure used for copy-on-write

crates/wasmtime/src/runtime/vm/component.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ impl ComponentInstance {
391391
&mut self,
392392
idx: TrampolineIndex,
393393
wasm_call: NonNull<VMWasmCallFunction>,
394-
array_call: VMArrayCallFunction,
394+
array_call: NonNull<VMArrayCallFunction>,
395395
type_index: VMSharedTypeIndex,
396396
) {
397397
unsafe {
@@ -731,7 +731,7 @@ impl OwnedComponentInstance {
731731
&mut self,
732732
idx: TrampolineIndex,
733733
wasm_call: NonNull<VMWasmCallFunction>,
734-
array_call: VMArrayCallFunction,
734+
array_call: NonNull<VMArrayCallFunction>,
735735
type_index: VMSharedTypeIndex,
736736
) {
737737
unsafe {

crates/wasmtime/src/runtime/vm/vmcontext.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,15 @@ use wasmtime_environ::{
3737
///
3838
/// * The capacity of the `ValRaw` buffer. Must always be at least
3939
/// `max(len(wasm_params), len(wasm_results))`.
40-
pub type VMArrayCallFunction =
40+
pub type VMArrayCallNative =
4141
unsafe extern "C" fn(*mut VMOpaqueContext, *mut VMOpaqueContext, *mut ValRaw, usize);
4242

43+
/// An opaque function pointer which might be `VMArrayCallNative` or it might be
44+
/// pulley bytecode. Requires external knowledge to determine what kind of
45+
/// function pointer this is.
46+
#[repr(transparent)]
47+
pub struct VMArrayCallFunction(VMFunctionBody);
48+
4349
/// A function pointer that exposes the Wasm calling convention.
4450
///
4551
/// In practice, different Wasm function types end up mapping to different Rust
@@ -60,7 +66,7 @@ pub struct VMFunctionImport {
6066

6167
/// Function pointer to use when calling this imported function with the
6268
/// "array" calling convention that `Func::new` et al use.
63-
pub array_call: VMArrayCallFunction,
69+
pub array_call: NonNull<VMArrayCallFunction>,
6470

6571
/// The VM state associated with this function.
6672
///
@@ -652,7 +658,7 @@ mod test_vmshared_type_index {
652658
pub struct VMFuncRef {
653659
/// Function pointer for this funcref if being called via the "array"
654660
/// calling convention that `Func::new` et al use.
655-
pub array_call: VMArrayCallFunction,
661+
pub array_call: NonNull<VMArrayCallFunction>,
656662

657663
/// Function pointer for this funcref if being called via the calling
658664
/// convention we use when compiling Wasm.
@@ -709,7 +715,15 @@ impl VMFuncRef {
709715
/// This method is unsafe because it can be called with any pointers. They
710716
/// must all be valid for this wasm function call to proceed.
711717
pub unsafe fn array_call(&self, caller: *mut VMOpaqueContext, args_and_results: *mut [ValRaw]) {
712-
(self.array_call)(
718+
union GetNativePointer {
719+
native: VMArrayCallNative,
720+
ptr: NonNull<VMArrayCallFunction>,
721+
}
722+
let native = GetNativePointer {
723+
ptr: self.array_call,
724+
}
725+
.native;
726+
native(
713727
self.vmctx,
714728
caller,
715729
args_and_results.cast(),

crates/wasmtime/src/runtime/vm/vmcontext/vm_host_func_context.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
//!
33
//! Keep in sync with `wasmtime_environ::VMHostFuncOffsets`.
44
5-
use super::VMOpaqueContext;
5+
use super::{VMArrayCallNative, VMOpaqueContext};
66
use crate::prelude::*;
77
use crate::runtime::vm::{StoreBox, VMFuncRef};
88
use core::any::Any;
9-
use wasmtime_environ::VM_ARRAY_CALL_HOST_FUNC_MAGIC;
9+
use core::ptr::{self, NonNull};
10+
use wasmtime_environ::{VMSharedTypeIndex, VM_ARRAY_CALL_HOST_FUNC_MAGIC};
1011

1112
/// The `VM*Context` for array-call host functions.
1213
///
@@ -30,13 +31,18 @@ impl VMArrayCallHostFuncContext {
3031
/// The `host_func` must be a pointer to a host (not Wasm) function and it
3132
/// must be `Send` and `Sync`.
3233
pub unsafe fn new(
33-
func_ref: VMFuncRef,
34+
host_func: VMArrayCallNative,
35+
type_index: VMSharedTypeIndex,
3436
host_state: Box<dyn Any + Send + Sync>,
3537
) -> StoreBox<VMArrayCallHostFuncContext> {
36-
debug_assert!(func_ref.vmctx.is_null());
3738
let ctx = StoreBox::new(VMArrayCallHostFuncContext {
3839
magic: wasmtime_environ::VM_ARRAY_CALL_HOST_FUNC_MAGIC,
39-
func_ref,
40+
func_ref: VMFuncRef {
41+
array_call: NonNull::new(host_func as *mut u8).unwrap().cast(),
42+
type_index,
43+
wasm_call: None,
44+
vmctx: ptr::null_mut(),
45+
},
4046
host_state,
4147
});
4248
let vmctx = VMOpaqueContext::from_vm_array_call_host_func_context(ctx.get());

0 commit comments

Comments
 (0)