Description
TinyGo v0.21.0
When I compile like this:
tinygo build -o tinygo.wasm -target=wasm -gc=none -scheduler=none -no-debug ./findJD.go
And then convert the WASM to WAT to look at the output (using another tool), I can see that the following is created (among other things):
(import "env" "runtime.alloc" (func $fimport$0 (param i32 i32 i32 i32) (result i32)))
(import "env" "main.main" (func $fimport$1 (param i32 i32)))
If I then instantiate this file using WebAssembly.instantiateStreaming
(and RXJS):
switchMap(() => fetch('assets/tinygo.wasm')),
switchMap(wasmBytes => WebAssembly.instantiateStreaming(wasmBytes, (new Go()).importObject)),
Then I get this error:
Uncaught LinkError: WebAssembly.instantiate(): Import #0 module="env" function="runtime.alloc" error: function import requires a callable
The root cause appears to be that wasm_exec.js
has no env["runtime.alloc"]
function. This is true of the current version (0.21.0), as well as the dev
branch. The documentation mentions that wasm_exec.js
comes from $GOROOT/misc/wasm/wasm_exec.js
. Checking this for my local installation of Go v1.17, env["runtime.alloc"]
does not appear there either.
The same conditions apply for env["main.main"]
.
Troubleshooting a bit, I tried a few compiler options, and found that main.main
seemed to be expected regardless of setting (although I didn't try every setting). runtime.alloc
begins to appear with the compiler setting gc=none
.
The issue has a workaround: stub the functions in Javascript to satisfy the Javascript-WebAssembly linker, and then otherwise ignore them.
In Javascript, this should work:
const tinygoImportObj = (new Go()).importObject;
tinygoImportObj.env['runtime.alloc'] = (a, b, c, d) => 0;
tinygoImportObj.env['main.main'] = (a, b) => void 0;
...
WebAssembly.instantiateStreaming(wasmBytes, tinygoImportObj)
Possibly related to this issue