2019/02/25にGo1.12がリリースされてました。
前回WebAssemblyビルドでメモリエラーになって困っていたので一応アップデートしてみました。
WebAssemblyはまだ実験的機能らしく関数や機能も変わっていたので試しつつメモ。
あと解決しなかったOOMエラーの考察。
Go1.12 wasm build
以前のファイルをコンパイルしてみるとエラーになりました。
1 2 |
>env GOOS=js GOARCH=wasm go build -o textimg.wasm textimg.go undefined: js.NewCallback |
Callback{}
とNewCallback()
はFunc{}
とFuncOf()
に変更になっています。
ドキュメントにコールバックないなぁと思っていたけどそういうことか。
とりあえずwasm_exec.js(GOのwasmを読み込むためのjavascript)が1.11から変更されているので変更します。
1 |
cp %GOROOT%/misc/wasm/wasm_exec.js . |
コードも新しい書き方に変えます。
1 2 3 4 5 6 7 8 9 |
func test(this js.Value,vs []js.Value) interface{}{ fmt.Println(this) fmt.Println(vs[0].String()) return "return value" } func setFuncs(){ js.Global().Set("test", js.FuncOf(test)) } |
jsでの呼び出しはそのままでthisが渡されるようになりました。
また返値を設定できるようになったため、js側で返値を得るための関数を用意しなくてよくなりました。
Out of memory考察
使いやすくなりましたがOut of Memoryエラーは変わりませんでした。
そもそもなんでそんなにメモリが使われるのか。
まずwasm_exec.jsのメモリを扱ってる部分で表示してみると10243B(1GB)のArrayBufferが作られていました。
1.12のソースだとこの辺で1024*16=16384ページ(1GB)確保しているようです。
ここを書き換えてビルドしたりも面倒そうなので、できたwasmのメモリ部分を書き換えるツールを使って半分にしてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
>go get github.com/termonio/wams >wams test.wasm memory section (offset 0x93a, 5 bytes) maxPages set to unlimited memPages 16384 (offset 0x93c, 3 bytes) >wams -pages 8192 -write test.wasm memory section (offset 0x93a, 5 bytes) maxPages set to unlimited memPages 16384 (offset 0x93c, 3 bytes) setting memPages to 8192 3 bytes written at 0x93c >wams test.wasm memory section (offset 0x93a, 5 bytes) maxPages set to unlimited memPages 8192 (offset 0x93c, 3 bytes) |
テストとして単純なwasmを作ります。
1 2 3 4 5 |
func main(){ js.Global().Call("alert","main") done := make(chan struct{}, 0) <-done } |
普通にコンパイルしたファイルと省メモリのものでテストします。
機種 | CP-L45s | P9 lite |
メモリ(RAM) | 2G | |
OS | Andorid6.0 | Android7.0 |
通常WASM実行 | Out of memory | 正常動作 |
半メモリWASM実行 | 実行されない | 正常動作 |
もしかするとメモリと関係ない問題があるのかもしれない。
P9liteも使用可能メモリ1G未満の状態で動いてるし。
どちらにせよ動かない環境があるならまだ本格使用はしにくいなぁ。