Stream: wasmtime

Topic: Module instantiation hook


view this post on Zulip Roman Volosatovs (Sep 16 2025 at 15:25):

Hey everyone, in short, I'm working on inline Wasm module instrumentation, which is relying on a single global "fuel" counter.

The module is parsed ahead-of-time and the global is injected along with an export of it under a well-known name.
This approach works great for almost all use cases, except one: a trap in module's start function.

Using the existing Wasmtime API, the runtime can set up a call hook to observe the global value, however to do that the Global has to be either closed over or passed through the Store state.

The challenge is that the Global can only be accessed either after instantiation, by looking it up from the Instance or, if the module invokes a host function, the host could access the global via the Caller::get_module_export, even during instantiation.

The challenge is the case when the module traps in start function - it appears that existing API is insufficient to observe the value of the global in that case.

It seems that one fairly non-intrusive way of making this work could be exposing the Caller (or just Instance/similar construct) in a new module instantiation hook API. E.g. Linker::instantiate_with_hook(store, module, |caller| {}). The hook would be called before invoking start.

What do you all think?
Are there any other ways to solve this issue I have not thought about?

I'd be happy to work on this feature

view this post on Zulip Alex Crichton (Sep 16 2025 at 19:43):

Another possible implementation would be to move the start function to a well-known name which is invoked manually by the embedder as well, which if you're already mutating the module may not be too too difficult to do. Would that be reasonable to integrate?

view this post on Zulip Alex Crichton (Sep 16 2025 at 19:43):

The current API design is intended to somewhat closely follow the web which also doesn't provide access to anything if the start function traps, but it's not like we can't add an API like the one you've described I mostly just think it'd be nice to avoid if we could

view this post on Zulip Roman Volosatovs (Sep 16 2025 at 20:08):

Interesting, I haven't thought of that - I guess the runtime should just be careful about always running the custom start before accessing any exports this way.

The current workaround I went with is injecting an init import call in the start, where the init in thr host looks up the global via Caller and keeps it in the Store for the call hook to keep in-sync. Just wanted to call out this gap to see if there's interest in adding something like this.

A custom start would probably be both faster and simpler though. :thinking: Thanks for the feedback, I will double-check with the spec on the potential side-effects of doing this, but it sounds like a great idea!

view this post on Zulip Pat Hickey (Sep 16 2025 at 21:01):

start section should have never been in wasm and if there was a way to turn it off without "breaking the web" i think a supermajority of the cg would

view this post on Zulip Pat Hickey (Sep 16 2025 at 21:01):

so doing anything possible to avoid using it is the way to go imo


Last updated: Dec 06 2025 at 06:05 UTC