// use anyhow::Result; // use wasmer::*; // use wasmer_vm::WeakOrStrongInstanceRef; // const MEM_WAT: &str = " // (module // (func $host_fn (import \"env\" \"host_fn\") (param) (result)) // (func (export \"call_host_fn\") (param) (result) // (call $host_fn)) // (memory $mem 0) // (export \"memory\" (memory $mem)) // ) // "; // const GLOBAL_WAT: &str = " // (module // (func $host_fn (import \"env\" \"host_fn\") (param) (result)) // (func (export \"call_host_fn\") (param) (result) // (call $host_fn)) // (global $global i32 (i32.const 11)) // (export \"global\" (global $global)) // ) // "; // const TABLE_WAT: &str = " // (module // (func $host_fn (import \"env\" \"host_fn\") (param) (result)) // (func (export \"call_host_fn\") (param) (result) // (call $host_fn)) // (table $table 4 4 funcref) // (export \"table\" (table $table)) // ) // "; // const FUNCTION_WAT: &str = " // (module // (func $host_fn (import \"env\" \"host_fn\") (param) (result)) // (func (export \"call_host_fn\") (param) (result) // (call $host_fn)) // ) // "; // fn is_memory_instance_ref_strong(memory: &Memory) -> Option { // // This is safe because we're calling it from a test to test the internals // unsafe { // memory // .get_vm_memory() // .instance_ref // .as_ref() // .map(|v| matches!(v, WeakOrStrongInstanceRef::Strong(_))) // } // } // fn is_table_instance_ref_strong(table: &Table) -> Option { // // This is safe because we're calling it from a test to test the internals // unsafe { // table // .get_vm_table() // .instance_ref // .as_ref() // .map(|v| matches!(v, WeakOrStrongInstanceRef::Strong(_))) // } // } // fn is_global_instance_ref_strong(global: &Global) -> Option { // // This is safe because we're calling it from a test to test the internals // unsafe { // global // .get_vm_global() // .instance_ref // .as_ref() // .map(|v| matches!(v, WeakOrStrongInstanceRef::Strong(_))) // } // } // fn is_function_instance_ref_strong(f: &Function) -> Option { // // This is safe because we're calling it from a test to test the internals // unsafe { // f.get_vm_function() // .instance_ref // .as_ref() // .map(|v| matches!(v, WeakOrStrongInstanceRef::Strong(_))) // } // } // fn is_native_function_instance_ref_strong(f: &NativeFunc) -> Option // where // Args: WasmTypeList, // Rets: WasmTypeList, // { // // This is safe because we're calling it from a test to test the internals // unsafe { // f.get_vm_function() // .instance_ref // .as_ref() // .map(|v| matches!(v, WeakOrStrongInstanceRef::Strong(_))) // } // } // #[test] // fn strong_weak_behavior_works_memory() -> Result<()> { // #[derive(Clone, Debug, WasmerEnv, Default)] // struct MemEnv { // #[wasmer(export)] // memory: LazyInit, // } // let host_fn = |env: &MemEnv| { // let mem = env.memory_ref().unwrap(); // assert_eq!(is_memory_instance_ref_strong(&mem), Some(false)); // let mem_clone = mem.clone(); // assert_eq!(is_memory_instance_ref_strong(&mem_clone), Some(true)); // assert_eq!(is_memory_instance_ref_strong(&mem), Some(false)); // }; // let f: NativeFunc<(), ()> = { // let store = Store::default(); // let module = Module::new(&store, MEM_WAT)?; // let env = MemEnv::default(); // let instance = Instance::new( // &module, // &imports! { // "env" => { // "host_fn" => Function::new_native_with_env(&store, env, host_fn) // } // }, // )?; // { // let mem = instance.exports.get_memory("memory")?; // assert_eq!(is_memory_instance_ref_strong(&mem), Some(true)); // } // let f: NativeFunc<(), ()> = instance.exports.get_native_function("call_host_fn")?; // f.call()?; // f // }; // f.call()?; // Ok(()) // } // #[test] // fn strong_weak_behavior_works_global() -> Result<()> { // #[derive(Clone, Debug, WasmerEnv, Default)] // struct GlobalEnv { // #[wasmer(export)] // global: LazyInit, // } // let host_fn = |env: &GlobalEnv| { // let global = env.global_ref().unwrap(); // assert_eq!(is_global_instance_ref_strong(&global), Some(false)); // let global_clone = global.clone(); // assert_eq!(is_global_instance_ref_strong(&global_clone), Some(true)); // assert_eq!(is_global_instance_ref_strong(&global), Some(false)); // }; // let f: NativeFunc<(), ()> = { // let store = Store::default(); // let module = Module::new(&store, GLOBAL_WAT)?; // let env = GlobalEnv::default(); // let instance = Instance::new( // &module, // &imports! { // "env" => { // "host_fn" => Function::new_native_with_env(&store, env, host_fn) // } // }, // )?; // { // let global = instance.exports.get_global("global")?; // assert_eq!(is_global_instance_ref_strong(&global), Some(true)); // } // let f: NativeFunc<(), ()> = instance.exports.get_native_function("call_host_fn")?; // f.call()?; // f // }; // f.call()?; // Ok(()) // } // #[test] // fn strong_weak_behavior_works_table() -> Result<()> { // #[derive(Clone, WasmerEnv, Default)] // struct TableEnv { // #[wasmer(export)] // table: LazyInit, // } // let host_fn = |env: &TableEnv| { // let table = env.table_ref().unwrap(); // assert_eq!(is_table_instance_ref_strong(&table), Some(false)); // let table_clone = table.clone(); // assert_eq!(is_table_instance_ref_strong(&table_clone), Some(true)); // assert_eq!(is_table_instance_ref_strong(&table), Some(false)); // }; // let f: NativeFunc<(), ()> = { // let store = Store::default(); // let module = Module::new(&store, TABLE_WAT)?; // let env = TableEnv::default(); // let instance = Instance::new( // &module, // &imports! { // "env" => { // "host_fn" => Function::new_native_with_env(&store, env, host_fn) // } // }, // )?; // { // let table = instance.exports.get_table("table")?; // assert_eq!(is_table_instance_ref_strong(&table), Some(true)); // } // let f: NativeFunc<(), ()> = instance.exports.get_native_function("call_host_fn")?; // f.call()?; // f // }; // f.call()?; // Ok(()) // } // #[test] // fn strong_weak_behavior_works_function() -> Result<()> { // #[derive(Clone, WasmerEnv, Default)] // struct FunctionEnv { // #[wasmer(export)] // call_host_fn: LazyInit, // } // let host_fn = |env: &FunctionEnv| { // let function = env.call_host_fn_ref().unwrap(); // assert_eq!(is_function_instance_ref_strong(&function), Some(false)); // let function_clone = function.clone(); // assert_eq!(is_function_instance_ref_strong(&function_clone), Some(true)); // assert_eq!(is_function_instance_ref_strong(&function), Some(false)); // }; // let f: NativeFunc<(), ()> = { // let store = Store::default(); // let module = Module::new(&store, FUNCTION_WAT)?; // let env = FunctionEnv::default(); // let instance = Instance::new( // &module, // &imports! { // "env" => { // "host_fn" => Function::new_native_with_env(&store, env, host_fn) // } // }, // )?; // { // let function = instance.exports.get_function("call_host_fn")?; // assert_eq!(is_function_instance_ref_strong(&function), Some(true)); // } // let f: NativeFunc<(), ()> = instance.exports.get_native_function("call_host_fn")?; // f.call()?; // f // }; // f.call()?; // Ok(()) // } // #[test] // fn strong_weak_behavior_works_native_function() -> Result<()> { // #[derive(Clone, WasmerEnv, Default)] // struct FunctionEnv { // #[wasmer(export)] // call_host_fn: LazyInit>, // } // let host_fn = |env: &FunctionEnv| { // let function = env.call_host_fn_ref().unwrap(); // assert_eq!( // is_native_function_instance_ref_strong(&function), // Some(false) // ); // let function_clone = function.clone(); // assert_eq!( // is_native_function_instance_ref_strong(&function_clone), // Some(true) // ); // assert_eq!( // is_native_function_instance_ref_strong(&function), // Some(false) // ); // }; // let f: NativeFunc<(), ()> = { // let store = Store::default(); // let module = Module::new(&store, FUNCTION_WAT)?; // let env = FunctionEnv::default(); // let instance = Instance::new( // &module, // &imports! { // "env" => { // "host_fn" => Function::new_native_with_env(&store, env, host_fn) // } // }, // )?; // { // let function: NativeFunc<(), ()> = // instance.exports.get_native_function("call_host_fn")?; // assert_eq!( // is_native_function_instance_ref_strong(&function), // Some(true) // ); // } // let f: NativeFunc<(), ()> = instance.exports.get_native_function("call_host_fn")?; // f.call()?; // f // }; // f.call()?; // Ok(()) // }