Skip to content

Unable to run Go code compiled for WASI #521

Open
@yasoob

Description

@yasoob

Hi @tessi !

I am fairly new to web assembly and trying to get Go code compiled for WASI to run via Elixir using Wasmex. Here is a super simple go code:

package main

//export greet
func greet() int32 {
	return 5
}

func main() {}

I can compile this using Tinygo to target WASI like this:

tinygo build -target=wasi -o tiny.wasm main.go

Now I can run this using Wasmex and call greet like this:

bytes = File.read!("./native/tiny.wasm")
{:ok, pid} = Wasmex.start_link(%{bytes: bytes, wasi: true}) 
{:ok, m} = Wasmex.module(pid)

Wasmex.call_function(pid, "greet", [])

This prints 5 as expected.

However, my next plan is to pass complex arguments to a Go program and for that I will need to write to memory. My understanding so far is that I will need to create a Wasmex.Instance using something like this:

{:ok, store} = Wasmex.Store.new_wasi(%Wasmex.Wasi.WasiOptions{})
{:ok, instance} = Wasmex.Instance.new(store, m, %{})

However, this fails with the following error:

iex(99)> {:ok, instance} = Wasmex.Instance.new(store, m, %{})
** (MatchError) no match of right hand side value: {:error, "incompatible import type for `wasi_snapshot_preview1::fd_write`"}
    (stdlib 5.2) erl_eval.erl:498: :erl_eval.expr/6
    iex:99: (file)

These are the exports and imports of my golang WASI binary:

iex(103)> Wasmex.Module.exports(m)
%{
  "_start" => {:fn, [], []},
  "asyncify_get_state" => {:fn, [], [:i32]},
  "asyncify_start_rewind" => {:fn, [:i32], []},
  "asyncify_start_unwind" => {:fn, [:i32], []},
  "asyncify_stop_rewind" => {:fn, [], []},
  "asyncify_stop_unwind" => {:fn, [], []},
  "calloc" => {:fn, [:i32, :i32], [:i32]},
  "free" => {:fn, [:i32], []},
  "greet" => {:fn, [], [:i32]},
  "malloc" => {:fn, [:i32], [:i32]},
  "memory" => {:memory, %{minimum: 2, shared: false, memory64: false}},
  "realloc" => {:fn, [:i32, :i32], [:i32]}
}
iex(104)> Wasmex.Module.imports(m)
%{
  "wasi_snapshot_preview1" => %{
    "fd_write" => {:fn, [:i32, :i32, :i32, :i32], [:i32]}
  }
}

I am not sure why it thinks the types are incompatible for fd_write. Can you please help with this? I have been trying to resolve this on my own for a few days on and off and haven't gotten anywhere. Going to do a last ditch effort to make it work with your help before giving up.

Let me know if you want me to provide any more information.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions