MacOSXでWebAssemblyを触ってみた

[Classi Advent Calendar 2016](http://qiita.com/advent-calendar/2016/classi) 19日目です。
2日続けて翌日に投稿です。ぐへぇ。

## 書いてあること
下記ページなどを参考にWebAssemblyに少し触ってみました。
[WebAssemblyを試してみた](http://qiita.com/pnlybubbles/items/0410e978afce647cf0b6)

sexpr-wasmがwast2wasmになっていたりと、所々変更されているようです。
現時点で、手元の環境(MacOSX 10.10.5)で試した結果を書き記しておきます。

## WebAssemblyについて
WebAssembly自体については、本家ドキュメントなど。
[本家ドキュメント](http://webassembly.org/docs/high-level-goals/)

こちらも大変勉強になりました。
[ゼロからはじめるWebAssembly入門](http://qiita.com/OMOIKANESAN/items/1ffc06ef6283befc4355)

高速化の観点など諸々ありますが、
個人的には色々な言語でブラウザ上で動作するアプリケーションを書けるようになる世界にワクワクしております。
(移植は大変そうだけど...)

## 環境の用意
### Google Chrome Canary
[こちら](https://www.google.co.jp/chrome/browser/canary.html)からダウンロードしてインストール
ブラウザを開いたらアドレスバーから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```と怒られてしまいました。

[こちらのページ](https://tutorials.technology/tutorials/11-webassembly-initial-steps-tutorial.html)によると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鯖立てて動作確認する
<img width="542" alt="2f3eb76a29186923163f616f0640a0f4.png" src="https://qiita-image-store.s3.amazonaws.com/0/47918/02ea2bb9-0e16-2d8e-3af2-70f491f865ad.png">
OK!

## 最後に
今すぐ何かに使えるようなモノではないかもしれませんが、
今後、やれる事や対応言語が増えていけば、どんどん楽しくなりそうです。
(流行るといいなあ)