Classi Advent Calendar 2016 19日目です。
2日続けて翌日に投稿です。ぐへぇ。
書いてあること
下記ページなどを参考にWebAssemblyに少し触ってみました。
WebAssemblyを試してみた
sexpr-wasmがwast2wasmになっていたりと、所々変更されているようです。
現時点で、手元の環境(MacOSX 10.10.5)で試した結果を書き記しておきます。
WebAssemblyについて
WebAssembly自体については、本家ドキュメントなど。
本家ドキュメント
こちらも大変勉強になりました。
ゼロからはじめるWebAssembly入門
高速化の観点など諸々ありますが、
個人的には色々な言語でブラウザ上で動作するアプリケーションを書けるようになる世界にワクワクしております。
(移植は大変そうだけど...)
環境の用意
Google Chrome Canary
こちらからダウンロードしてインストール
ブラウザを開いたらアドレスバーからchrome://flags/#enable-webassemblyへアクセスしてWebAssemblyの機能を有効にする。
llvm
$ brew edit llvm #cmakeのオプションに"-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly"を追加
$ brew install llvm --HEAD
$ export PATH=/usr/local/opt/llvm/bin:$PATH
clang
上記のインストールで/usr/local/opt/llvm/bin内に展開されているはず
$ clang -v
clang version 4.0.0 (http://llvm.org/git/clang.git b917c327ed880036a94aeb325aee20297a33702f) (http://llvm.org/git/llvm.git d6878955b884c7965b40208836e96bfa22cac580)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
binaryen
$ cd /usr/local/src
$ git clone https://github.com/WebAssembly/binaryen.git
$ cd binaryen/
$ cmake . && make
$ export PATH=/usr/local/src/binaryen/bin:$PATH
wabt(旧称sexpr-wasm-prototype)
$ cd /usr/local/src
$ git clone --recursive https://github.com/WebAssembly/wabt
$ cd wabt/
$ make
$ export PATH=/usr/local/src/wabt/out:$PATH
触ってみる
1.Cのコードを用意
# sample.c
int fact(int n) {
if (n == 0) {
return 1;
} else {
return n * fact(n - 1);
}
}
2.CのコードをWebAssemblyのバイトコードへ変換
$ clang -emit-llvm --target=wasm32 -S sample.c # Cのコード→LLVM IR(sample.ll)
$ llc sample.ll -march=wasm32 # LLVM IR → アセンブリ(sample.s)
$ s2wasm --allocate-stack 1000 sample.s > sample.wast # アセンブリ → S式(sample.wast)
$ wast2wasm sample.wast -o sample.wasm # S式 → WebAssemblyバイトコード
3.HTMLソースの用意
JavaScriptからのバイトコードの解析のため、
以前はWasm.instantiateModule()というようなWebAssembly用のメソッドを利用していたようだけど、
手元で利用するとReferenceError: WASM is not defined
と怒られてしまいました。
こちらのページによるとWebAssembly.Instance()を代わりに使えとのこと。
#sample.html
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WebAssembly</title>
<script>
fetch('sample.wasm')
.then(response => response.arrayBuffer())
.then(buffer => WebAssembly.compile(buffer))
.then(module => {
const instance = new WebAssembly.Instance(module);
//0から10までの階乗計算結果をログ出力
for (var i = 0; i <= 10; i++) {
console.log(instance.exports.fact(i));
}
});
</script>
</head>
<body>
</body>
</html>
4.適当にHTTP鯖立てて動作確認する
OK!最後に
今すぐ何かに使えるようなモノではないかもしれませんが、
今後、やれる事や対応言語が増えていけば、どんどん楽しくなりそうです。
(流行るといいなあ)