2020-07-21
気持ちよく大規模webアプリを開発するために、静的型付け言語を使用するのも有効です。 APIを使用する際、間違ったパラメータを渡してハマることを防いでくれ、エディタの支援も受けやすいのが特徴です。

ブラウザで動作するクライアント側がサポートする2つの言語、JavaScriptとWebAssembly。 最近のお気に入り、静的型付け言語 Rust は WebAssembly のバイトコードを生成してくれます。 (もう一つの人気の静的型付け言語TypeScriptは、動的型付け言語JavaScriptへと変換するトランスパイラGLSLを含めると3つ?)


早速実験してみましょう。

まず準備、Rustをインストールし、WebAssembly用にコンパイルするために、targetを追加します(一度だけでok)

$ rustup target add wasm32-unknown-unknown 次のコードは、超コンパクトな、足し算するだけのRustのプログラム add.rs です。

#![no_main] #![no_std] #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} } #[no_mangle] pub fn add(a: i32, b: i32) -> i32 { a + b }

mainがなく、標準ライブラリを使わないための設定をするのは、IchigoJam用のRust「rust4ij」と同様です。 no_mangleで、最適化して行方不明になってしまわないよう設定します。

コンパイルはこのように

$ rustc --target wasm32-unknown-unknown add.rs -C opt-level=1

131byte、小さな add.wasm ファイルができました!
(wasm-strip add.wasm で116byteに!opt-level=1 を付けないとデバッグ情報で1.5MBに!)

wasmをJavaScriptから呼び出すのはこんなコードを書きます。

<script type="module"> (async () => { const bin = await (await fetch("./add.wasm")).arrayBuffer(); const wasm = await WebAssembly.instantiate(bin); const ex = wasm.instance.exports; const add = ex.add; document.body.textContent = "WebAssembly in Rust, add(1,2) = " + add(1, 2); })(); </script>

* ブラウザがトップレベルawaitに対応してくれると、async関数で囲む必要がなくなります
* SafariがWebAssembly.instantiateStreaming対応したらもっと短くかけます

wasmの読み込みはファイル上ではだめなので、live-serverなど、何かHTTPサーバーをローカルに立てて、http://127.0.0.1:8080/ などでアクセスするか、手持ちのサーバーにアップして試してみましょう!

$ live-server

コンパクトで簡単ですね!

JavaScriptやブラウザとの相互やり取りには共有メモリを使うイメージで連携します。
本格的なwebアプリ、RustとJavaScriptの連携で一度作ってみたいと思います。

DenoやNode.jsでもwasmは動きます。

$ deno run -A test-file.mjs $ node test-node.mjs

src on GitHub、いろいろ遊んでみてください!

links
- マシン語で検証、RustはC言語の代わりになりうるか? IchigoJamでライトに楽しむ組み込み開発 panic編と情報処理
- IchigoJamでかんたん組み込みRust開発 - rust4ij x IchigoJam API

Tweet
クリエイティブ・コモンズ・ライセンス
本ブログの記事や写真は「Creative Commons — CC BY 4.0」の下に提供します。記事内で紹介するプログラムや作品は、それぞれに記載されたライセンスを参照ください。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / 「一日一創」画像 / RSS