This will be probably be a big project, and I have no idea where to start, but now that we've got rudimentary WASM support in master we should consider this the next target.
I'd like to eventually be able to run all the examples from my wasm-experiments.
Actually, this might not be that difficult. What needs to happen (roughly):
For the last part, we can use a static JavaScript file but preferably this file should be auto-generated. I'm not what a good way would be, perhaps an extra output flag -js=<path> like -o=<path> where the generated JS is written, if specified?
Cool, as I mentioned in a PM, the stdlib implementation requires a JS file to be included whenever you use the WASM output, so it doesn't seem unreasonable for us to have the same requirements. The file in question is https://github.com/golang/go/blob/master/misc/wasm/wasm_exec.js
We may also require some of the glue code in https://github.com/golang/go/blob/master/misc/wasm/wasm_exec.html
I think most of wasm_exec.js can just be copied with minimal modifications.
I have started some work on this: https://github.com/aykevl/tinygo/tree/wasm-glue
Sadly it doesn't quite work yet (calling os.Stdout.Write):
panic: TypedArrayOf: not a supported slice
Uncaught (in promise) RuntimeError: unreachable
at syscall/js.typedArrayOf (wasm-function[28]:39)
at (*internal/poll.FD).Write (wasm-function[40]:917)
at (*os.File).write (wasm-function[38]:33)
at (*os.File).Write (wasm-function[37]:62)
at add (wasm-function[36]:46)
at updateResult (http://localhost:8033/src/examples/wasm/wasm.js:44:29)
at http://localhost:8033/src/examples/wasm/wasm.js:56:5
EDIT: note that it hits 'unreachable' there because the call to panic() shouldn't return but I stubbed out the call to abort() so it does actually return. That means the stack trace is just garbage after the panic call (but I'm surprised to see it actually includes function names and a stack trace).
Ah, I see what's probably going on. I'm using the C calling convention in TinyGo (because it is more efficient in most cases) but wasm_exec.js expects the Go calling convention.
I don't know what LLVM uses but we will have to match that on the JavaScript side.
Investigated a bit more. It's not just the calling convention. It's also how I stubbed out some init calls previously for microcontroller support (which of course can't call JS glue code anyway).
When I fixed that (see the wasm-glue branch) I found a different problem: because TinyGo uses the C calling convention instead of the Go calling convention, it directly calls with an i64 parameter, which is currently unsupported in WebAssembly. Chrome has a confusing error message, but Firefox is quite clear about it with TypeError: cannot pass i64 to or from JS. The reason is that i64 does not exist in JavaScript, everything is a float64.
I'll have to think a bit about a proper fix, as I see multiple options.
Basic support for syscall/js has landed. It is not yet complete, that will require some hacking on wasm_exec.js. Feel free to reopen this bug if you think it is not finished, with an example of what doesn't work yet.
Most helpful comment
Basic support for syscall/js has landed. It is not yet complete, that will require some hacking on wasm_exec.js. Feel free to reopen this bug if you think it is not finished, with an example of what doesn't work yet.