diff --git a/lib/api/src/externals/function.rs b/lib/api/src/externals/function.rs index ed5132850..bc220eb38 100644 --- a/lib/api/src/externals/function.rs +++ b/lib/api/src/externals/function.rs @@ -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::().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"), } diff --git a/lib/api/src/externals/global.rs b/lib/api/src/externals/global.rs index 49f2a4c12..83d7630a1 100644 --- a/lib/api/src/externals/global.rs +++ b/lib/api/src/externals/global.rs @@ -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. diff --git a/lib/api/src/types.rs b/lib/api/src/types.rs index cfb41322e..df5943c75 100644 --- a/lib/api/src/types.rs +++ b/lib/api/src/types.rs @@ -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, diff --git a/lib/api/tests/reference_types.rs b/lib/api/tests/reference_types.rs index 0a685fec7..2c97b9a9c 100644 --- a/lib/api/tests/reference_types.rs +++ b/lib/api/tests/reference_types.rs @@ -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(()) } diff --git a/lib/vm/src/global.rs b/lib/vm/src/global.rs index 81904e13e..19de2c466 100644 --- a/lib/vm/src/global.rs +++ b/lib/vm/src/global.rs @@ -64,7 +64,7 @@ impl Global { } /// Get a value from the global. - pub fn get(&self) -> Value { + pub fn get(&self, store: &dyn std::any::Any) -> Value { 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)) } }