Can't run Go template
Steps to reproduce:
- Create new Go template with
w4 new foobar --go - Build it:
make - Run it:
w4 run build/cart.wasm - See in the console:
LinkError: WebAssembly.instantiate(): Import #0 module="env" function="tinygo_getCurrentStackPointer" error: function import requires a callable
Environment:
- Fedora 37
- wasm4 version 2.5.3
- tinygo version 0.26.0 linux/amd64 (using go version go1.19.3 and LLVM version 15.0.0)
Downgrading tinygo to 0.25.0 fixed the issue.
Adding
//go:linkname getCurrentStackPointer tinygo_getCurrentStackPointer
func getCurrentStackPointer() uintptr {
return 0
}
to the end of w4/wasm4.go fixed the issue for tinygo 0.26.0
Hi, thanks for reporting this!
I'm actually not able to repro, but I wonder if something changed with the tinygo's default wasm.json in 0.26, and we need to mirror any changes into the wasm4 project's target.json. Eg: default-stack-size looks suspicious.
BigAngryBob ran into other issues with the tinygo. Tinygo was invoking wasm-opt on its own, but not providing --enable-bulk-memory.
[wasm-validator error in function 0] unexpected false: Bulk memory operations require bulk memory [--enable-bulk-memory], on
His versions:
% w4 --version
2.5.4
% tinygo version
tinygo version 0.27.0 darwin/amd64 (using go version go1.20.4 and LLVM version 15.0.0)
% wasm-opt --version
wasm-opt version 113
I ran into the issue mentioned above (unexpected false: Bulk memory operations require bulk memory) as well with the default Go template. I'm not sure how to get past to it work with Go. I'm on the same w4 version, 2.5.4.
$ tinygo version
tinygo version 0.28.1 linux/amd64 (using go version go1.20.5 and LLVM version 15.0.0)
$ wasm-opt --version
wasm-opt version 105
Do you know if it's failing on tinygo compilation, or the wasm-opt post-build pass?
It failed on tinygo. I tried removing the wasm-opt logic from the Makefile and saw the same error.
As @DenialAdams mentioned, tinygo is internally calling wasm-opt with its own flags. This error happens during the tinygo compilation phase, before the wasm-opt post-build pass.
I was able to compile successfully by replacing the template's target.json with the one from the tinygo project: https://github.com/tinygo-org/tinygo/blob/release/targets/wasm.json (this one contains the -mbulk-memory flag, which bypasses the current compiling error)
However, I am now facing the issue: Uncaught (in promise) TypeError: import object field 'wasi_snapshot_preview1' is not an Object when I open the game in the browser through w4 run build/cart.wasm. Not sure how to fix that one.
I'm using go 1.21.1, tinygo 0.30.0, and w4 2.5.4.
tl;dr
- Replace contents of
target.jsonin template with https://github.com/tinygo-org/tinygo/blob/release/targets/wasm.json - Remove
wasm-optsteps in Makefile, because tinygo already callswasm-optinternally - Since tinygo runs
wasm-optinternally, the user needs to havewasm-optinstalled 3.1) If tinygo was installed through a package manager, then a separate install ofbinaryenis needed to getwasm-opt3.2) If tinygo was installed by downloading it from their GitHub releases, thenwasm-optalready comes included in theirbinfolder. tinygo will automatically find thiswasm-optin their own code: https://github.com/tinygo-org/tinygo/blob/731532cd2b6353b60b443343b51296ec0fafae09/goenv/goenv.go#L143-L165
Replacing all of target.json was probably too intrusive on my part. The contentious flag in the current target.json seems to be --strip-all https://github.com/aduros/wasm4/blob/aca37f98e509f96faa789efb9df8925d28f65bbf/cli/assets/templates/go/target.json#L21
Looks like this flag isn't playing nicely with the latest tinygo. If you remove that flag you can get past the unexpected false: Bulk memory operation (bulk memory is disabled) build errors. However, you still have the Uncaught (in promise) TypeError: import object field 'wasi_snapshot_preview1' is not an Object error in the console once you run the cart.
Unfortunately I don't currently know anything about tinygo or wasm to figure out if any of these changes are lining up to produce a correct wasm4 cart.
I haven't had time to look at this, but more experienced Go developers may have some insight. Ping @peterhellberg @christopher-kleine
There's a small game I'd like to implement using Go anyway. I'll look into this in the next days, I guess. I'm currently busy with work.
@christopher-kleine Cool, I have primarily used Zig :zap: lately for fantasy console related stuff, so have no up to date experience with TinyGo together with WASM-4
So far I was able to confirm the problem. I tried the default target.json supplied by WASM4 and also the target.json directly from TinyGo. Both failed.
Digging a little, it's stated, that we need the wasm_exec.js from TinyGo instead of the one from Go itself. I tried this, but was unsuccessful as of now. I might have to ask on their Repo about this.
This is still an issue, was trying the same thing and same error on the console. Any leads?
Sorry, I didn't find anything new. Currently I don't have the time to investigate further, since other things popped up.
My best advice so far would be: Either try to downgrade to an earlier version of Tinygo or - if an older version of WASM4 is fine - try the Docker Images.
Reminds me: Should I take them down, @aduros ? I can't maintain the docker images for quite some time, I'm afraid. And I don't want people come running to you because of bugs in those older versions.
ok so for now here is how to use wasm-4 with go
-
installing proper version of tinygo (0.21.0) https://github.com/tinygo-org/tinygo/releases/tag/v0.21.0 You will need to ensure that the path to the tinygo executable file is in your PATH variable.
-
installing proper go version (1.17) I use gvm. Atm I have both go1.17 and go1.22.4 installed with gvm.
-
After creating the
w4 new --go project. You should write in terminalgvm use go1.17and for double check you writetinygo versionwhich must say:tinygo version 0.21.0 linux/amd64 (using go version go1.17 and LLVM version 11.0.0)
After all of these, everything should work
It seems that the problem with the latest versions of Go and TinyGo is still in the incorrect target.json. With these settings, Wasm-4 works for me without errors. In my case, versions Go 1.22.2 and TinyGo 0.31.2
target.json content: { "llvm-target": "wasm32-unknown-unknown", "cpu": "generic", "features": "+mutable-globals,+nontrapping-fptoint,+sign-ext,+bulk-memory", "build-tags": [ "tinygo.wasm", "wasm_unknown" ], "goos": "linux", "goarch": "arm", "linker": "wasm-ld", "rtlib": "compiler-rt", "scheduler": "none", "cflags": [ "-mno-bulk-memory", "-mnontrapping-fptoint", "-msign-ext" ], "ldflags": [ "--allow-undefined", "--no-demangle", "--import-memory", "--initial-memory=65536", "--max-memory=65536", "--stack-first", "--no-entry", "-zstack-size=14752" ] }
I can partially confirm this. The "Hello World" example works. But I also tried to compile the snake demo and my Tic-Tac-Toe source. Both compile just fine. But I can't run them.
Uncaught (in promise) LinkError: import object field 'tinygo_getCurrentStackPointer' is not a Function
// Edit: I'll try to go through the snake tutorial to figure out where it breaks.