ZetaNumbers commented on issue #2583:
I tried to replicate this bug on 0.32.0, but it seems to be fixed! I had to update example above, but i am sure logic didn't change:
use wasmtime::*; struct MyMemory {} unsafe impl LinearMemory for MyMemory { fn byte_size(&self) -> usize { 0 } fn grow_to(&mut self, _new: usize) -> anyhow::Result<()> { anyhow::bail!("cannot grow memory") } fn as_ptr(&self) -> *mut u8 { std::ptr::null_mut() } fn maximum_byte_size(&self) -> Option<usize> { Some(0) } } impl Drop for MyMemory { fn drop(&mut self) { println!("Dropped!") } } struct MyMemoryCreator {} unsafe impl MemoryCreator for MyMemoryCreator { fn new_memory( &self, _ty: MemoryType, _minimum: usize, _maximum: Option<usize>, _reserved_size_in_bytes: Option<usize>, _guard_size_in_bytes: usize, ) -> Result<Box<dyn LinearMemory>, String> { Ok(Box::new(MyMemory {})) } } fn main() { let mut config = Config::new(); config.with_host_memory(std::sync::Arc::new(MyMemoryCreator {})); let engine = Engine::new(&config).unwrap(); let mut store = Store::new(&engine, ()); let mut linker = Linker::<()>::new(&engine); let memory_ty = MemoryType::new(1, None); let memory = Memory::new(&mut store, memory_ty).unwrap(); let captured_memory = memory.clone(); linker .func_wrap("", "", move || { let _ = captured_memory; }) .unwrap(); }
alexcrichton commented on issue #2583:
Ah yes indeed, this has been fixed!
alexcrichton closed issue #2583:
Hi, I'm using
wasmtime = 0.21
and run into a bug where theMemory
is never dropped if moved inside a closure passed toLinker::func
.Here is a minimal example:
use wasmtime::*; struct MyMemory {} unsafe impl LinearMemory for MyMemory { fn size(&self) -> u32 { 0 } fn grow(&self, _delta: u32) -> Option<u32> { None } fn as_ptr(&self) -> *mut u8 { std::ptr::null_mut() } } impl Drop for MyMemory { fn drop(&mut self) { println!("Dropped!") } } struct MyMemoryCreator {} unsafe impl MemoryCreator for MyMemoryCreator { fn new_memory( &self, _ty: MemoryType, _reserved_size_in_bytes: Option<u64>, _guard_size_in_bytes: u64, ) -> Result<Box<dyn LinearMemory>, String> { Ok(Box::new(MyMemory {})) } } fn main() { let mut config = Config::new(); config.with_host_memory(std::sync::Arc::new(MyMemoryCreator {})); let engine = Engine::new(&config); let store = Store::new(&engine); let mut linker = Linker::new(&store); let memory_ty = MemoryType::new(Limits::new(1, None)); let memory = Memory::new(&store, memory_ty); let captured_memory = memory.clone(); linker .func("", "", move || { let _ = captured_memory; }) .unwrap(); }
MyMemory
andMyMemoryCreator
are added here only for the purpose of printing out on drop, but the same behaviour is observed with the defaultMemory
.In this example "Dropped!" is never printed out, but if I comment out
let _ = captured_memory;
it is. I assume there is somewhere a cycle in reference counting.I'm also aware that the instance memory can be accessed through the first argument (
Caller
), but because of some other design decisions I prefer capturing some memories this way. Would this be considered a bug or aMemory
should never be captured like this?
Last updated: Dec 23 2024 at 12:05 UTC