Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List and access non-exported globals of an instance #10156

Open
laurmaedje opened this issue Jan 30, 2025 · 2 comments
Open

List and access non-exported globals of an instance #10156

laurmaedje opened this issue Jan 30, 2025 · 2 comments

Comments

@laurmaedje
Copy link

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 #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 than wasmtime, 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.

Footnotes

  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
Copy link
Contributor

bjorn3 commented Jan 30, 2025

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
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants