Skip to content

Commit 5b6a711

Browse files
committed
Use TryVec in the store's FuncRefs structure
1 parent 837d02f commit 5b6a711

File tree

4 files changed

+41
-35
lines changed

4 files changed

+41
-35
lines changed

crates/wasmtime/src/runtime/func.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ impl Func {
381381

382382
// SAFETY: the `T` used by `func` matches the `T` of the store we're
383383
// inserting into via this function's type signature.
384-
unsafe { host.into_func(store) }
384+
unsafe { host.into_func(store).panic_on_oom() }
385385
}
386386

387387
/// Creates a new [`Func`] with the given arguments, although has fewer
@@ -425,7 +425,7 @@ impl Func {
425425

426426
// SAFETY: the `T` used by `func` matches the `T` of the store we're
427427
// inserting into via this function's type signature.
428-
unsafe { host.into_func(store) }
428+
unsafe { host.into_func(store).panic_on_oom() }
429429
}
430430

431431
/// Creates a new host-defined WebAssembly function which, when called,
@@ -516,7 +516,7 @@ impl Func {
516516

517517
// SAFETY: the `T` used by `func` matches the `T` of the store we're
518518
// inserting into via this function's type signature.
519-
unsafe { host.into_func(store) }
519+
unsafe { host.into_func(store).panic_on_oom() }
520520
}
521521

522522
/// Creates a new `Func` from a store and a funcref within that store.
@@ -795,7 +795,7 @@ impl Func {
795795

796796
// SAFETY: The `T` the closure takes is the same as the `T` of the store
797797
// we're inserting into via the type signature above.
798-
unsafe { host.into_func(store) }
798+
unsafe { host.into_func(store).panic_on_oom() }
799799
}
800800

801801
/// Same as [`Func::wrap`], except the closure asynchronously produces the
@@ -817,7 +817,7 @@ impl Func {
817817

818818
// SAFETY: The `T` the closure takes is the same as the `T` of the store
819819
// we're inserting into via the type signature above.
820-
unsafe { host.into_func(store) }
820+
unsafe { host.into_func(store).panic_on_oom() }
821821
}
822822

