Article Outline
WebAssemblyとは
ブラウザ上で動く仮想マシンを動かすための仕様のこと。
WebAssemblyアセンブリ言語の例
命令語 | 16進数 |
---|---|
get_local $n | 20 |
i32.const n | 41 |
i32.add | 6a |
WebAssemblyアセンブリ言語→WebAssemblyマシン語
アセンブリ言語からマシン語に変換することをアセンブル、その機械をアセンブラという。
例えばWebAssemblyアセンブリ言語で足し算をする関数を書いてみます。
get_local 0
i32.const 1
i32.add
end
これをアセンブルすると、WebAssemblyマシン語(wasm)の完成。
0x00, 0x61, 0x73, 0x6d,
0x01, 0x00, 0x00, 0x00,
0x01, 0x06, 0x01, 0x60, 0x01, 0x7f, 0x01, 0x7f,
0x03, 0x02, 0x01, 0x00,
0x07, 0x05, 0x01, 0x01, 0x66, 0x00, 0x00,
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x0b
0x20, 0x00, 0x41, 0x01, 0x6a
福野さん作の手書きWebAssembly。
アセンブリを書くのは辛い
マシン語を手書きするのは勿論、アセンブリ言語の手書きもつらいので高級言語を使います。
高級言語を用いることで、高級言語→コンパイル→アセンブリ言語→アセンブル→マシン語
と変換できます。
zig言語を使う
zig言語を使ってWebAssemblyを吐かせてみます。
zig言語はC++やRustなどの他の言語に比べて仕様がシンプルだそう。
プロジェクトの作成
brew install zig
mkdir zig-playground
cd zig-playground
zig init-exe
ハローワールド
src/main.zig
を編集します。
const std = @import("std");
pub fn main() anyerror!void {
std.debug.print("Hello, {s}!\n", .{"World"});
}
実行。
zig run src/main.zig
wasmを吐かせる
src/main.zig
を編集します。
export fn add(a: i32, b: i32) i32 {
return a + b;
}
コンパイル。
zig build-lib src/main.zig -target wasm32-freestanding-musl -dynamic -O ReleaseSmall
中身を見てみる。
ブラウザからwasmを読み取る
index.html
を作成。
<!DOCTYPE html>
<html lang="ja">
<head>
<title>WebAssembly</title>
</head>
<body>
<script>
WebAssembly.instantiateStreaming(fetch('main.wasm'))
.then(obj => {
const res = obj.instance.exports.add(1, 2);
console.log(res)
});
</script>
</body>
</html>
Webサーバーを立ち上げる。なんでもいいですがかんたんなのでpython
使ってます。
python3 -m http.server 8000
localhost:8000
にアクセスしコンソールで確認。