48
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TypeScriptでWebAssemblyを開発できるAssemblyScriptを試してみた

Posted at

TypeScriptでWebAssemblyを開発できるAssemblyScriptというのを見つけたので試してみる。

AssemblyScriptとは?

  • AssemblyScriptとは、TypeScriptからWebAssemblyにコンパイルする言語とそのコンパイラのこと。
  • Microsoftによって開発されている。
  • 厳密にはTypeScript風な言語であって、TypeScriptではない。
  • まだまだ開発途上(2019-11-21現在)

AssemblyScriptを試してみよう

必要な環境

Node.jsの9が必要なので、nodenvでその環境を用意しておく。

AssemblyScriptのインストール

まず、AssemblyScriptを試すプロジェクトを作る:

mkdir assemblyscript-playground
cd assemblyscript-playground
npm init

AssemblyScriptはnpmパッケージとして公開されていないので、GitHubから直接インストールする:

npm install --save-dev github:AssemblyScript/assemblyscript#v0.8.0

プロジェクトの雛形の生成

[asinit]を使って、WebAssemblyのコンパイルに必要なファイル群と設定を生成する:

npx asinit .

これを実行すると、package.jsonに次のようなNPMスクリプトが追加される:

package.json
{
  "scripts": {
    "asbuild:untouched": "asc assembly/index.ts -b build/untouched.wasm -t build/untouched.wat --sourceMap --validate --debug",
    "asbuild:optimized": "asc assembly/index.ts -b build/optimized.wasm -t build/optimized.wat --sourceMap --validate --optimize",
    "asbuild": "npm run asbuild:untouched && npm run asbuild:optimized"
  }
}

トップレベルに生成されたindex.jsは下記のようになっている:

index.js
const fs = require("fs");
const compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/build/optimized.wasm"));
const imports = {
  env: {
    abort(_msg, _file, line, column) {
       console.error("abort called at index.ts:" + line + ":" + column);
    }
  }
};
Object.defineProperty(module, "exports", {
  get: () => new WebAssembly.Instance(compiled, imports).exports
});

これは、普通のJavaScriptモジュールと同様に、WebAssemblyモジュールをrequireで読み込めるようにする仕掛けだ。便利。

assemblyディレクトリには、AssemblyScriptのソースコードが配置される。コード生成時には、次のような足し算をするサンプルが生成されている:

assembly/index.ts
// The entry file of your WebAssembly module.

export function add(a: i32, b: i32): i32 {
  return a + b;
}

ここで気になるのが、i32という型だ。普段TypeScriptを書いているなら、number型を使うところだが、AssemblyScriptではWebAssemblyの型を用いるようである。ちなみに、number型も使えるが、AssemblyScriptではf64のエイリアスになる。

ビルドしてみよう

プロジェクトの雛形を生成しただけでも、WebAssemblyをビルドしてみることができるので、下記のコマンドを実行してビルドしてみよう。

npm run asbuild

ビルドが成功すると、buildディレクトリに下記のファイルが生成される:

optimized.wasm
optimized.wasm.map
optimized.wat
untouched.wasm
untouched.wasm.map
untouched.wat

.wasmはバイナリで、.wsm.mapはそのソースマップ。

.watは人が読むためのテキスト表現になる。バイナリの読み下し文のようなもの。.watをじっくり読めば、どういうふうな命令になっているかを理解することができるが、今は読んで理解する必要はない。

WebAssemblyを動かしてみる

ビルドしたWebAssemblyをNode.jsで実行してみよう。

$ node
> const add = require('./index').add 
undefined
> add(1, 2)
3

所感

安定性はまだまだ

Nightlyをインストールしたらビルドできなかったりと、まだまだ開発途上感は否めない。今後に期待。

TSerにとっては学習しやすいツールになるかもしれない

WebAssemblyを使うシナリオのひとつに「JavaScriptのチューニングではもう限界なので、WebAssemblyで部分的にチューニングしよう」ということが想定される。WebAssemblyの開発言語というとRustをよく耳にするが、今までJavaScript/TypeScriptで作ってきた現場からすると、新しい言語の学習に対する負担は小さくないだろう。TS風の文法で書けるAssemblyScriptが実用的になってくれば、そうした学習コストを捻出しにくい場面でもWebAssemblyに挑戦しやくなり、いいかもしれない。

48
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
48
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?