I have quite a complex use-case. I'm using wasmtime for a video game that's like screeps. Each player uploads a wasm script (written in Rust), and I create an Instance for each of their units each tick.
I want to somehow provide a way to persist memory between instances. I have a basic implementation working like this:
This involves 4 different copies and/or serializations. That's pretty sucky, and adds a lot of overhead. I've considered various schemes to avoid 2-3 by using mem::transmute() and building an allocator that allocates entirely within the byte slice. That would avoid needing to use bincode to convert to and from bytes within the instance. However, I still would need to copy the data in and out of the instance each time.
I think a better way would be to limit the memory to 1mb for the instance, and reuse it between instances. The questions are then:
Ideally, if the wasm script panics, then all changes to the persistent memory would be rolled back. So I kinda want copies 1+4, but I want to avoid the overhead of bincode is the bigger issue.
Currently linear memories cannot be reused across stores, and you probably want to retain one-instance-per-store since otherwise instances never get deallocated (they're owned by the store). Linear memories can technically be shared between instances within the same store but it would mean you have to persist the store for a long time which may not be what you want.
Otherwise what you can do is if the modules import the memory you can manage the memory yourself. For example you could create the linear memory on the host and then when the wasm module is done with it you do what's necessary to serialize that to disk and such. Using the MemoryCreator
trait you may be able to create custom schemes for memory allocation perhaps as well?
How exactly do I provide memory to the guest? Right now I'm calling a function to allocate memory from within the guest, and give the pointer back to the host to write to. Is there a way to just provide memory directly to the guest?
Is there a way to just provide memory directly to the guest?
You can use the grow
method on the Memory
and then write to the newly grown pages. It will depend on whichever memory allocator the wasm module uses if it will handle this fine, or corrupts it internal state. In any case you probably won't be able to deallocate the memory again without corrupting the allocator state. You also can't map existing pages with data into the wasm linear memory. You must copy it one way or another.
Last updated: Dec 23 2024 at 12:05 UTC