tinygo-org / tinygo

Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
https://tinygo.org
Other
15.47k stars 912 forks source link

Reading from a PIPE (Stdin) when invoked through Wasm3 #1104

Closed JohnMurga closed 4 years ago

JohnMurga commented 4 years ago

I have had success running basic go code compiled through TinyGo WASM through Wasm3 (WASI) ... Right down to manipulating buffers in memory, strings and passing them in and out of the code.

But when trying to read Stdin (to read piped input) I am getting errors ... I am doing the same I have done before in WASM from C and Rust ...

So I do know that it works through WASM/Wasm3. But I rather use TinyGo if possible ....

In standard non-WASM go the following works, but it does not in TinyGo/WASM :

package main

import "os"
import "io/ioutil"

func main() {
    bytes, _ := ioutil.ReadAll(os.Stdin)
    println(string(bytes))
}

I get the following error : missing imported function ('env.syscall/js.valueGet')

In fact, looking at the generated WASM it is pulling in the following env callbacks ... Which are not going to work :

syscall/js.valueGet syscall/js.valueNew syscall/js.valueSet syscall/js.valueSetIndex syscall/js.stringVal syscall/js.valueLength syscall/js.valueCall syscall/js.valueIndex syscall/js.valuePrepareString syscall/js.valueLoadString syscall/js.finalizeRef

I am assuming that these are basic env dependencies and that I am going to run into this when doing anything non-trivial. I was thinking of implementing them in the Wasm3 runtime, but at same time they don't seem to do anything could not be done in the generated Wasm code.

So I was wondering is there a way around this ?

aykevl commented 4 years ago

This is not a TinyGo issue, but rather a Go issue. The io/ioutil package imports the time package, which in turn imports the syscall/js package, which has a number of globals initialized at runtime and requires these imports for that. Therefore, for now you can't use io/ioutil (or the time package) if you want to run the binary on a pure WASI runtime.

There appears to be work to support WASI in Go, but it will probably take a while.

Also note that TinyGo has not implemented os.Stdin on most systems such as WebAssembly.

JohnMurga commented 4 years ago

Thanks for the detailed info !