はじめに
HTML ファイルには CSS や JavaScript を直接記述することができますが、第 4 の Web 言語と呼ばれる WebAssembly も工夫すればファイル内に直接記述することができます。
本記事では、Base64 を利用した方法を紹介します。
実装
本記事では、以下のシンプルな「加算モジュール」を扱います。(WebAssembly
自体はバイナリ形式であり、以下は、そのテキスト表現である Wat
で記述しています。)
(module
(func $add (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add
)
(export "add" (func $add))
)
以下のリンク先などで、上記のコードを BASE64
形式の WebAssembly
に変換します。
変換すると、以下のような文字列形式に変換されます。
AGFzbQEAAAABBwFgAn9/AX8DAgEABwcBA2FkZAAACgkBBwAgACABagsAGARuYW1lAQYBAANhZGQCCQEAAgABYQEBYg==
あとは、HTML
ファイルの script
タグ内で WebAssembly
を呼び出すだけです。
index.html
<script>
const base64Wasm = "AGFzbQEAAAABBwFgAn9/AX8DAgEABwcBA2FkZAAACgkBBwAgACABagsAGARuYW1lAQYBAANhZGQCCQEAAgABYQEBYg==";
// 1. Base64デコードしてArrayBufferに変換
function base64ToArrayBuffer(base64) {
const binaryString = atob(base64); // Base64デコード
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer; // ArrayBufferを返す
}
// 2. WASMインスタンスを生成
async function loadWasm(base64) {
const wasmArrayBuffer = base64ToArrayBuffer(base64);
const wasmModule = await WebAssembly.instantiate(wasmArrayBuffer);
return wasmModule.instance;
}
// 3. WASMを利用
loadWasm(base64Wasm)
.then(instance => {
console.log("WASM instance loaded:", instance);
// エクスポートされた関数を呼び出す
if (instance.exports.add) {
for (let i = 0; i < 10; i++) {
console.log(instance.exports.add(i, i));
}
}
})
.catch(err => {
console.error("Failed to load WASM:", err);
});
</script>
コードの解説
-
Base64 デコード
atob
でBase64
文字列をバイナリー文字列に変換。
Uint8Array
でバイト列に変換し、ArrayBuffer
に変換。 -
WebAssembly.instantiate
ArrayBuffer
からWASM
モジュールをインスタンス化。
exports.add
としてエクスポートされた関数を呼び出します。 -
WASM を利用
instance.exports.add
を呼び出し、ここではループを10回行い、結果をログに出力します。