spec icon indicating copy to clipboard operation
spec copied to clipboard

[js-api] Monitoring the execution of Wasm

Open ShinWonho opened this issue 4 months ago • 6 comments

Functions defined in embedding section provide abstraction of Wasm's mechanics to embedders. However, I found a case in JS API specification that breaks this abstraction: monitoring the execution of Wasm. I'm curious whether these are inevitable or intentional.


Abstraction over the mechanics of Wasm execution is achieved by the embedding function func_invoke. As shown in Fig. 1, it takes a function address, invokes the corresponding function, and returns the result. By using this function, the embedder does not need to understand how execution of Wasm is performed.

Image

Fig. 1: Embedding function func_invoke

However, there is an algorithm that must run immediately after a WebAssembly memory.grow instruction executes, which requires monitoring the Wasm execution context. Not only that, this algorithm inspects the value at the top of the stack (line 1) and accesses the current frame (line 1.1-1.3). These steps even require knowledge of the composition of the Wasm state and direct access to its internal structures.

These requirements significantly breaks the abstraction layer established by func_invoke. Could the algorithm be reformulated in a way that preserves this abstraction?

Image

Fig.2: JS API algorithm which is performed "immediately after a WebAssembly memory.grow instruction executes"

ShinWonho avatar Aug 18 '25 04:08 ShinWonho

It would be good to reformulate this to preserve the abstraction, but I don't know how to do that short of having the core semantics of memory.grow call an embedder-configurable callback.

tlively avatar Aug 21 '25 00:08 tlively

That sounds like the clearest solution, yeah

Ms2ger avatar Aug 21 '25 09:08 Ms2ger

Making memory.grow invoke an embedder-defined callback aligns with my thinking as well. I would appreciate hearing @rossberg’s view on this.

ShinWonho avatar Aug 27 '25 02:08 ShinWonho

Here is the previous discussion: https://github.com/WebAssembly/spec/issues/646

keithw avatar Aug 27 '25 03:08 keithw

I still stand by what I said in the previous discussion that @keithw linked to: there is no obvious way to decide what operations should have callbacks, once you think beyond JavaScript it could be almost any of them. They could also need to run before or after the actual instruction. Hence, just adding a one-off callback would be way too limited and ad-hoc. And adding one for every instruction would clearly be a total mess.

So I think we'd need a non-intrusive, sufficiently "aspect-oriented" way of expressing such hooks. The embedding interface could just hand-wave that there are implicit hooks for every instruction, identified by their abstract syntax mnemonic, and receiving the instruction's operands as arguments.

rossberg avatar Sep 02 '25 09:09 rossberg

I don't have particularly strong opinions on the exact way to spec this, except that explicit is better than implicit and having the hook visible in the place where you need to implement it is better than the "comefrom" we have now

Ms2ger avatar Sep 02 '25 09:09 Ms2ger