Skip to content
Advertisement

Convert a Javascript function into an “funcref” for a WebAssembly.Table

I am trying to place a Javascript function inside a WebAssembly.Table, where the element type of the table is required to be funcref. The following lines can be executed in node but raise an exception when I try to put the function inside the table:

table = new WebAssembly.Table({initial: 1, element: "anyfunc"})
func = function() { return 42 }
table.set(0, func)

The exception is:

TypeError: WebAssembly.Table.set(): Argument 1 is invalid for table of type funcref

Is it possible to convert from a Javascript function to a funcref?

Advertisement

Answer

This doesn’t work because Wasm wouldn’t be able to tell what type to assume for this function. The upcoming WebAssembly.Function constructor will fill that gap:

let func_i32 = new WebAssembly.Function({parameters: [], results: ["i32"]]}, func)
table.set(0, func_i32)

However, this is not yet standardised, so not yet available in browsers (at least not without turning on some flags).

Edit: The only way currently is to import a JS function. You can abuse that to convert a JS function into a Wasm function by funnelling it through a little auxiliary module:

(module
  (func (export "f") (import "m" "f") (result i32))
)

If you convert that module to binary and instantiate it with your function as import, then you get out a proper Wasm function:

let instance = new WebAssembly.Instance(new WebAssembly.Module(binary), {m: {f: func}})
let func_i32 = instance.exports.f
table.set(0, func_i32)  // works
Advertisement