Skip to content

Commit c52b941

Browse files
authored
Use NonNull for VMFuncRef in more places (#9677)
* Use `NonNull` for `VMFuncRef` in more places This commit switches to using `NonNull<VMFuncRef>` in more places instead of `*mut VMFuncRef`. A few minor locations benefitted from this by removing some otherwise extraneous checks but most places have been updated to mostly do the same as before. The goal of this commit is to make it more clear about what returns a nullable reference and what never returns a nullable reference. Additionally some constructors now unconditionally work with `NonNull<T>` instead of checking for null internally. * Fix a refactoring typo
1 parent 8e8ad73 commit c52b941

File tree

11 files changed

+56
-56
lines changed

11 files changed

+56
-56
lines changed

crates/wasmtime/src/runtime/externals/table.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl Table {
163163
unsafe {
164164
match (*table).get(gc_store, index)? {
165165
runtime::TableElement::FuncRef(f) => {
166-
let func = Func::from_vm_func_ref(&mut store, f);
166+
let func = f.map(|f| Func::from_vm_func_ref(&mut store, f));
167167
Some(func.into())
168168
}
169169

crates/wasmtime/src/runtime/func.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -573,12 +573,11 @@ impl Func {
573573

574574
pub(crate) unsafe fn from_vm_func_ref(
575575
store: &mut StoreOpaque,
576-
raw: *mut VMFuncRef,
577-
) -> Option<Func> {
578-
let func_ref = NonNull::new(raw)?;
576+
func_ref: NonNull<VMFuncRef>,
577+
) -> Func {
579578
debug_assert!(func_ref.as_ref().type_index != VMSharedTypeIndex::default());
580579
let export = ExportFunction { func_ref };
581-
Some(Func::from_wasmtime_function(export, store))
580+
Func::from_wasmtime_function(export, store)
582581
}
583582

584583
/// Creates a new `Func` from the given Rust closure.
@@ -1091,7 +1090,7 @@ impl Func {
10911090
}
10921091

10931092
pub(crate) unsafe fn _from_raw(store: &mut StoreOpaque, raw: *mut c_void) -> Option<Func> {
1094-
Func::from_vm_func_ref(store, raw.cast())
1093+
Some(Func::from_vm_func_ref(store, NonNull::new(raw.cast())?))
10951094
}
10961095

10971096
/// Extracts the raw value of this `Func`, which is owned by `store`.

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use core::ffi::c_void;
1010
use core::marker;
1111
use core::mem::{self, MaybeUninit};
1212
use core::num::NonZeroUsize;
13-
use core::ptr::{self};
13+
use core::ptr::{self, NonNull};
1414
use wasmtime_environ::VMSharedTypeIndex;
1515

1616
/// A statically typed WebAssembly function.
@@ -566,9 +566,8 @@ unsafe impl WasmTy for Func {
566566

567567
#[inline]
568568
unsafe fn load(store: &mut AutoAssertNoGc<'_>, ptr: &ValRaw) -> Self {
569-
let p = ptr.get_funcref();
570-
debug_assert!(!p.is_null());
571-
Func::from_vm_func_ref(store, p.cast()).unwrap()
569+
let p = NonNull::new(ptr.get_funcref()).unwrap().cast();
570+
Func::from_vm_func_ref(store, p)
572571
}
573572
}
574573

@@ -617,7 +616,8 @@ unsafe impl WasmTy for Option<Func> {
617616

618617
#[inline]
619618
unsafe fn load(store: &mut AutoAssertNoGc<'_>, ptr: &ValRaw) -> Self {
620-
Func::from_vm_func_ref(store, ptr.get_funcref().cast())
619+
let ptr = NonNull::new(ptr.get_funcref())?.cast();
620+
Some(Func::from_vm_func_ref(store, ptr))
621621
}
622622
}
623623

crates/wasmtime/src/runtime/values.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -974,14 +974,14 @@ impl Ref {
974974
match (self, ty.heap_type().top()) {
975975
(Ref::Func(None), HeapType::Func) => {
976976
assert!(ty.is_nullable());
977-
Ok(TableElement::FuncRef(ptr::null_mut()))
977+
Ok(TableElement::FuncRef(None))
978978
}
979979
(Ref::Func(Some(f)), HeapType::Func) => {
980980
debug_assert!(
981981
f.comes_from_same_store(&store),
982982
"checked in `ensure_matches_ty`"
983983
);
984-
Ok(TableElement::FuncRef(f.vm_func_ref(&mut store).as_ptr()))
984+
Ok(TableElement::FuncRef(Some(f.vm_func_ref(&mut store))))
985985
}
986986

987987
(Ref::Extern(e), HeapType::Extern) => match e {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'a> ConstEvalContext<'a> {
4444

4545
fn ref_func(&mut self, index: FuncIndex) -> Result<ValRaw> {
4646
Ok(ValRaw::funcref(
47-
self.instance.get_func_ref(index).unwrap().cast(),
47+
self.instance.get_func_ref(index).unwrap().as_ptr().cast(),
4848
))
4949
}
5050

crates/wasmtime/src/runtime/vm/gc/enabled/arrayref.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,7 @@ impl VMArrayRef {
172172
.func_ref_table
173173
.get_untyped(func_ref_id);
174174
Val::FuncRef(unsafe {
175-
Func::from_vm_func_ref(
176-
store,
177-
func_ref.map_or(core::ptr::null_mut(), |f| f.as_ptr()),
178-
)
175+
func_ref.map(|p| Func::from_vm_func_ref(store, p.as_non_null()))
179176
})
180177
}
181178
otherwise => unreachable!("not a top type: {otherwise:?}"),

crates/wasmtime/src/runtime/vm/gc/enabled/structref.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,7 @@ impl VMStructRef {
166166
.func_ref_table
167167
.get_untyped(func_ref_id);
168168
Val::FuncRef(unsafe {
169-
Func::from_vm_func_ref(
170-
store,
171-
func_ref.map_or(core::ptr::null_mut(), |f| f.as_ptr()),
172-
)
169+
func_ref.map(|p| Func::from_vm_func_ref(store, p.as_non_null()))
173170
})
174171
}
175172
otherwise => unreachable!("not a top type: {otherwise:?}"),

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

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,6 @@ impl Instance {
650650

651651
fn get_exported_func(&mut self, index: FuncIndex) -> ExportFunction {
652652
let func_ref = self.get_func_ref(index).unwrap();
653-
let func_ref = NonNull::new(func_ref as *const VMFuncRef as *mut _).unwrap();
654653
ExportFunction { func_ref }
655654
}
656655

@@ -880,7 +879,7 @@ impl Instance {
880879
///
881880
/// The returned reference is a stable reference that won't be moved and can
882881
/// be passed into JIT code.
883-
pub(crate) fn get_func_ref(&mut self, index: FuncIndex) -> Option<*mut VMFuncRef> {
882+
pub(crate) fn get_func_ref(&mut self, index: FuncIndex) -> Option<NonNull<VMFuncRef>> {
884883
if index == FuncIndex::reserved_value() {
885884
return None;
886885
}
@@ -918,7 +917,7 @@ impl Instance {
918917
.vmctx_plus_offset_mut::<VMFuncRef>(self.offsets().vmctx_func_ref(func.func_ref));
919918
self.construct_func_ref(index, sig, func_ref);
920919

921-
Some(func_ref)
920+
Some(NonNull::new(func_ref).unwrap())
922921
}
923922
}
924923

@@ -1010,12 +1009,7 @@ impl Instance {
10101009
.get(src..)
10111010
.and_then(|s| s.get(..len))
10121011
.ok_or(Trap::TableOutOfBounds)?;
1013-
table.init_func(
1014-
dst,
1015-
elements
1016-
.iter()
1017-
.map(|idx| self.get_func_ref(*idx).unwrap_or(ptr::null_mut())),
1018-
)?;
1012+
table.init_func(dst, elements.iter().map(|idx| self.get_func_ref(*idx)))?;
10191013
}
10201014
TableSegmentElements::Expressions(exprs) => {
10211015
let exprs = exprs
@@ -1045,11 +1039,13 @@ impl Instance {
10451039
WasmHeapTopType::Func => table.init_func(
10461040
dst,
10471041
exprs.iter().map(|expr| unsafe {
1048-
const_evaluator
1049-
.eval(store, &mut context, expr)
1050-
.expect("const expr should be valid")
1051-
.get_funcref()
1052-
.cast()
1042+
NonNull::new(
1043+
const_evaluator
1044+
.eval(store, &mut context, expr)
1045+
.expect("const expr should be valid")
1046+
.get_funcref()
1047+
.cast(),
1048+
)
10531049
}),
10541050
)?,
10551051
}
@@ -1283,9 +1279,7 @@ impl Instance {
12831279
};
12841280
// Panicking here helps catch bugs rather than silently truncating by accident.
12851281
let func_index = precomputed.get(usize::try_from(i).unwrap()).cloned();
1286-
let func_ref = func_index
1287-
.and_then(|func_index| self.get_func_ref(func_index))
1288-
.unwrap_or(ptr::null_mut());
1282+
let func_ref = func_index.and_then(|func_index| self.get_func_ref(func_index));
12891283
self.tables[idx]
12901284
.1
12911285
.set(i, TableElement::FuncRef(func_ref))

crates/wasmtime/src/runtime/vm/instance/allocator.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::runtime::vm::table::Table;
88
use crate::runtime::vm::{CompiledModuleId, ModuleRuntimeInfo, VMFuncRef, VMGcRef, VMStore};
99
use crate::store::{AutoAssertNoGc, StoreOpaque};
1010
use crate::vm::VMGlobalDefinition;
11+
use core::ptr::NonNull;
1112
use core::{any::Any, mem, ptr};
1213
use wasmtime_environ::{
1314
DefinedMemoryIndex, DefinedTableIndex, HostPtr, InitMemory, MemoryInitialization,
@@ -594,7 +595,7 @@ fn initialize_tables(
594595
}
595596

596597
WasmHeapTopType::Func => {
597-
let funcref = raw.get_funcref().cast::<VMFuncRef>();
598+
let funcref = NonNull::new(raw.get_funcref().cast::<VMFuncRef>());
598599
let items = (0..table.size()).map(|_| funcref);
599600
table.init_func(0, items).err2anyhow()?;
600601
}

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

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ use crate::prelude::*;
5858
use crate::runtime::vm::table::{Table, TableElementType};
5959
use crate::runtime::vm::vmcontext::VMFuncRef;
6060
use crate::runtime::vm::{Instance, TrapReason, VMGcRef, VMStore};
61+
use core::ptr::NonNull;
6162
#[cfg(feature = "threads")]
6263
use core::time::Duration;
6364
use wasmtime_environ::Unsigned;
@@ -87,6 +88,7 @@ pub mod raw {
8788
#![allow(unused_doc_comments, unused_attributes)]
8889

8990
use crate::runtime::vm::{InstanceAndStore, TrapReason, VMContext};
91+
use core::ptr::NonNull;
9092

9193
macro_rules! libcall {
9294
(
@@ -184,6 +186,13 @@ pub mod raw {
184186
}
185187
}
186188

189+
impl LibcallResult for NonNull<u8> {
190+
type Abi = *mut u8;
191+
unsafe fn convert(self) -> *mut u8 {
192+
self.as_ptr()
193+
}
194+
}
195+
187196
impl LibcallResult for bool {
188197
type Abi = u32;
189198
unsafe fn convert(self) -> u32 {
@@ -217,7 +226,7 @@ unsafe fn table_grow_func_ref(
217226
let table_index = TableIndex::from_u32(table_index);
218227

219228
let element = match instance.table_element_type(table_index) {
220-
TableElementType::Func => (init_value as *mut VMFuncRef).into(),
229+
TableElementType::Func => NonNull::new(init_value.cast::<VMFuncRef>()).into(),
221230
TableElementType::GcRef => unreachable!(),
222231
};
223232

@@ -271,7 +280,7 @@ unsafe fn table_fill_func_ref(
271280
let table = &mut *instance.get_table(table_index);
272281
match table.element_type() {
273282
TableElementType::Func => {
274-
let val = val.cast::<VMFuncRef>();
283+
let val = NonNull::new(val.cast::<VMFuncRef>());
275284
table
276285
.fill(store.optional_gc_store_mut()?, dst, val.into(), len)
277286
.err2anyhow()?;
@@ -401,7 +410,7 @@ fn memory_init(
401410
}
402411

403412
// Implementation of `ref.func`.
404-
fn ref_func(_store: &mut dyn VMStore, instance: &mut Instance, func_index: u32) -> *mut u8 {
413+
fn ref_func(_store: &mut dyn VMStore, instance: &mut Instance, func_index: u32) -> NonNull<u8> {
405414
instance
406415
.get_func_ref(FuncIndex::from_u32(func_index))
407416
.expect("ref_func: funcref should always be available for given func index")
@@ -427,7 +436,10 @@ unsafe fn table_get_lazy_init_func_ref(
427436
.get(None, index)
428437
.expect("table access already bounds-checked");
429438

430-
elem.into_func_ref_asserting_initialized().cast()
439+
match elem.into_func_ref_asserting_initialized() {
440+
Some(ptr) => ptr.as_ptr().cast(),
441+
None => core::ptr::null_mut(),
442+
}
431443
}
432444

433445
/// Drop a GC reference.
@@ -802,9 +814,8 @@ unsafe fn array_new_elem(
802814
.ok_or_else(|| Trap::TableOutOfBounds.into_anyhow())?
803815
.iter()
804816
.map(|f| {
805-
let raw_func_ref =
806-
instance.get_func_ref(*f).unwrap_or(core::ptr::null_mut());
807-
let func = Func::from_vm_func_ref(store, raw_func_ref);
817+
let raw_func_ref = instance.get_func_ref(*f);
818+
let func = raw_func_ref.map(|p| Func::from_vm_func_ref(store, p));
808819
Val::FuncRef(func)
809820
}),
810821
);
@@ -910,8 +921,8 @@ unsafe fn array_init_elem(
910921
.ok_or_else(|| Trap::TableOutOfBounds.into_anyhow())?
911922
.iter()
912923
.map(|f| {
913-
let raw_func_ref = instance.get_func_ref(*f).unwrap_or(core::ptr::null_mut());
914-
let func = Func::from_vm_func_ref(&mut store, raw_func_ref);
924+
let raw_func_ref = instance.get_func_ref(*f);
925+
let func = raw_func_ref.map(|p| Func::from_vm_func_ref(&mut store, p));
915926
Val::FuncRef(func)
916927
})
917928
.collect::<Vec<_>>(),

0 commit comments

Comments
 (0)