Skip to content

Commit 09005e5

Browse files
committed
Reimplement how instance exports are stored/loaded
This commit internally refactors how instance exports are handled and fixes two issues. One issue is that when we instantiate an instance we no longer forcibly load all items from the instance immediately, deferring insertion of each item into the store data tables to happen later as necessary. The next issue is that repeated calls to `Caller::get_export` would continuously insert items into the store data tables. While working as intended this was undesirable because it would continuously push onto a vector that only got deallocated once the entire store was deallocate. Now it's routed to `Instance::get_export` which doesn't have this behavior. Closes #2916 Closes #2983
1 parent 5737558 commit 09005e5

8 files changed

Lines changed: 341 additions & 166 deletions

File tree

crates/runtime/src/instance.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl Instance {
143143
.cast()
144144
}
145145

146-
pub(crate) fn module(&self) -> &Module {
146+
pub(crate) fn module(&self) -> &Arc<Module> {
147147
&self.module
148148
}
149149

@@ -957,7 +957,7 @@ impl InstanceHandle {
957957
}
958958

959959
/// Return a reference to a module.
960-
pub fn module(&self) -> &Module {
960+
pub fn module(&self) -> &Arc<Module> {
961961
self.instance().module()
962962
}
963963

crates/wasmtime/src/func.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::store::{StoreData, StoreOpaque, StoreOpaqueSend, Stored};
22
use crate::{
3-
AsContext, AsContextMut, Engine, Extern, FuncType, InterruptHandle, StoreContext,
3+
AsContext, AsContextMut, Engine, Extern, FuncType, Instance, InterruptHandle, StoreContext,
44
StoreContextMut, Trap, Val, ValType,
55
};
66
use anyhow::{bail, Context as _, Result};
@@ -1514,19 +1514,21 @@ impl<T> Caller<'_, T> {
15141514
/// It's recommended to take care when calling this API and gracefully
15151515
/// handling a `None` return value.
15161516
pub fn get_export(&mut self, name: &str) -> Option<Extern> {
1517-
unsafe {
1518-
let index = self.caller.module().exports.get(name)?;
1519-
match index {
1520-
// Only allow memory/functions for now to emulate what interface
1521-
// types will once provide
1522-
EntityIndex::Memory(_) | EntityIndex::Function(_) => {
1523-
Some(Extern::from_wasmtime_export(
1524-
self.caller.lookup_by_declaration(&index),
1525-
&mut self.store.as_context_mut().opaque(),
1526-
))
1527-
}
1528-
_ => None,
1529-
}
1517+
// All instances created have a `host_state` with a pointer pointing
1518+
// back to themselves. If this caller doesn't have that `host_state`
1519+
// then it probably means it was a host-created object like `Func::new`
1520+
// which doesn't have any exports we want to return anyway.
1521+
match self
1522+
.caller
1523+
.host_state()
1524+
.downcast_ref::<Instance>()?
1525+
.get_export(&mut self.store, name)?
1526+
{
1527+
Extern::Func(f) => Some(Extern::Func(f)),
1528+
Extern::Memory(f) => Some(Extern::Memory(f)),
1529+
// Intentionally ignore other Extern items here since this API is
1530+
// supposed to be a temporary stop-gap until interface types.
1531+
_ => None,
15301532
}
15311533
}
15321534

0 commit comments

Comments
 (0)