Shogo's Blog

Aug 19, 2018 - 1 minute read - go golang wasm

GoAst ViewerをWebAssemblyへビルドしてみた

もうすぐリリースのGo1.11ではWebAssemblyのサポートが予定されています。 (2018/08/19現在の最新版はGo1.11rc1)

正式リリース前に少し遊んでみようということで、@yuroyoroさんのGoAst ViewerをWebAssemblyへビルドしてみました。

JavaScriptの連携方法

コードをASTに変換し、JSONとしてエンコードする部分(ast.go)に関しては、一切変更しなくても動きました。素晴らしい。

ただし、さすがにブラウザ上でHTTPサーバーは動かない(そういえば試してないけど、動かないよね??)ので、JavaScriptとの連携部分を実装してあげる必要があります。 syscall/jsパッケージはまだ実験段階というステータスで機能が限られているので、 連携には少し工夫が必要です。

JavaScriptからGoの関数を呼ぶ

JavaScriptからGoの関数を呼ぶには window にコールバック関数として必要な関数を登録します。

// GoASTParse 関数を定義(Go言語)
js.Global().Set("GoASTParse", js.NewCallback(func(args []js.Value) {
    source := args[0].String()
    // ...ASTへの変換処理...
}))

戻り値をGoからJavaScriptへ返す

js.NewCallback なのですが、もともとは addEventListener にわたすコールバック関数なので、 関数の戻り値を受けわたす方法がありません。 回避方法はいろいろあるでしょうが、今回はコールバック関数の引数にコールバック関数指定してもらうことにしました。

// GoASTParse 関数を定義(Go言語)
js.Global().Set("GoASTParse", js.NewCallback(func(args []js.Value) {
    source := args[0].String()
    // ...ASTへの変換処理...
    args[1].Invoke(string(body))
}))
// GoASTParseを呼び出す(JavaScript)
GoASTParse("package main; func main() {}", function(body) {
    // ASTの表示処理
})

まとめ

Goのバイナリ全般に言えることですが、WASMになってもやっぱりサイズが大きい(3.5M)。 今後のパフォーマンス向上に期待です。

GoよりAngulerJSの方が難しかったʕ  ゚皿゚ ʔ

参考