1月29日、Denoで「Deno での Wasm の紹介(Intro to Wasm in Deno)」と題した記事が公開された。この記事では、WebAssemblyをDenoで利用し、RustコードをJavaScriptから呼び出す方法について詳しく紹介されている。

以下に、その内容を簡潔にまとめて紹介する。
WebAssembly(以下、Wasm)はCやC++、Rustなどの言語をコンパイルして利用でき、ブラウザ上でもネイティブに近い高速なパフォーマンスを実現すると同時に、サンドボックスによる強固なセキュリティを提供する。 Deno 2.1ではWasmを簡単に利用できる機能が導入されており、 JavaScriptからWasmモジュールをシームレスに呼び出すことができるようになった。
Wasmモジュールをビルドする方法
まず、単純なWasmモジュールを作成し、Denoにインポートする手順を紹介する。wat形式(WebAssemblyのテキスト表現)で書かれた以下の例では、二つの整数を加算する関数addを定義している。
(module
(func (export "add") (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add
)
)
このadd.watをwat2wasmツールなどを使ってadd.wasmにコンパイルすることで、バイナリ形式のWasmモジュールを得ることができる。また、Wasm Code Explorerを利用すれば、生成されたWasmバイナリの内部構造を可視化できる。
Denoでは、以下のようにadd.wasmをインポートすることで、add関数をJavaScript側から直接呼び出すことが可能だ。
import { add } from "./add.wasm";
console.log(add(1, 2));
出力結果:
> deno run main.ts
3
DenoはWasmのエクスポートを理解し、型チェックも行うため、Wasmのコードを普通の関数としてインポートする感覚で扱うことが可能だ。
RustコードをJavaScriptからWasm経由で呼び出す
続いて、Rustで書かれた関数をWasm経由でJavaScriptから呼び出す方法を紹介する。wasmbuildというCLIツールを利用すると、Rustで定義した関数や構造体を自動的にWasmに変換し、JavaScript用のグルーコードを生成できる。
DenoとRustがインストールされている環境でdeno.jsonを作成したうえで、
{
"tasks": {
"wasmbuild": "deno run -A jsr:@deno/wasmbuild@0.19.0"
}
}
以下のようにコマンドを実行すると、新規のRustプロジェクトが作成される。
deno task wasmbuild new
生成されたRustのサンプルコードは、addという関数やGreeter構造体をWasm用にエクスポートしている。
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[wasm_bindgen]
pub struct Greeter {
name: String,
}
#[wasm_bindgen]
impl Greeter {
#[wasm_bindgen(constructor)]
pub fn new(name: String) -> Self {
Self { name }
}
pub fn greet(&self) -> String {
format!("Hello {}!", self.name)
}
}
ビルドを行うと、lib/rs_lib.wasmなど複数のファイルが生成される。
- lib/rs_lib.internal.js
- lib/rs_lib.js
- lib/rs_lib.d.ts
- lib/rs_lib.wasm
- mod.js
このlib/rs_lib.wasmも先ほどのWasm Code Explorerで可視化可能である。
さらに、mod.jsというファイルにはRust関数をJavaScriptで呼び出すサンプルコードが含まれている。
import { add, Greeter } from "./lib/rs_lib.js";
console.log(add(1, 1));
const greeter = new Greeter("world");
console.log(greeter.greet());
これにより、add関数やGreeter構造体のメソッドgreetをJavaScriptコード内で直接利用できる。実際にdeno mod.jsを実行すると、
2
Hello world!
のような出力が得られることを確認できる。
最後に
Denoでは、RustやJavaScriptの連携をより手軽にするためwasmbuildの機能拡充も進められているだけでなく、Wasmのコンパイルプロセスを簡略化してより高レベルなAPIのみを公開する方向性も検討されているという。
詳細は[Intro to Wasm in Deno]を参照していただきたい。