wasmtime: Initial, partial support for externref
This is enough to get an `externref -> externref` identity function passing. However, `externref`s that are dropped by compiled Wasm code are (safely) leaked. Follow up work will leverage cranelift's stack maps to resolve this issue.
This commit is contained in:
@@ -16,14 +16,15 @@ wasmtime_c_api_macros::declare_ref!(wasm_instance_t);
|
||||
|
||||
impl wasm_instance_t {
|
||||
pub(crate) fn new(instance: Instance) -> wasm_instance_t {
|
||||
let store = instance.store().clone();
|
||||
wasm_instance_t {
|
||||
instance: HostRef::new(instance),
|
||||
instance: HostRef::new(&store, instance),
|
||||
exports_cache: RefCell::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn externref(&self) -> wasmtime::ExternRef {
|
||||
self.instance.externref()
|
||||
self.instance.clone().into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,12 +35,12 @@ pub unsafe extern "C" fn wasm_instance_new(
|
||||
imports: *const Box<wasm_extern_t>,
|
||||
result: Option<&mut *mut wasm_trap_t>,
|
||||
) -> Option<Box<wasm_instance_t>> {
|
||||
let store = &store.store.borrow();
|
||||
let store = &store.store;
|
||||
let module = &wasm_module.module.borrow();
|
||||
if !Store::same(&store, module.store()) {
|
||||
if let Some(result) = result {
|
||||
let trap = Trap::new("wasm_store_t must match store in wasm_module_t");
|
||||
let trap = Box::new(wasm_trap_t::new(trap));
|
||||
let trap = Box::new(wasm_trap_t::new(store, trap));
|
||||
*result = Box::into_raw(trap);
|
||||
}
|
||||
return None;
|
||||
@@ -58,7 +59,7 @@ pub unsafe extern "C" fn wasm_instance_new(
|
||||
assert!(trap.is_null());
|
||||
assert!(instance.is_null());
|
||||
if let Some(result) = result {
|
||||
*result = Box::into_raw(err.to_trap());
|
||||
*result = Box::into_raw(err.to_trap(store));
|
||||
}
|
||||
None
|
||||
}
|
||||
@@ -111,10 +112,16 @@ fn _wasmtime_instance_new(
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let module = &module.module.borrow();
|
||||
handle_instantiate(Instance::new(module, &imports), instance_ptr, trap_ptr)
|
||||
handle_instantiate(
|
||||
module.store(),
|
||||
Instance::new(module, &imports),
|
||||
instance_ptr,
|
||||
trap_ptr,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn handle_instantiate(
|
||||
store: &Store,
|
||||
instance: Result<Instance>,
|
||||
instance_ptr: &mut *mut wasm_instance_t,
|
||||
trap_ptr: &mut *mut wasm_trap_t,
|
||||
@@ -130,7 +137,7 @@ pub fn handle_instantiate(
|
||||
}
|
||||
Err(e) => match e.downcast::<Trap>() {
|
||||
Ok(trap) => {
|
||||
write(trap_ptr, wasm_trap_t::new(trap));
|
||||
write(trap_ptr, wasm_trap_t::new(store, trap));
|
||||
None
|
||||
}
|
||||
Err(e) => Some(Box::new(e.into())),
|
||||
@@ -146,10 +153,10 @@ pub extern "C" fn wasm_instance_exports(instance: &wasm_instance_t, out: &mut wa
|
||||
instance
|
||||
.exports()
|
||||
.map(|e| match e.into_extern() {
|
||||
Extern::Func(f) => ExternHost::Func(HostRef::new(f)),
|
||||
Extern::Global(f) => ExternHost::Global(HostRef::new(f)),
|
||||
Extern::Memory(f) => ExternHost::Memory(HostRef::new(f)),
|
||||
Extern::Table(f) => ExternHost::Table(HostRef::new(f)),
|
||||
Extern::Func(f) => ExternHost::Func(HostRef::new(instance.store(), f)),
|
||||
Extern::Global(f) => ExternHost::Global(HostRef::new(instance.store(), f)),
|
||||
Extern::Memory(f) => ExternHost::Memory(HostRef::new(instance.store(), f)),
|
||||
Extern::Table(f) => ExternHost::Table(HostRef::new(instance.store(), f)),
|
||||
})
|
||||
.collect()
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user