wapc/wapc-go

Help for running the example

Closed this issue · 21 comments

Hi all!
I'm trying to run the example from https://github.com/wapc/wapc-go#example with a wasm module built in go using https://github.com/wapc/wapc-guest-tinygo#example

But I get

panic: Failed to instantiate the module:
    link error: Import not found, namespace: wasi_snapshot_preview1, name: fd_write

Any hint will be super appreciated

It's greate project, but it's doesn't work with the CLI build.

You have to either use tiny-go version earlier than 0.18. or you convert the wasm to wat. String replace "wasi_snapshot_preview1" to "wasi-unstable" then convert it back to wasm. This repo is quite outdated, will need to change to depend on wasm3

still maintained?

pkedy commented

I am working on upgrade to the latest Wasmer Go library to resolve this. There many breaking changes in the API but I hope to have it working soon.

Great news @pkedy!
Whenever I can give a try, ping me!

pkedy commented

An update on upgrading to the latest wasmer-go:
I have a branch for the latest library here: https://github.com/wapc/wapc-go/tree/wasmer_v1.0.3
Unfortunately, after a handful of invocations to a module, I get a panic from wasmer-go.

image

I'm still looking into it but it feels like an issue in wasmer-go originating here. If I can narrow it down, I'll submit an issue/PR to wasmer-go. If not, this might be reason to switch to Wasmtime's Go library.

pkedy commented

I may have figured it out. My hypothesis is that the waPC Instance needs to prevent the instances of *wasmer.Function/wasmer.IntoExtern from being garbage collected. I've committed the change. Tests are looking good so far.

pkedy commented

This branch with Wasmer v1.0.3 seems to be working well and I'm considering opening a PR.

@fabriziopandini @madflojo Do you think you could test it out?

@pkedy, I merged my Go testdata changes with your new branch on my fork https://github.com/madflojo/wapc-go/tree/wasmer_v1.0.3/testdata/go and tested it.

With TinyGo v0.17.0 - works well from what I can see (non-breaking).
With TinyGo v0.19.0 - Got the below Error.

$ go test -v ./...
=== RUN   TestModule
--- PASS: TestModule (0.01s)
=== RUN   TestPool
    pool_test.go:29: 
                Error Trace:    pool_test.go:29
                Error:          Received unexpected error:
                                Missing import: `wasi_snapshot_preview1`.`args_sizes_get`
                Test:           TestPool
--- FAIL: TestPool (0.04s)
FAIL
FAIL    github.com/wapc/wapc-go 0.242s
?       github.com/wapc/wapc-go/example [no test files]
FAIL

I also created a branch on my main project that uses wapc-go https://github.com/madflojo/tarmac/tree/wapc-wasmer and updated it to the new branch. With testdata/scheduler.wasm being TinyGo v0.17.0 and testdata/tarmac.wasm being TinyGo v0.19.0. The results are the same, v0.17.0 works great, v0.19.0 has the same import error.

Looks like you are close to working!

pkedy commented

@madflojo Are you compiling using target wasi instead of wasm? If so, please try wasm. I've noticed that wasm only requires fd_write where wasi requires a few more functions.

If wasm works for you, I'll create the PR and do some follow up research for the wasi target.

pkedy commented

Actually, I added args_sizes_get and args_get to support TinyGo -target wasi. My feeling is that -target wasm is sufficient for waPC but give it a test.

Let me test out the latest, FYI targeting wasm I am getting this error:

=== RUN   TestPool
    pool_test.go:29: 
                Error Trace:    pool_test.go:29
                Error:          Received unexpected error:
                                Missing import: `env`.`syscall/js.valueGet`
                Test:           TestPool

If I remember right (and I couldn't find it referenced anywhere) when I was playing with wasmer-go in the past I had a hard time getting any Go compiled code to work that wasn't for WASI.

pkedy commented

Weird. syscall/js.* are definitely imported if you are using Go and not TinyGo. Your program must be importing some package that requires that. Never seen that with TinyGo.

The only thing that code is importing outside of the wapc go client is fmt. It maybe a TinyGo thing with fmt.

On the wasi front, so the same code untouched compiled in v0.17.0 works great no issues.

$ docker run -v `pwd`:/build -w /build tinygo/tinygo:0.17.0  tinygo build -o /build/hello.wasm -target wasi /build/main.go
go: downloading github.com/wapc/wapc-guest-tinygo v0.3.0
$ cd ../../
$ go test -v ./...
=== RUN   TestModule
--- PASS: TestModule (0.01s)
=== RUN   TestPool
--- PASS: TestPool (0.04s)
PASS
ok      github.com/wapc/wapc-go 0.307s
?       github.com/wapc/wapc-go/example [no test files]

But v0.19.0 seems to be running into some sort of error (though not specific what).

$ docker run -v `pwd`:/build -w /build tinygo/tinygo:0.19.0  tinygo build -o /build/hello.wasm -target wasi /build/main.go
go: downloading github.com/wapc/wapc-guest-tinygo v0.3.0
$ cd ../../
$ go test -v ./...
=== RUN   TestModule
--- PASS: TestModule (0.02s)
=== RUN   TestPool
    pool_test.go:37: 
                Error Trace:    pool_test.go:37
                Error:          Received unexpected error:
                                call to "hello" was unsuccessful
                Test:           TestPool
--- FAIL: TestPool (0.06s)
FAIL
FAIL    github.com/wapc/wapc-go 0.285s
?       github.com/wapc/wapc-go/example [no test files]
FAIL
pkedy commented

Thanks! That's very helpful. I'll look into this more tomorrow.

You might also want to try this release of the guest library. https://github.com/wapc/wapc-guest-tinygo/releases/tag/v0.3.1

@pkedy just got around to testing the v0.3.1 version as you suggested and it took care of the error I was getting.

$ go test -v ./...
=== RUN   TestModule
--- PASS: TestModule (0.01s)
=== RUN   TestPool
--- PASS: TestPool (0.04s)
PASS
ok      github.com/wapc/wapc-go 0.232s
?       github.com/wapc/wapc-go/example [no test files]

I also tested with my other project but did get some errors there. I'll keep testing and let you know.

pkedy commented

Awesome. And I confirmed what you said that importing fmt targeting wasm instead of wasi creates all the JS imports we don't want. So perhaps -target wasi is preferred. At least until 0.20.0 when it all changes again :)

Ok, I did some testing against TinyGo 0.17.0, 0.19.0 and Rust and things are looking good to me.

tests_1              | --- PASS: TestWASMExecutionPortability (0.74s)
tests_1              |     --- PASS: TestWASMExecutionPortability/Verify_-_/testdata/tinygo19.wasm (0.19s)
tests_1              |     --- PASS: TestWASMExecutionPortability/Verify_-_/testdata/tinygo17.wasm (0.28s)
tests_1              |     --- PASS: TestWASMExecutionPortability/Verify_-_/testdata/rust.wasm (0.27s)
pkedy commented

@madflojo That's great news! I've also tested TinyGo and AssemblyScript extensively. Based on this, I created #6. Feel free to review. I'll merge and cut a new release later today or early tomorrow.

@pkedy thanks for all your work!
I have made some tests and thanks to your work I'm now unblocked for my experiments when working with the following configuration:

guest (the WebAssembly) with

github.com/wapc/wapc-guest-tinygo v0.3.1
build with tinygo v0:18 --target wasi

server with

github.com/wapc/wapc-go v0.3.0

FYI, when building with tinygo v0:19 --target wasi, instead I got an error server side.

Note: it will be great if this repository gets a go example under testdata instead of a typescript one

pkedy commented

@fabriziopandini That's great! Please reopen if you need anything else