AssemblyScript の今後

はい、この記事は [WebAssembly Advent Calendar 2017](https://qiita.com/advent-calendar/2017/webassembly) 22日目の記事です。

# :bow: はじめに
この記事では、AssemblyScript (以降 AS) で i18n を実装したみた系の記事を書く予定でしたが間に合わなかったので、急遽、AS の次のバージョン v0.5.0 である AssemblyScript NEXT (以降 AS NEXT) で気になったことについて書きます。

AS について初めてな方は、@chikoskiさんが書いた WebAssembly Advent Calender 2017 の[この記事](https://qiita.com/chikoski/items/d98ed0a98acfa896869f)を読むと大体どんなことができるかどか分かると思うので、そちらを読んでください。

# :warning: 注意事項
言うまでもないですが、AS NEXT はこの記事執筆時点でまだ開発中で、今後変わる可能性があります。

クラス、配列、文字列といった他の言語ではあって当たり前のような言語機能でさえ、まだ実装されていません。

適当に読み物的な感じで読んでもらえればと思います。


# <img src="https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/168fa0dc7a1c6392dc8ad9c04621864d1370d499/medium.jpg" width="30px" height="32px"> GitHub のリポジトリ
ここ最近、気づいた方がいるかと思いますが、AS をホストしているリポジトリが以下のように変わりました。

- `AssemblyScript/assemblyscript` -> [`AssemblyScript/prototype`](https://github.com/AssemblyScript/prototype)
- `AssemblyScript/next` -> [`AssemblyScript/assemblyscript`](https://github.com/AssemblyScript/assemblyscript)

そうです。主が変わりました。

従来のホストしているリポジトリが `prototype` に変わりました。それに変わって、次のバージョンを開発していた `next` リポジトリが、主である `assemblyscript` に変わっています。


# <img src="https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/168fa0dc7a1c6392dc8ad9c04621864d1370d499/medium.jpg" width="30px" height="32px"> インストール方法
現時点で、開発版はまだ npm に公開されていません。なので、以下のように `git clone` してきてインストールする必要があります。

```shell
$ git clone https://github.com/AssemblyScript/assemblyscript.git assemblyscript
$ cd assemblyscript
$ npm install
```


# <img src="https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/168fa0dc7a1c6392dc8ad9c04621864d1370d499/medium.jpg" width="30px" height="32px"> WebAssembly と JavaScript との移植性

AS NEXT 以降では、WebAssembly (以降 WASM) なモノや JavaScript (以降 JS) なモノ両方に対応できる移植性のある開発ができるようになりそうです。

AS NEXT 以降では、以下のような、WASM 向けのみをターゲットとした assembly definitions と、WASM / JS 両方をターゲットした portable definitions という型定義が提供されるようです。

assembly definitions:

```json
{
  "extends": "./node_modules/assemblyscript/std/assembly.json",
  "include": [
    "./**/*.ts"
  ]
}
```

portable definitions:

```json
{
  "extends": "./node_modules/assemblyscript/std/portable.json",
  "include": [
    "./**/*.ts"
  ]
}
```

portable definitions を使えば、AS の コンパイラ `asc` と TypeScript (以降 TS) のコンパイラ `tsc` 両方で、WASM なモノや JS なモノに対応できるということになります。

これは、AS の作者 dcodeIO 氏が GitHub で[言及](https://github.com/boyanio/wasm-wheel/issues/2#issuecomment-351072535)しているように、まさに AS は TS のサブセットですね。

これをどうやって実現しているか気になる人は、portable definitions の[型定義の中身](https://github.com/AssemblyScript/assemblyscript/blob/master/std/portable.d.ts)や、[JS のコード](https://github.com/AssemblyScript/assemblyscript/blob/master/std/portable.js)を見てみるといいでしょう。

# <img src="https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/168fa0dc7a1c6392dc8ad9c04621864d1370d499/medium.jpg" width="30px" height="32px"> 移植可能なコーディング
AS NEXT 以降では上記で WASM と JS 両方、移植可能な実装が可能になると書きましたが、実装するに当たっていくつか考慮しないといけなことがあるようです。

## 明示的な変換
AS では、WASM の整数、実数、そして符号の有無などの型が仕様で定義されているものについては、型を独自に拡張して追加しています。ただ TS は JS のスーパーセットであるため、数値の場合は `number` という曖昧な型しかないため、明示的に型変換するような場合は以下のようなコーディングが必要になりそうです。

```typescript
let someFloat: f32 = 1.5
let someInt: i32 = (<i32>someFloat) | 0
```

## オーバーフロー
同様に、オーバーフローについても以下のようなコーディングが必要になりそうです。

```typescript
let someU8: u8 = 255
let someOtherU8: u8 = (someU8 + 1) & 0xff
```

## 移植性のない演算
JS での数値は IEEE754 で規定されている倍精度型(double)であるため、64 ビットな数値を扱うことはできないため、portable definitions の型定義内(`std/ portable.d.ts`)では、`i64` と `u64` は使用していません。

AS ではこれに対処するために、以下な対処法を提供しているようです。

- [I64 wrapper class]( https://github.com/AssemblyScript/assemblyscript/blob/master/src/util/i64.ts)
- [i64 polyfill]( https://github.com/AssemblyScript/assemblyscript/tree/master/examples/i64-polyfill)

また、他に AS で `load` のようなビルドインで提供する関数の引数において、全ての値の範囲をサポートしていなかったり、`String.fromCharCode` のような複数の引数を指定可能な関数において、型が異なるものを指定できなかったりするようです。


# <img src="https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/168fa0dc7a1c6392dc8ad9c04621864d1370d499/medium.jpg" width="30px" height="32px"> ビルドイン関数
GitHub の AS NEXT の この [wiki ページ](https://github.com/AssemblyScript/assemblyscript/wiki/Built-in-functions) の内容から、従来の AS (v0.3.0) で提供されているビルドインな関数が使える模様。

ただ、以下のような違いがあるようです。

- 従来の AS v0.3.0 で提供されてた `malloc`、`free`などのような、C 言語ライクなメモリ操作系の関数は提供されていない (現時点で[このモジュール](https://github.com/AssemblyScript/runtime)とリンクしていなようだ。)
- 型変換関数が `unsafe_cast` が `change_type` に変わった
- `assert` 関数が入った (デバッグが便利になりそう)
- `parseInt`、`parseFloat`のような JS で提供される標準関数のようなものビルドインで提供

# <img src="https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/168fa0dc7a1c6392dc8ad9c04621864d1370d499/medium.jpg" width="30px" height="32px"> 値の範囲
AS NEXT 以降では、整数、実数の扱い可能な値の範囲をグローバル定数で参照できるようです。

この [wiki ページ](https://github.com/AssemblyScript/assemblyscript/wiki/Types#range-limits)で表形式で確認できます。


# <img src="https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/168fa0dc7a1c6392dc8ad9c04621864d1370d499/medium.jpg" width="30px" height="32px"> 開発状況とロードマップ
現状の開発状況としては、単純なモノであれば動作するようです。import/export、そしてビルドイン関数が動作し、関数も呼び出せるようです。基本的な動作の例として、[ライフゲーム](https://github.com/AssemblyScript/assemblyscript/tree/master/examples/game-of-life)が公開されています。

今後のロードマップは、[wiki のロードマップ](https://github.com/AssemblyScript/assemblyscript/wiki/Status-and-Roadmap)と GitHub の[この Issue](https://github.com/AssemblyScript/assemblyscript/issues/1) から以下のようです。

- 実装された機能に対するテストケースの追加と問題の修正
- 正規表現のリテラルのトークン化について検討
- `TODO:`でマーキングしたものの対応
- クラスについて検討 (GC の仕様が固まるまで待つ？)
- TLSF メモリアロケーターの対応
- 標準ライブラリ`std/*.ts`(Array/String/Map/Setなど)の実装 (メモリ周りとクラス周りが終われば進みそう)

# <img src="https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/168fa0dc7a1c6392dc8ad9c04621864d1370d499/medium.jpg" width="30px" height="32px"> まとめ
これまで、いろいろ AS NEXT について調べていろいろ書いてきました。WASM / JS 両方に対応可能になりそうなのはかなり面白いです。

WASM 周り、まだまだフロンティアですが、ひょっとしたら、将来 AS ベースで Web アプリケーションを実装する時代が来るのかもしれません。

# <img src="https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/168fa0dc7a1c6392dc8ad9c04621864d1370d499/medium.jpg" width="30px" height="32px"> おわりに
今年になって、メジャーブラウザでサポートしたため、WASM 大分盛り上がってきました。WASM の現時点での利用ユースケースとしては、ゲームや暗号処理などのスピードの高速化などがメインだと思います。

WASM は今後 GC やスレッドなど対応していくと思いますが、個人的には、ブラウザ以外で動作するよう進化してからが、本領発揮だと思っています。

WASM が Ruby、Python のような環境においても動作するようになれば、ライブラリとかクラスプラットフォーム対応とか容易にできるようなりますし。

自分の WASM に対するお気持ちはこんな感じです！

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">5年も待てない。WASMが単なるWebだけでのWindowsでいう.exe/.dllで終わるんじゃなく、どの環境でも動作するものになれば、i18nとかunit testとか様々な言語で利用できるライブラリとか出てくると思うんで。 <a href="https://t.co/a5w4lykCng">https://t.co/a5w4lykCng</a></p>&mdash; 🐤kazuya kawaguchi🐤 (@kazu_pon) <a href="https://twitter.com/kazu_pon/status/935399157937815552?ref_src=twsrc%5Etfw">2017年11月28日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

WASM の今後が楽しみです。 :grinning: