Tinygo: Support full stdlib syscall/js interface in WebAssembly

Created on 21 Oct 2018  路  8Comments  路  Source: tinygo-org/tinygo

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.

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.

All 8 comments

Actually, this might not be that difficult. What needs to happen (roughly):

  • Try compiling any program using syscall/js. It will result in a linker error.
  • Add the symbols listed in the error (should be syscall/js.*) to targets/wasm.syms - this makes the linker happy but when loaded in a browser the browser will complain about missing defines.
  • Add the required glue code to JavaScript to satisfy the JS<->Wasm bridge.

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sh0rez picture sh0rez  路  4Comments

Zambiorix picture Zambiorix  路  3Comments

DazWilkin picture DazWilkin  路  6Comments

mcrosson picture mcrosson  路  3Comments

tranxuanthang picture tranxuanthang  路  8Comments