mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-07 13:18:20 +00:00
Get references passed through globals fully working via top level API
This commit is contained in:
3
lib/api/src/externals/function.rs
vendored
3
lib/api/src/externals/function.rs
vendored
@@ -79,7 +79,7 @@ impl wasmer_types::ValueEnumType for Function {
|
|||||||
/// read the value
|
/// read the value
|
||||||
// quick hack, make it take `dyn Any`
|
// quick hack, make it take `dyn Any`
|
||||||
unsafe fn read_value_from(store: &dyn std::any::Any, p: *const i128) -> Self {
|
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();
|
let store = store.downcast_ref::<Store>().unwrap();
|
||||||
match Val::from_checked_anyfunc(func_ref, store) {
|
match Val::from_checked_anyfunc(func_ref, store) {
|
||||||
Val::FuncRef(Some(fr)) => fr,
|
Val::FuncRef(Some(fr)) => fr,
|
||||||
@@ -649,6 +649,7 @@ impl Function {
|
|||||||
FunctionDefinition::Wasm(wasm) => {
|
FunctionDefinition::Wasm(wasm) => {
|
||||||
self.call_wasm(&wasm, params, &mut results)?;
|
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"),
|
_ => unimplemented!("The function definition isn't supported for the moment"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
lib/api/src/externals/global.rs
vendored
2
lib/api/src/externals/global.rs
vendored
@@ -125,7 +125,7 @@ impl Global {
|
|||||||
/// assert_eq!(g.get(), Value::I32(1));
|
/// assert_eq!(g.get(), Value::I32(1));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn get(&self) -> Val {
|
pub fn get(&self) -> Val {
|
||||||
self.global.get()
|
self.global.get(&self.store)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a custom value [`Val`] to the runtime Global.
|
/// Sets a custom value [`Val`] to the runtime Global.
|
||||||
|
|||||||
@@ -72,7 +72,10 @@ impl ValFuncRef for Val {
|
|||||||
if func_ref.is_null() {
|
if func_ref.is_null() {
|
||||||
return Self::FuncRef(None);
|
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
|
let signature = store
|
||||||
.engine()
|
.engine()
|
||||||
.lookup_signature(item.type_index)
|
.lookup_signature(item.type_index)
|
||||||
@@ -84,6 +87,7 @@ impl ValFuncRef for Val {
|
|||||||
vm_function: wasmer_vm::VMExportFunction {
|
vm_function: wasmer_vm::VMExportFunction {
|
||||||
address: item.func_ptr,
|
address: item.func_ptr,
|
||||||
signature,
|
signature,
|
||||||
|
// TODO: review this comment (unclear if it's still correct):
|
||||||
// All functions in tables are already Static (as dynamic functions
|
// All functions in tables are already Static (as dynamic functions
|
||||||
// are converted to use the trampolines with static signatures).
|
// are converted to use the trampolines with static signatures).
|
||||||
kind: wasmer_vm::VMFunctionKind::Static,
|
kind: wasmer_vm::VMFunctionKind::Static,
|
||||||
|
|||||||
@@ -165,8 +165,8 @@ fn refs_in_globals() -> Result<()> {
|
|||||||
(global $er_global (export "er_global") (mut externref) (ref.null extern))
|
(global $er_global (export "er_global") (mut externref) (ref.null extern))
|
||||||
(global $fr_global (export "fr_global") (mut funcref) (ref.null func))
|
(global $fr_global (export "fr_global") (mut funcref) (ref.null func))
|
||||||
(global $fr_immutable_global (export "fr_immutable_global") funcref (ref.func $hello))
|
(global $fr_immutable_global (export "fr_immutable_global") funcref (ref.func $hello))
|
||||||
(func $hello (param) (result funcref)
|
(func $hello (param) (result i32)
|
||||||
(global.get $fr_immutable_global))
|
(i32.const 73))
|
||||||
)"#;
|
)"#;
|
||||||
let module = Module::new(&store, wat)?;
|
let module = Module::new(&store, wat)?;
|
||||||
let instance = Instance::new(&module, &imports! {})?;
|
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() {
|
if let Value::FuncRef(Some(f)) = fr_global.get() {
|
||||||
dbg!(f);
|
let native_func: NativeFunc<(), u32> = f.native()?;
|
||||||
|
assert_eq!(native_func.call()?, 73);
|
||||||
} else {
|
} 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ impl Global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a value from the 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();
|
let _global_guard = self.lock.lock().unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
let definition = &*self.vm_global_definition.get();
|
let definition = &*self.vm_global_definition.get();
|
||||||
@@ -77,13 +77,13 @@ impl Global {
|
|||||||
Type::ExternRef => Value::ExternRef(definition.to_externref().into()),
|
Type::ExternRef => Value::ExternRef(definition.to_externref().into()),
|
||||||
// reading funcref from globals requires a Store
|
// reading funcref from globals requires a Store
|
||||||
Type::FuncRef => {
|
Type::FuncRef => {
|
||||||
let p = definition.to_i64() as usize as *const i128;
|
let p = definition.to_u128() as i128;
|
||||||
if (*(p as *const usize)) == 0 {
|
if p as usize == 0 {
|
||||||
Value::FuncRef(None)
|
Value::FuncRef(None)
|
||||||
} else {
|
} else {
|
||||||
// TODO:
|
// TODO:
|
||||||
let store = todo!("Need a store here, there's no store to get here");
|
//let store = todo!("Need a store here, there's no store to get here");
|
||||||
let v = T::read_value_from(&store, p);
|
let v = T::read_value_from(store, &p);
|
||||||
Value::FuncRef(Some(v))
|
Value::FuncRef(Some(v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user