Skip to content

Shuta-syd/tiny-wasm-runtime

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TinyWasm

TinyWasmは、軽量なWebAssembly (WASM) ランタイム実装の学習プロジェクトです。このプロジェクトは、RustでWasm Runtimeを実装するの記事を参考にして作成されました。WebAssemblyの仕組みとRustでの実装方法を学ぶことを目的としています。

概要

  • WebAssemblyバイナリのパースと解析方法
  • WebAssemblyの実行環境の構築
  • WASIインターフェースの基本実装
  • Rustを使った低レベルプログラミング

主な構成

プロジェクトは以下のモジュール構成になっています:

  • binary: WASMバイナリの解析とパース

    • instruction: WASM命令の定義と解析
    • module: WASMモジュールの構造と処理
    • opecode: 命令のオペコード定義
    • section: WASMセクションの解析
    • types: データ型の定義
  • execution: 実行環境

    • runtime: WASMプログラムの実行エンジン
    • store: メモリ、関数、テーブルなどの状態管理
    • value: WASMの値型と操作
    • wasi: WASI APIの実装
    • import: 外部関数のインポート機能

使い方

基本的な使用例

use anyhow::Result;
use tinywasm::execution::{runtime::Runtime, wasi::WasiSnapshotPreview1};

fn main() -> Result<()> {
    // WASIサポート付きでランタイムを初期化
    let wasi = WasiSnapshotPreview1::new();
    let wasm = include_bytes!("path/to/your/program.wasm");
    let mut runtime = Runtime::instantiate_with_wasi(wasm, wasi)?;
    
    // エントリポイント関数を実行
    runtime.call("_start", vec![])?;

    Ok(())
}

WASIサポート

このプロジェクトでは、WASI(WebAssembly System Interface)の一部を学習のために実装しています。現在実装されている主な機能は以下の通りです:

  • ファイルディスクリプタ(stdin, stdout, stderr)のサポート
  • fd_write 関数の実装(標準出力への書き込み)

WASIの初期化は以下のように行います:

// WASIの初期化 let wasi = WasiSnapshotPreview1::new(); // WASI対応のランタイム生成 let mut runtime = Runtime::instantiate_with_wasi(wasm, wasi)?;

サポート関数

関数名 説明
fd_write ファイルディスクリプタに対するデータ書き込み

サンプルWATコード(WebAssembly Text Format)

以下は「Hello, World!」を表示するWATサンプルです:

(module
  ;; WASIのfd_write関数をインポート
  (import "wasi_snapshot_preview1" "fd_write"
    (func $fd_write (param i32 i32 i32 i32) (result i32))
  )
  ;; メモリ定義
  (memory 1)
  ;; "Hello, World!\n"をメモリにセット
  (data (i32.const 0) "Hello, World!\n")

  ;; メイン関数
  (func $hello_world (result i32)
    (local $iovs i32)

    ;; IOVecの設定
    (i32.store (i32.const 16) (i32.const 0))
    (i32.store (i32.const 20) (i32.const 14))

    (local.set $iovs (i32.const 16))

    ;; fd_writeを呼び出し
    (call $fd_write
      (i32.const 1)  ;; ファイルディスクリプタ (stdout)
      (local.get $iovs)  ;; IOVecのポインタ
      (i32.const 1)  ;; IOVecの数
      (i32.const 24)  ;; 書き込みサイズを格納する位置
    )
  )
  ;; _start関数としてエクスポート
  (export "_start" (func $hello_world))
)

WATファイルはWasmバイナリに変換してから使用します:

# wat2wasmツールを使用してバイナリに変換
wat2wasm hello_world.wat -o hello_world.wasm

実装している機能

このプロジェクトを通じて学習した主なWASM実装:

  • 基本的な命令セット(算術演算、ローカル変数操作など)
  • メモリ操作
  • 関数呼び出し
  • WASI(WebAssembly System Interface)の基本実装

使用しているクレート

  • anyhow: エラーハンドリング
  • nom: バイナリパーサー
  • nom-leb128: LEB128エンコードされた数値のデコード
  • num-derive / num-traits: 数値型の変換ユーティリティ

実行方法

# ビルド
cargo build

# テスト実行
cargo test

# Hello Worldサンプルの実行
cargo run

参考資料

About

wasm runtime written in rust Reference: https://zenn.dev/skanehira/books/writing-wasm-runtime-in-rust

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •