@@ -1,6 +1,6 @@
|
|||||||
use crate::runtime::StoreInner;
|
use crate::runtime::StoreInner;
|
||||||
use crate::trampoline::StoreInstanceHandle;
|
use crate::trampoline::StoreInstanceHandle;
|
||||||
use crate::{Extern, FuncType, Memory, Store, Trap, Val, ValType};
|
use crate::{Extern, ExternRef, FuncType, Memory, Store, Trap, Val, ValType};
|
||||||
use anyhow::{bail, ensure, Context as _, Result};
|
use anyhow::{bail, ensure, Context as _, Result};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
@@ -1131,6 +1131,61 @@ unsafe impl WasmTy for f64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl WasmTy for Option<ExternRef> {
|
||||||
|
type Abi = *mut u8;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn into_abi_for_arg<'a>(self, store: WeakStore<'a>) -> Self::Abi {
|
||||||
|
if let Some(x) = self {
|
||||||
|
let store = Store::upgrade(store.0).unwrap();
|
||||||
|
let abi = x.inner.as_raw();
|
||||||
|
unsafe {
|
||||||
|
store
|
||||||
|
.externref_activations_table()
|
||||||
|
.insert_with_gc(x.inner, store.stack_map_registry());
|
||||||
|
}
|
||||||
|
abi
|
||||||
|
} else {
|
||||||
|
ptr::null_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn from_abi<'a>(abi: Self::Abi, _store: WeakStore<'a>) -> Self {
|
||||||
|
if abi.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(ExternRef {
|
||||||
|
inner: wasmtime_runtime::VMExternRef::clone_from_raw(abi),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push(dst: &mut Vec<ValType>) {
|
||||||
|
dst.push(ValType::ExternRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn matches(mut tys: impl Iterator<Item = ValType>) -> anyhow::Result<()> {
|
||||||
|
let next = tys.next();
|
||||||
|
ensure!(
|
||||||
|
next == Some(ValType::ExternRef),
|
||||||
|
"Type mismatch, expected externref, got {:?}",
|
||||||
|
next
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn load_from_args(ptr: &mut *const u128) -> Self::Abi {
|
||||||
|
let ret = **ptr as usize as *mut u8;
|
||||||
|
*ptr = (*ptr).add(1);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn store_to_args(abi: Self::Abi, ptr: *mut u128) {
|
||||||
|
ptr::write(ptr, abi as usize as u128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl<T> WasmRet for T
|
unsafe impl<T> WasmRet for T
|
||||||
where
|
where
|
||||||
T: WasmTy,
|
T: WasmTy,
|
||||||
|
|||||||
@@ -160,35 +160,16 @@ fn many_live_refs() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let live_refs = Rc::new(Cell::new(0));
|
let live_refs = Rc::new(Cell::new(0));
|
||||||
|
|
||||||
let make_ref = Func::new(
|
let make_ref = Func::wrap(&store, {
|
||||||
&store,
|
let live_refs = live_refs.clone();
|
||||||
FuncType::new(
|
move || Some(ExternRef::new(CountLiveRefs::new(live_refs.clone())))
|
||||||
vec![].into_boxed_slice(),
|
});
|
||||||
vec![ValType::ExternRef].into_boxed_slice(),
|
|
||||||
),
|
|
||||||
{
|
|
||||||
let live_refs = live_refs.clone();
|
|
||||||
move |_caller, _params, results| {
|
|
||||||
results[0] =
|
|
||||||
Val::ExternRef(Some(ExternRef::new(CountLiveRefs::new(live_refs.clone()))));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let observe_ref = Func::new(
|
let observe_ref = Func::wrap(&store, |r: Option<ExternRef>| {
|
||||||
&store,
|
let r = r.unwrap();
|
||||||
FuncType::new(
|
let r = r.data().downcast_ref::<CountLiveRefs>().unwrap();
|
||||||
vec![ValType::ExternRef].into_boxed_slice(),
|
assert!(r.live_refs.get() > 0);
|
||||||
vec![].into_boxed_slice(),
|
});
|
||||||
),
|
|
||||||
|_caller, params, _results| {
|
|
||||||
let r = params[0].externref().unwrap().unwrap();
|
|
||||||
let r = r.data().downcast_ref::<CountLiveRefs>().unwrap();
|
|
||||||
assert!(r.live_refs.get() > 0);
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let instance = Instance::new(&store, &module, &[make_ref.into(), observe_ref.into()])?;
|
let instance = Instance::new(&store, &module, &[make_ref.into(), observe_ref.into()])?;
|
||||||
let many_live_refs = instance.get_func("many_live_refs").unwrap();
|
let many_live_refs = instance.get_func("many_live_refs").unwrap();
|
||||||
@@ -413,14 +394,7 @@ fn gc_during_gc_from_many_table_gets() -> anyhow::Result<()> {
|
|||||||
"#,
|
"#,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let observe_ref = Func::new(
|
let observe_ref = Func::wrap(&store, |_: Option<ExternRef>| {});
|
||||||
&store,
|
|
||||||
FuncType::new(
|
|
||||||
vec![ValType::ExternRef].into_boxed_slice(),
|
|
||||||
vec![].into_boxed_slice(),
|
|
||||||
),
|
|
||||||
|_caller, _params, _results| Ok(()),
|
|
||||||
);
|
|
||||||
|
|
||||||
let instance = Instance::new(&store, &module, &[observe_ref.into()])?;
|
let instance = Instance::new(&store, &module, &[observe_ref.into()])?;
|
||||||
let init = instance.get_func("init").unwrap();
|
let init = instance.get_func("init").unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user