Get references passed through globals fully working via top level API

This commit is contained in:
Mark McCaskey
2021-02-23 11:52:31 -08:00
parent 79de368c5c
commit 54b76cddfc
5 changed files with 40 additions and 17 deletions

View File

@@ -79,7 +79,7 @@ impl wasmer_types::ValueEnumType for Function {
/// read the value
// quick hack, make it take `dyn Any`
unsafe fn read_value_from(store: &dyn std::any::Any, p: *const i128) -> Self {
let func_ref = *(p as *const VMFuncRef);
let func_ref = std::ptr::read(p as *const VMFuncRef);
let store = store.downcast_ref::<Store>().unwrap();
match Val::from_checked_anyfunc(func_ref, store) {
Val::FuncRef(Some(fr)) => fr,
@@ -649,6 +649,7 @@ impl Function {
FunctionDefinition::Wasm(wasm) => {
self.call_wasm(&wasm, params, &mut results)?;
}
// TODO: we can trivially hit this, look into it
_ => unimplemented!("The function definition isn't supported for the moment"),
}

View File

@@ -125,7 +125,7 @@ impl Global {
/// assert_eq!(g.get(), Value::I32(1));
/// ```
pub fn get(&self) -> Val {
self.global.get()
self.global.get(&self.store)
}
/// Sets a custom value [`Val`] to the runtime Global.

View File

@@ -72,7 +72,10 @@ impl ValFuncRef for Val {
if func_ref.is_null() {
return Self::FuncRef(None);
}
let item: &wasmer_vm::VMCallerCheckedAnyfunc = unsafe { &**func_ref };
let item: &wasmer_vm::VMCallerCheckedAnyfunc = unsafe {
let anyfunc: *const wasmer_vm::VMCallerCheckedAnyfunc = *func_ref;
&*anyfunc
};
let signature = store
.engine()
.lookup_signature(item.type_index)
@@ -84,6 +87,7 @@ impl ValFuncRef for Val {
vm_function: wasmer_vm::VMExportFunction {
address: item.func_ptr,
signature,
// TODO: review this comment (unclear if it's still correct):
// All functions in tables are already Static (as dynamic functions
// are converted to use the trampolines with static signatures).
kind: wasmer_vm::VMFunctionKind::Static,

View File

@@ -165,8 +165,8 @@ fn refs_in_globals() -> Result<()> {
(global $er_global (export "er_global") (mut externref) (ref.null extern))
(global $fr_global (export "fr_global") (mut funcref) (ref.null func))
(global $fr_immutable_global (export "fr_immutable_global") funcref (ref.func $hello))
(func $hello (param) (result funcref)
(global.get $fr_immutable_global))
(func $hello (param) (result i32)
(i32.const 73))
)"#;
let module = Module::new(&store, wat)?;
let instance = Instance::new(&module, &imports! {})?;
@@ -188,18 +188,36 @@ fn refs_in_globals() -> Result<()> {
}
}
// blocked on needing a store when reading from globals
/*
{
let er_global: &Global = instance.exports.get_global("fr_immutable_global")?;
let fr_global: &Global = instance.exports.get_global("fr_immutable_global")?;
if let Value::FuncRef(f) = er_global.get() {
dbg!(f);
if let Value::FuncRef(Some(f)) = fr_global.get() {
let native_func: NativeFunc<(), u32> = f.native()?;
assert_eq!(native_func.call()?, 73);
} else {
panic!("Did not find func ref in the global");
panic!("Did not find non-null func ref in the global");
}
}
{
let fr_global: &Global = instance.exports.get_global("fr_global")?;
if let Value::FuncRef(None) = fr_global.get() {
} else {
panic!("Did not find a null func ref in the global");
}
let f = Function::new_native(&store, |arg1: i32, arg2: i32| -> i32 { arg1 + arg2 });
fr_global.set(Val::FuncRef(Some(f)))?;
if let Value::FuncRef(Some(f)) = fr_global.get() {
let native: NativeFunc<(i32, i32), i32> = f.native()?;
assert_eq!(native.call(5, 7)?, 12);
} else {
panic!("Did not find extern ref in the global");
}
}
*/
Ok(())
}

View File

@@ -64,7 +64,7 @@ impl Global {
}
/// Get a value from the global.
pub fn get<T: ValueEnumType>(&self) -> Value<T> {
pub fn get<T: ValueEnumType>(&self, store: &dyn std::any::Any) -> Value<T> {
let _global_guard = self.lock.lock().unwrap();
unsafe {
let definition = &*self.vm_global_definition.get();
@@ -77,13 +77,13 @@ impl Global {
Type::ExternRef => Value::ExternRef(definition.to_externref().into()),
// reading funcref from globals requires a Store
Type::FuncRef => {
let p = definition.to_i64() as usize as *const i128;
if (*(p as *const usize)) == 0 {
let p = definition.to_u128() as i128;
if p as usize == 0 {
Value::FuncRef(None)
} else {
// TODO:
let store = todo!("Need a store here, there's no store to get here");
let v = T::read_value_from(&store, p);
//let store = todo!("Need a store here, there's no store to get here");
let v = T::read_value_from(store, &p);
Value::FuncRef(Some(v))
}
}