laurmaedje opened issue #10156:
Feature
I'd like to access (list/get/set) the value of globals that were not explicitly exported by the module.
Benefit
I'm trying to take a snapshot of a store's state, so that I can spin up a second instance that is behaviourally equivalent to the first one. Crucially, I don't want to snapshot in the middle of a function call, just at rest when the call stack should be empty.
I went through the WebAssembly instruction reference and as far as can tell, when I instantiate a new module, the only things I would need to restore would be the main memory size & data and the globals.[^1] I'm already snapshotting the memory (which is required to be exported in my case), but I can't snapshot the globals as far as I can tell.
As far as I'm aware, LLVM-based compilers will typically only have one internal global with a shadow stack pointer. Since I'm only snapshotting when the call stack is empty, I expect not snapshotting globals for now will not immediately break in practice, but it does not seem quite correct and of course not every WebAssembly module comes from LLVM. So it'd be nice if that use case was covered somehow.
Alternatives
An alternative that would be even better for my purposes is a direct snapshotting API as discussed in https://github.com/bytecodealliance/wasmtime/issues/3017. But I expect such an API to be _much_ harder to implement and the requirement might be that it also works with a non-empty call stack. The feature proposed here would be a minimal addition to implement snapshotting of an instance with an empty call stack manually.
Another option is that there already is a way to do this and I just wasn't able to find it.
Notes
Background info: My motivation for this is adding support for automic behind-the-scenes multi-threading for Typst's plugin system. Typst uses
wasmi
rather thanwasmtime
, but I'm proposing the feature here first, because as far as I can tell, wasmi's API mostly mirrors wasmtime's, so proposing it here first seemed more fruitful to me.[^1]: I'm not taking any of the WebAssembly extensions into account here, which I don't intend to support at this time. I'm not sure whether they would add complication, but e.g. multi-memories might.
bjorn3 commented on issue #10156:
Wizer handles this by intrumenting (modifying) the wasm module to allow access to non-exported globals and memories: https://github.com/bytecodealliance/wizer/blob/main/src/instrument.rs
laurmaedje commented on issue #10156:
Thanks for the info! I saw the
__wizer_global_{}
in snapshot.rs, but didn't make the connection to instrument.rs, so was unsure how that worked.I expect doing it this way would add quite a bit of dependency burden on top of
wasmi
(and also some performance overhead for doing this at runtime). However, as a last resort, it would indeed work.
alexcrichton commented on issue #10156:
Wasmtime doesn't support accessing unexported globals/functions/tables/etc, so purely using the
wasmtime
crate API you'll be unable to solve this goal. As @bjorn3 mentioned though what you're doing is very similar to what Wizer does and Wizer achieve this goal by modifying the wasm binary ahead-of-time.If you're interested in doing that it may not be too too hard to implement this by using a combination of
wasmparser
andwasm-encoder
, likely using thewasm_encoder::reencode
module.
laurmaedje commented on issue #10156:
Thanks for the link! Is it an explicit decision to not support this or is it just currently not supported? If it's the former, I of course respect that and would then probably embark on the wizer-like route. Though I'd still be curious if there's any particular reason why it would be a bad idea to have such an API.
alexcrichton commented on issue #10156:
The former yeah, it's an intentional design decision to only give access to explicit exports. That enables opportunities for us to optimize more, for example.
laurmaedje closed issue #10156:
Feature
I'd like to access (list/get/set) the value of globals that were not explicitly exported by the module.
Benefit
I'm trying to take a snapshot of a store's state, so that I can spin up a second instance that is behaviourally equivalent to the first one. Crucially, I don't want to snapshot in the middle of a function call, just at rest when the call stack should be empty.
I went through the WebAssembly instruction reference and as far as can tell, when I instantiate a new module, the only things I would need to restore would be the main memory size & data and the globals.[^1] I'm already snapshotting the memory (which is required to be exported in my case), but I can't snapshot the globals as far as I can tell.
As far as I'm aware, LLVM-based compilers will typically only have one internal global with a shadow stack pointer. Since I'm only snapshotting when the call stack is empty, I expect not snapshotting globals for now will not immediately break in practice, but it does not seem quite correct and of course not every WebAssembly module comes from LLVM. So it'd be nice if that use case was covered somehow.
Alternatives
An alternative that would be even better for my purposes is a direct snapshotting API as discussed in https://github.com/bytecodealliance/wasmtime/issues/3017. But I expect such an API to be _much_ harder to implement and the requirement might be that it also works with a non-empty call stack. The feature proposed here would be a minimal addition to implement snapshotting of an instance with an empty call stack manually.
Another option is that there already is a way to do this and I just wasn't able to find it.
Notes
Background info: My motivation for this is adding support for automic behind-the-scenes multi-threading for Typst's plugin system. Typst uses
wasmi
rather thanwasmtime
, but I'm proposing the feature here first, because as far as I can tell, wasmi's API mostly mirrors wasmtime's, so proposing it here first seemed more fruitful to me.[^1]: I'm not taking any of the WebAssembly extensions into account here, which I don't intend to support at this time. I'm not sure whether they would add complication, but e.g. multi-memories might.
laurmaedje commented on issue #10156:
Okay thanks for all the info!
Last updated: Feb 28 2025 at 03:10 UTC