823823
/// Returns the underlying wasm type that this `Func` has.
@@ -2625,13 +2625,13 @@ impl HostFunc {
26252625
///
26262626
/// Can only be inserted into stores with a matching `T` relative to when
26272627
/// this `HostFunc` was first created.
2628-
pub unsafe fn to_func(self: &Arc<Self>, store: &mut StoreOpaque) -> Func {
2628+
pub unsafe fn to_func(self: &Arc<Self>, store: &mut StoreOpaque) -> Result<Func, OutOfMemory> {
26292629
self.validate_store(store);
26302630
let (funcrefs, modules) = store.func_refs_and_modules();
2631-
let funcref = funcrefs.push_arc_host(self.clone(), modules);
2631+
let funcref = funcrefs.push_arc_host(self.clone(), modules)?;
26322632
// SAFETY: this funcref was just pushed within the store, so it's safe
26332633
// to say this store owns it.
2634-
unsafe { Func::from_vm_func_ref(store.id(), funcref) }
2634+
Ok(unsafe { Func::from_vm_func_ref(store.id(), funcref) })
26352635
}
26362636

26372637
/// Inserts this `HostFunc` into a `Store`, returning the `Func` pointing to
@@ -2685,18 +2685,18 @@ impl HostFunc {
26852685
}
26862686

26872687
/// Same as [`HostFunc::to_func`], different ownership.
2688-
unsafe fn into_func(self, store: &mut StoreOpaque) -> Func {
2688+
unsafe fn into_func(self, store: &mut StoreOpaque) -> Result<Func, OutOfMemory> {
26892689
self.validate_store(store);
26902690

26912691
// This function could be called by a guest at any time, and it requires
26922692
// fibers, so the store now required async entrypoints.
26932693
store.set_async_required(self.asyncness);
26942694

26952695
let (funcrefs, modules) = store.func_refs_and_modules();
2696-
let funcref = funcrefs.push_box_host(Box::new(self), modules);
2696+
let funcref = funcrefs.push_box_host(Box::new(self), modules)?;
26972697
// SAFETY: this funcref was just pushed within `store`, so it's safe to
26982698
// say it's owned by the store's id.
2699-
unsafe { Func::from_vm_func_ref(store.id(), funcref) }
2699+
Ok(unsafe { Func::from_vm_func_ref(store.id(), funcref) })
27002700
}
27012701

27022702
fn validate_store(&self, store: &mut StoreOpaque) {

crates/wasmtime/src/runtime/instance.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -976,14 +976,14 @@ fn pre_instantiate_raw(
976976
// will insert a function into the store automatically as part of
977977
// instantiation, so reserve space here to make insertion more efficient
978978
// as it won't have to realloc during the instantiation.
979-
funcrefs.reserve_storage(host_funcs);
979+
funcrefs.reserve_storage(host_funcs)?;
980980

981981
// The usage of `to_extern_store_rooted` requires that the items are
982982
// rooted via another means, which happens here by cloning the list of
983983
// items into the store once. This avoids cloning each individual item
984984
// below.
985-
funcrefs.push_instance_pre_definitions(items.clone());
986-
funcrefs.push_instance_pre_func_refs(func_refs.clone());
985+
funcrefs.push_instance_pre_definitions(items.clone())?;
986+
funcrefs.push_instance_pre_func_refs(func_refs.clone())?;
987987
}
988988

989989
store.set_async_required(asyncness);

crates/wasmtime/src/runtime/linker.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use core::future::Future;
1313
use core::marker;
1414
use core::mem::MaybeUninit;
1515
use log::warn;
16-
use wasmtime_environ::{Atom, StringPool};
16+
use wasmtime_environ::{Atom, PanicOnOom, StringPool};
1717

1818
/// Structure used to link wasm modules/instances together.
1919
///
@@ -1348,7 +1348,7 @@ impl Definition {
13481348
// SAFETY: the contract of this function is the same as what's
13491349
// required of `to_func`, that `T` of the store matches the `T` of
13501350
// this original definition.
1351-
Definition::HostFunc(func) => unsafe { func.to_func(store).into() },
1351+
Definition::HostFunc(func) => unsafe { func.to_func(store).panic_on_oom().into() },
13521352
}
13531353
}
13541354

crates/wasmtime/src/runtime/store/func_refs.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ pub struct FuncRefs {
2222

2323
/// Pointers into `self.bump` for entries that need `wasm_call` field filled
2424
/// in.
25-
with_holes: Vec<SendSyncPtr<VMFuncRef>>,
25+
with_holes: TryVec<SendSyncPtr<VMFuncRef>>,
2626

2727
/// General-purpose storage of "function things" that need to live as long
2828
/// as the entire store.
29-
storage: Vec<Storage>,
29+
storage: TryVec<Storage>,
3030
}
3131

3232
/// Various items to place in `FuncRefs::storage`
@@ -90,17 +90,17 @@ impl FuncRefs {
9090
&mut self,
9191
func_ref: VMFuncRef,
9292
modules: &ModuleRegistry,
93-
) -> NonNull<VMFuncRef> {
93+
) -> Result<NonNull<VMFuncRef>, OutOfMemory> {
9494
debug_assert!(func_ref.wasm_call.is_none());
9595
let func_ref = self.bump.get_mut().alloc(func_ref);
9696
// SAFETY: it's a contract of this function itself that `func_ref` has a
9797
// valid vmctx field to read.
9898
let has_hole = unsafe { !try_fill(func_ref, modules) };
9999
let unpatched = SendSyncPtr::from(func_ref);
100100
if has_hole {
101-
self.with_holes.push(unpatched);
101+
self.with_holes.push(unpatched)?;
102102
}
103-
unpatched.as_non_null()
103+
Ok(unpatched.as_non_null())
104104
}
105105

106106
/// Patch any `VMFuncRef::wasm_call`s that need filling in.
@@ -110,25 +110,31 @@ impl FuncRefs {
110110
}
111111

112112
/// Reserves `amt` space for extra items in "storage" for this store.
113-
pub fn reserve_storage(&mut self, amt: usize) {
114-
self.storage.reserve(amt);
113+
pub fn reserve_storage(&mut self, amt: usize) -> Result<(), OutOfMemory> {
114+
self.storage.reserve(amt)
115115
}
116116

117117
/// Push pre-patched `VMFuncRef`s from an `InstancePre`.
118118
///
119119
/// This is used to ensure that the store itself persists the entire list of
120120
/// `funcs` for the entire lifetime of the store.
121-
pub fn push_instance_pre_func_refs(&mut self, funcs: Arc<TryVec<VMFuncRef>>) {
122-
self.storage.push(Storage::InstancePreFuncRefs { funcs });
121+
pub fn push_instance_pre_func_refs(
122+
&mut self,
123+
funcs: Arc<TryVec<VMFuncRef>>,
124+
) -> Result<(), OutOfMemory> {
125+
self.storage.push(Storage::InstancePreFuncRefs { funcs })
123126
}
124127

125128
/// Push linker definitions into storage, keeping them alive for the entire
126129
/// lifetime of the store.
127130
///
128131
/// This is used to keep linker-defined functions' vmctx values alive, for
129132
/// example.
130-
pub fn push_instance_pre_definitions(&mut self, defs: Arc<TryVec<Definition>>) {
131-
self.storage.push(Storage::InstancePreDefinitions { defs });
133+
pub fn push_instance_pre_definitions(
134+
&mut self,
135+
defs: Arc<TryVec<Definition>>,
136+
) -> Result<(), OutOfMemory> {
137+
self.storage.push(Storage::InstancePreDefinitions { defs })
132138
}
133139

134140
/// Pushes a shared host function into this store.
@@ -147,25 +153,25 @@ impl FuncRefs {
147153
&mut self,
148154
func: Arc<HostFunc>,
149155
modules: &ModuleRegistry,
150-
) -> NonNull<VMFuncRef> {
156+
) -> Result<NonNull<VMFuncRef>, OutOfMemory> {
151157
debug_assert!(func.func_ref().wasm_call.is_none());
152158
// SAFETY: the vmctx field in the funcref of `HostFunc` is safe to read.
153-
let ret = unsafe { self.push(func.func_ref().clone(), modules) };
154-
self.storage.push(Storage::ArcHost { func });
155-
ret
159+
let ret = unsafe { self.push(func.func_ref().clone(), modules)? };
160+
self.storage.push(Storage::ArcHost { func })?;
161+
Ok(ret)
156162
}
157163

158164
/// Same as `push_arc_host`, but for owned host functions.
159165
pub fn push_box_host(
160166
&mut self,
161167
func: Box<HostFunc>,
162168
modules: &ModuleRegistry,
163-
) -> NonNull<VMFuncRef> {
169+
) -> Result<NonNull<VMFuncRef>, OutOfMemory> {
164170
debug_assert!(func.func_ref().wasm_call.is_none());
165171
// SAFETY: the vmctx field in the funcref of `HostFunc` is safe to read.
166-
let ret = unsafe { self.push(func.func_ref().clone(), modules) };
167-
self.storage.push(Storage::BoxHost { func });
168-
ret
172+
let ret = unsafe { self.push(func.func_ref().clone(), modules)? };
173+
self.storage.push(Storage::BoxHost { func })?;
174+
Ok(ret)
169175
}
170176
}
171177

0 commit comments

Comments
 (0)