Skip to content

[js-api] Monitoring the execution of Wasm #1957

Description

@ShinWonho

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"

Activity

  1. tlively commented on Aug 21, 2025

    @tlively
    Member

    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.

  2. Ms2ger commented on Aug 21, 2025

    @Ms2ger
    Collaborator

    That sounds like the clearest solution, yeah

  3. ShinWonho commented on Aug 27, 2025

    @ShinWonho
    ContributorAuthor

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

  4. keithw commented on Aug 27, 2025

    @keithw
    Member

    Here is the previous discussion: #646

  5. rossberg commented on Sep 2, 2025

    @rossberg
    Member

    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.

  6. Ms2ger commented on Sep 2, 2025

    @Ms2ger
    Collaborator

    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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions