I'm writing a wasm program that will dynamically generate wasm functions as bytecode (including the type signature, locals vector, and body instruction sequence; everything that defines a function according to the spec). I want an efficient way to execute these functions (i.e. be able to obtain a funcref
to them) from within an already-instantiated, running module.
It seems like most implementations do this sort of thing by simply creating a new module out of the generated code, hooking up the necessary imports, and then invoking the new module from JavaScript.
I need to do it without JavaScript, and ideally without creating a new module either. It seems like this should be doable in a relatively simple way:
- Just add the new function to the current module's existing vector of functions, with a new
funcidx
. Obviously, care must be taken to ensure the generated code references other functions, globals, imports etc. by their appropriate indices. - Reference the new function by it's new
funcidx
, including callingref.func
to get afuncref
to call it indirectly.
Based on my understanding of wasm, step 1 is impossible because there's no instruction to add a new function to the default funcref
table. Might this be subject to change in the future? It's a bit difficult to navigate all the wasm spec proposals so was hoping this post might get attention from someone who works on this problem to at least link to some hints on the current state of affairs.
If an actual instruction in the spec is a non-starter, it seems this may be doable alternatively via a runtime API such as WASI, which could introduce an API method to modify the currently-running module in-place. AFAICT WASI does not currently design for this nor does it have plans to. Am I wrong about that or is there another runtime interface that does plan to do this?
WebAssembly does not support adding or removing functions (or any other elements) from running instances, and I don't know of any proposals to add such as feature.
To create a new function (e.g. when writing a JIT) you currently need to create a new module. Is there a particular reason you want to avoid this route?