コンテンツへスキップ

TypeScriptからWebAssemblyを生成するAssemblyScriptを試す

by : 2019/04/19

WebAssemblyはプログラミング言語ではなく、様々なプログラミング言語から生成されるWebブラウザ上で実行できるバイナリフォーマットになります。基本はRustやC、C++であり、他にもGo、Java、Kotlin、Swiftなど様々なプログラミング言語が対応しています。

しかし複数のプログラミング言語を混ぜて開発するのは要員確保も大変です。そこで注目したいのがTypeScriptからWebAssemblyファイルを生成するAssemblyScriptです。今回はその特徴を紹介します。

JavaScriptの関数を呼び出せる

AssemblyScriptではdeclareを使って関数を定義することで、JavaScript側の関数を呼び出せます。例えば以下はsayHello関数を呼び出しています。

declare function sayHello(): void;
sayHello();

view raw
index.js
hosted with ❤ by GitHub

そしてJavaScript側では次のように記述します。mainの中でsayHelloという関数を定義することで、AssemblyScriptからJavaScriptの関数呼び出しを可能にしています。

WebAssembly.instantiateStreaming(fetch("../out/main.wasm"), {
main: {
sayHello() {
console.log("Hello from WebAssembly!");
}
},
env: {
abort(msg, file, line, column) {
console.error("abort called at main.ts:" + line + ":" + column);
}
},
})

view raw
index.js
hosted with ❤ by GitHub

JavaScriptからAssemblyScriptの関数を呼び出す

逆にJavaScriptからAssemblyScriptの関数を呼び出す場合はexportを使って関数を公開します。型を指定しなければなりません。

export function add(x: i32, y: i32): i32 {
return x + y;
}
export function minus(x: i32, y: i32): i32 {
return x y;
}

view raw
index.js
hosted with ❤ by GitHub

これで、WebAssemblyファイル読み込み後の result.instance.exports の中に関数が入ります。

exports.minus(23, 20);
// -> 3

view raw
index.js
hosted with ❤ by GitHub

文字列を返す場合

文字列の場合は多少注意が必要です。まず関数の定義の時点で文字列の長さも返すように定義します。

declare function sayHello(msg: string, len: usize): void;
export function say(): void {
const str: string = "hifive";
sayHello(str, str.length);
}

view raw
index.js
hosted with ❤ by GitHub

次に受け取った側ではメモリ中の値を読み取り、デコードしなければなりません。

sayHello(index) {
const length = mem.getUint32(index,true);
const array = new Uint16Array(mem.buffer,index + 4,length);
const str = new TextDecoder('utf-16').decode(array);
console.log(`Hello ${str}, from WebAssembly!`);
}

view raw
index.js
hosted with ❤ by GitHub

memはWebAssemblyファイルを読み込んだ後 result.instance.exports.memory.buffer で取得できます。

mem = new DataView(result.instance.exports.memory.buffer);

view raw
index.js
hosted with ❤ by GitHub

まとめ

WebAssemblyがTypeScriptで書けるようになれば、 TypeScriptだけでフロントエンドの開発が完結できます。もちろんサブセットなので全ての機能が使える訳ではありません。しかし高速な処理が必要になった際に、AssemblyScriptであれば書き慣れた構文でWebAssembly化できるメリットが大きいでしょう。

AssemblyScript/assemblyscript: A TypeScript to WebAssembly compiler 🚀

From → hifive

コメントは受け付けていません。

%d人のブロガーが「いいね」をつけました。