<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Runtime on κeenのHappy Hacκing Blog</title>
    <link>https://KeenS.github.io/categories/runtime/</link>
    <description>Recent content in Runtime on κeenのHappy Hacκing Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>ja-jp</language>
    <lastBuildDate>Thu, 16 Feb 2017 15:46:21 +0900</lastBuildDate>
    
	<atom:link href="https://KeenS.github.io/categories/runtime/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>WebAssemblyとコンパイラとランタイム</title>
      <link>https://KeenS.github.io/slide/webassemblytokonpairatorantaimu/</link>
      <pubDate>Thu, 16 Feb 2017 15:46:21 +0900</pubDate>
      
      <guid>https://KeenS.github.io/slide/webassemblytokonpairatorantaimu/</guid>
      <description>&lt;textarea data-markdown
    data-separator=&#34;\n===\n&#34;
    data-vertical=&#34;\n---\n&#34;
    data-notes=&#34;^Note:&#34;&gt;
# WebAssemblyとコンパイラとランタイム
----------------------
[emscripten night !! #3 - connpass](https://emsn.connpass.com/event/48100/)

&lt;!-- .slide: class=&#34;center&#34; --&gt;
===
# About Me
---------
![κeenのアイコン](/images/kappa.png) &lt;!-- .element: style=&#34;position:absolute;right:0;z-index:-1&#34; width=&#34;20%&#34; --&gt;

 * κeen
 * [@blackenedgold](https://twitter.com/blackenedgold)
 * Github: [KeenS](https://github.com/KeenS)
 * [Idein Inc.](https://idein.jp/)のエンジニア
 * Lisp, ML, Rust, Shell Scriptあたりを書きます

===
# 何の話
---------

* WebAssemblyをバックエンドに使う言語を作りたい
* [KeenS/webml: An ML like toy language compiler](https://github.com/KeenS/webml)
* 既に発表したものの補足記事的な
  + [コンパイラの人からみたWebAssembly | κeenのHappy Hacκing Blog](https://keens.github.io/slide/konpairanoninkaramitaWebAssembly/)
  + ある程度再度説明します

===
# アジェンダ
------------

* なぜWebAssembly
* コンパイラ
* コード生成
* ランタイム

===

# なぜWebAssembly

&lt;!-- .slide: class=&#34;center&#34; --&gt;
===
# なぜWebAssembly
----------------

* なんかバイナリでテンション上がる
* ポータブルでコンパクトで速い
* 機能的にJSを越えるかもしれない…？
* コンパイラがブラウザで動くと言語導入のハードル下がる
  + 気軽に試せる
  + コンパイラだけでなく吐いたコードもブラウザで動かしたい

===
# WASM over LLVM
----------------

* 既存のJS環境と協調する
  + JSとの相互呼び出しとか
* **non-determinismが少ない**
* 細かいアラインメント考える必要がない
* **API安定しそう**

===

# WASM over asm.js
--------------------

* ブラウザ以外への組込みもサポート
  + Node.jsとか
  + **JITエンジンに使えそう**
* プラットフォーム
* 実行までのレイテンシが短かい
* asm.jsより速度を出しやすい設計
* テキストフォーマットで生成コードの文法エラーが怖い
* 将来機能が増えるかも

===
# WebAssemblyの現状
-------------------

* Minimum Viable Product(MVP)
* 機能を削ってとりあえず動くものを作ってる
* 今はC/C++からLLVMを通して吐けるのが目標
  + C/C++には不要でも自分の言語に欲しい機能は……
* 今後SIMDとかスレッドとかDOM APIとか増えていく

===

# コンパイラ

&lt;!-- .slide: class=&#34;center&#34; --&gt;

===
# WASM概要
----------

* WASMには以下がある
  + 関数
    - 関数内ローカル変数
  + リニアメモリ
  + グローバル変数
  + テーブル
  + importテーブル
  + exportテーブル

===
# WASM実行モデル
--------------

* i32,i64,f32,f64のみ
* **スタックマシン**
  + 命令のオペランドや関数の引数はスタック経由で渡す
  + 1 passのコード生成が楽そう
* 無限のローカル変数が使える
  + 型がある
* 関数の引数はローカル変数経由で渡される
* コントロールフローはgotoじゃなくてstructured
  + 静的検証がしやすいらしい
  + 安全だけどコンパイラ的には…

===

# コントロールフロー
-------------------

* `loop` + `br` (名前付き)
* `block` + `br` (名前付き)
* `br_if` or `br_table`
* `if` + `else` + `end`
* `return`
* 等

===

# コントロールフロー
-------------------

* gotoがない
  + `br` はブランチじゃなくてブレイク
* gotoからstructuredに[変換出来る](https://github.com/kripken/emscripten/blob/master/docs/paper.pdf)
    + loop, block, br, br_ifを使う
* 高級言語から変換するなら `if` を使う
  + ifが2系統あることになる

===
# サンプル
---------

``` javascript
function geometricMean(start, end) {
  start = start|0; // start has type int
  end = end|0;     // end has type int
  return +exp(+logSum(start, end) / +((end - start)|0));
}
...
```

===
# サンプル
---------

```wasm
(module
  (type (;0;) (func (param i64 i64) (result f64)))
  (type (;1;) (func (param i64 i64) (result f64)))
  (type (;2;) (func (param f64) (result f64)))
  (func (;0;) (type 0) (param i64 i64) (result f64)
    (get_local 0)
    (get_local 1)
    (call 1)
    (get_local 1)
    (get_local 0)
    (i64.sub)
    (f64.convert_s/i64)
    (f64.div)
    (call 2))
  ...)
```

===
# サンプル
---------

```wasm
(module
  (type (;0;) (func (param i64 i64) (result f64)))
  (type (;1;) (func (param i64 i64) (result f64)))
  (type (;2;) (func (param f64) (result f64)))
  (func (;0;) (type 0) (param i64 i64) (result f64)
    (call 2
      (f64.div
       (call 1 (get_local 0) (get_local 1))
       (f64.convert_s/i64
        (i64.sub
         (get_local 1)
         (get_local 0))))))
  ...)
```

===

# WebMLコンパイラ
------------

* パーサ、AST、HIR、MIR、LIR
* LIRがRTLなのでそれをWASMに変換したい
* gotoからstructured control flow…

===

```
[コード]
   | パーサ
 [AST] 型推論とか
   | AST2HIR
 [HIR] 早期最適化、K正規化、A正規化など
   | HIR2MIR
 [MIR] 諸々の最適化
   | MIL2LIR
 [LIR] シリアライズ、レジスタ割り当てなど
   | コード生成
 [WASM]
```

===

# 変数
------

* LIRはレジスタで計算する
* LIRはCFG由来の大量の変数を使う
  + レジスタ割り当ては一旦置いとく
* WASMはスタックで計算する
* どうコード生成すると最適か？

===

```
fun main: () -&gt; i64 = {
    entry@0:
        r0: i64 &lt;- 1
        r1: i32 &lt;- 0
        r2: i64 &lt;- 1
        r3: i64 &lt;- 2
        r4: i64 &lt;- 3
        r5: i64 &lt;- r3 * r4
        r6: i64 &lt;- 4
        r7: i64 &lt;- r5 + r6
        r8: i64 &lt;- r2 + r7
        r9: i64 &lt;- 1
        r10: i64 &lt;- 2
        r11: i64 &lt;- r9 + r10
        r12: i64 &lt;- 3
        r13: i64 &lt;- r11 * r12
        r14: i64 &lt;- 4
        r15: i64 &lt;- r13 + r14
        r16: i32 &lt;- 1
        jump_if_zero r16 then@1
        jump else@2
    then@1:
        r17: i64 &lt;- r8
        jump join@3
    else@2:
        r17: i64 &lt;- r15
        jump join@3
    join@3:
        r18: i64 &lt;- 1
        r19: i64 &lt;- r18 + r15
        r20: i64 &lt;- 1
        r21: i64 &lt;- call d@9(r20, )
        r22: i64 &lt;- 2
        r23: i64 &lt;- call #g37(r22, )
        r24: i64 &lt;- 1
        r25: i64 &lt;- heapalloc(16)
        [r25+0] &lt;- &lt;anonfun&gt;@11
        [r25+8] &lt;- r24
        r26: i64 &lt;- 0
        ret r26
}
```

===

# 変数割り当て
--------------

* SSAの1変数 = WASMの1ローカル変数
* スタックの効率利用を完全に無視
* 計算はLV→スタック→LVに書き戻し
* どうせスタックもLVもレジスタ扱いにしてレジスタ割り当てされるでしょ
* （測ってないけど）多分速度は変わらない

===

# CFG
-----

* コンパイラが一旦gotoを使うコントロールフローグラフを作る
* WASMにはgotoがない
* どうやったら生成出来るか？
* そもそも生成出来るの？

===

# blockと前方ジャンプ
------------

* `block` + `break` で前方ジャンプ
* 閉じ括弧の位置にジャンプ
* `block` の位置は自由

===

&lt;pre&gt;
&lt;code&gt;
(&lt;span class=&#39;hljs-keyword&#39;&gt;block&lt;/span&gt;
  ...
  (&lt;span class=&#39;hljs-keyword&#39;&gt;br&lt;/span&gt; 0)--+
  ...     |
  )&lt;------+
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;===&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
