Open
Description
What version of Go are you using (go version
)?
$ go version go version go1.20.3 darwin/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/Users/penghaoh/.cache/go-build" GOENV="/Users/penghaoh/Library/Application Support/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOINSECURE="" GOMODCACHE="/Users/penghaoh/Workplace/my_go_workspace/pkg/mod" GONOPROXY="*" GONOSUMDB="*" GOOS="darwin" GOPATH="/Users/penghaoh/Workplace/my_go_workspace" GOPRIVATE="*" GOPROXY="direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64" GOVCS="" GOVERSION="go1.20.3" GCCGO="gccgo" GOAMD64="v1" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="/dev/null" GOWORK="" CGO_CFLAGS="-O2 -g" CGO_CPPFLAGS="" CGO_CXXFLAGS="-O2 -g" CGO_FFLAGS="-O2 -g" CGO_LDFLAGS="-O2 -g" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/h0/6tx4n9fn59z1vj88py9mncmr00vbmk/T/go-build2636679718=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
- Make a go program trying to reuse some logic in our project written in Go
main.go
var done chan bool
func init() {
done = make(chan bool)
}
func main() {
var hash js.Func
hash = js.FuncOf(func(this js.Value, args []js.Value) any {
h := crypto.SHA512.New()
h.Write([]byte(args[0].String()))
return hex.EncodeToString(h.Sum(nil))
})
js.Global().Set("wasmHash", hash)
var close js.Func
close = js.FuncOf(func(this js.Value, args []js.Value) any {
defer close.Release()
defer hash.Release()
done <- true
return nil
})
js.Global().Set("close", close)
<-done
}
- Build it with
GOOS=js GOARCH=wasm go build -o wasm.wasm main.go
and the binary size is 19.4 MB (i add some extra dependencies to simulate the real project for this prototype) - Compress the wasm file
gzip -9 -v -c wasm.wasm > wasm.wasm.gz
- Run it with
node ./main.js
main.js
const pako = require("pako"); require("./wasm_exec"); fs = require("fs"); const wasmBuffer = new Uint8Array(pako.ungzip(fs.readFileSync("wasm.wasm.gz"))); const go = new Go(); go.env = Object.assign({ TMPDIR: require("os").tmpdir() }, process.env); go.exit = process.exit; WebAssembly.instantiate(wasmBuffer, go.importObject).then((wasmModule) => { go.run(wasmModule.instance); console.log(wasmHash("asdf")); close(); process.on("exit", (code) => { // Node.js exits if no event handler is pending // commend the block avoid deadlock if (code === 0 && !go.exited) { // deadlock, make Go print error and stack traces go._pendingEvent = { id: 0 }; go._resume(); } process.exit(); }); return; });
What did you expect to see?
The hashed result for asdf
showing up instantly.
What did you see instead?
If the binary size is big, after seeing the result, it takes 5 seconds on my machine to exit. However, it is surprising to me that if I rewrite the js file in deno, it exits instantly after printing the result in my terminal.
deno.js
import * as _ from "./wasm_exec.js"; const go = new window.Go(); const f = await Deno.open("./wasm.wasm"); const buf = await Deno.readAll(f); const inst = await WebAssembly.instantiate(buf, go.importObject); go.run(inst.instance); const result = wasmHash("asdf"); console.log(result);