🍔

WsamとWASIにGoで触れてみる

2025/03/21に公開
2

はじめに

Wasm(WebAssembly)は、ブラウザだけでなくサーバーや組み込み環境でも実行可能な バイナリフォーマットのことを指します。
一方で、WASI(WebAssembly System Interface)は、Wasmをより汎用的な環境で動作させるためのAPI規格のことであり、Webブラウザに限定されないアプリケーションの開発を可能にします。

今回は、WasmとWASIの基礎概念を学び、Goを用いてWebAssemblyモジュールを作成する方法を解説してみようと思います。
ここ最近新し目の概念や技術に触れることが多くて、インプットもアウトプットも大変だ〜頑張ろう

対象読者

  • Wasm(WebAssembly)とWASIの基本を学びたい方
  • GoでWebAssemblyを活用する方法を知りたい方
  • WASIを使ってWebAssemblyをブラウザ以外の環境で実行してみたい方

目次

  1. Wasm(WebAssembly)とは?
    • Wasmの概要と仕組み
    • なぜWasmを使うのか?
  2. WASI(WebAssembly System Interface)とは?
    • WASIの役割と特徴
    • WasmとWASIの違い
  3. GoでWasmを作成する
    • GoでWasmモジュールをコンパイル
    • ブラウザでWasmを実行する方法
  4. GoでWASIを活用する
    • WASIを使ったファイルI/Oの実装
    • wasmtimeでGoのWasmモジュールを実行
  5. まとめ

1. Wasm(WebAssembly)とは?

1.1 Wasmの概要と仕組み

Wasm(WebAssembly)は、ブラウザで高パフォーマンスなコードを実行するためのバイナリフォーマットのことです。

特徴 説明
高速 ほぼネイティブ並みのパフォーマンスを実現
クロスプラットフォーム ブラウザ・サーバー・組み込み環境で実行可能
セキュア サンドボックス内で動作し、安全性が高い

1.2 なぜWasmを使うのか?

Wasmを利用することで、GoやRustなどの言語で書かれたコードを、JavaScriptの代わりにWebで実行することができます。

例えば、以下のようなユースケースがあります。

  • 計算量の多い処理(画像処理・データ解析)
  • ゲームエンジンや3Dレンダリング
  • WebブラウザでのGoアプリケーション実行

2. WASI(WebAssembly System Interface)とは?

2.1 WASIの役割と特徴

WASI(WebAssembly System Interface)は、WebAssemblyをブラウザ以外の環境で動作させるための API仕様です。

機能 説明
ファイル I/O ファイルの読み書きが可能
ネットワーク ソケット通信やHTTPリクエストのサポート
環境変数 システムの環境変数へアクセス可能

2.2 WasmとWASIの違い

項目 Wasm WASI
対象環境 ブラウザ中心 サーバー、CLI、組み込み環境
システムAPI JavaScript経由でアクセス 直接システムリソースにアクセス
用途 フロントエンド開発向け バックエンドやCLIアプリ向け

3. GoでWasmを作成する

3.1 GoでWasmモジュールをコンパイル

GoではGOOS=jsGOARCH=wasmを指定することでWasmにコンパイルできます。

wasm_program.go

package main

import "syscall/js"

func add(this js.Value, args []js.Value) interface{} {
    return js.ValueOf(args[0].Int() + args[1].Int())
}

func main() {
    js.Global().Set("add", js.FuncOf(add))
    select {}
}

コンパイル

GOOS=js GOARCH=wasm go build -o main.wasm wasm_program.go

3.2 ブラウザでWasmを実行する方法

<!DOCTYPE html>
<html>
<head>
    <script>
        WebAssembly.instantiateStreaming(fetch("main.wasm"), {}).then(obj => {
            console.log("2 + 3 =", obj.instance.exports.add(2, 3));
        });
    </script>
</head>
<body>
    <h1>Wasm + Go</h1>
</body>
</html>

4. GoでWASIを活用する

4.1 WASIを使ったファイルI/Oの実装

wasi_program.go

package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

func main() {
    data, _ := ioutil.ReadFile("input.txt")
    fmt.Println("File content:", string(data))
}

WASIに対応したコンパイル

GOOS=wasip1 GOARCH=wasm go build -o main.wasm wasi_program.go

4.2 wasmtimeでGoのWasmモジュールを実行

wasmtimeをインストール

brew install wasmtime

実行

wasmtime main.wasm --dir=.

5. まとめ

項目 説明
Wasm(WebAssembly) 高速・安全なコードをWebで実行するための技術
WASI(WebAssembly System Interface) Wasmをブラウザ外で実行するための API
GoでのWasm実装 syscall/jsを使ってJavaScriptと連携
GoでのWASI実装 ファイルI/OやシステムAPIを活用可能

次は、Wasmでのリアルタイムデータ処理についてや、WASI を活用したサーバーレス実行環境の構築についても書いてみようと思います!
日々の学習頑張ります〜

2

Discussion