雑多なブログ

音楽や語学、プログラム関連の話題について書いています

goでwasm

goのインストール

brew install golang

go version go1.16.6 darwin/amd64 がインストールされた。
このバージョンではwasmのモジュールがすでに組み込まれているので、 特別な対応は不要。

wasm のテストプログラムコンパイル

hello worldするだけのコードを作成する。
特別な記述はせず、ふつーのgoのコードを書けば良いみたい。

hello.go

package main

import "fmt"

func main() {
    fmt.Println("Hello, Wasm!")
}

コンパイル
webassemblyのコンパイル用に環境変数をする部分が、通常のコンパイルと違うところ。

GOOS=js GOARCH=wasm go build -o hello.wasm hello.go

ブラウザwasmを実行する。

まずは、wasmを実行するために必要なスクリプトとhtmlをドキュメントルートにコピーする。

$ cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .

index.html

<html>
<head>
    <meta charset="utf-8"/>
    <script src="wasm_exec.js"></script>
    <script>
        const go = new Go();
        WebAssembly.instantiateStreaming(fetch("hello.wasm"), go.importObject).then((result) => {
            go.run(result.instance);
        });
    </script>
</head>
<body></body>
</html>

次に、goで簡易Webサーバーを実行する。

serve.go

package main

import (
    "flag"
    //"log"
    "net/http"
)

func main() {
    addr := flag.String("a", ":555", "address:port")
    flag.Parse()
    http.ListenAndServe(*addr, http.FileServer(http.Dir(".")))
}

実行

go run serve.go

備考

ブラウザ実行時次のエラーが出る場合がある。

LinkError: WebAssembly.instantiate(): Import #5 module="go" function="runtime.walltime1" error: function import requires a callable

wasm_exec.js がgoのバージョンと食い違っている事で起きているようなので、 goのバージョンに合った wasm_exec.js を用意する必要がある。 ※本記事のやり方であれば大丈夫だとは思う。