Files
hakorune/docs/phases/phase-11.5/WASM-ISSUES.md

4.3 KiB
Raw Blame History

WASM実装の問題と改善計画

🚨 現状の問題

1. 2つのWASM実装が存在

  • Rust→WASM: wasm-pack buildでNyashインタープリター全体をWASMに動作する
  • MIR→WASM: --compile-wasmでNyashコードをWASMに変換ほぼ動かない

2. MIR→WASM実装の問題点

// src/backend/wasm/codegen.rs より
pub fn generate_module(...) -> Result<WasmModule, WasmError> {
    // 基本的な命令しか実装されていない
    // - 算術演算
    // - 制御フロー
    // - print文ホスト関数呼び出し
    
    // 未実装:
    // - Box操作NewBox, BoxCall, PluginInvoke
    // - 配列操作
    // - プラグインシステム
    // - GC/メモリ管理
}

3. 根本的な設計問題

  • Box抽象の表現困難: Everything is BoxをWASMの型システムで表現できない
  • 動的ディスパッチ: BoxCallやPluginInvokeの実装が困難
  • GCの不在: WASMにはGCがないWasmGC提案はまだ実験的
  • プラグインFFI: C ABIをWASM環境で実現できない

📊 現状の実装状況

実装済み(動作するもの)

// 基本的な算術
function add(a, b) {
    return a + b
}

// 単純な制御フロー
function factorial(n) {
    if n <= 1 { return 1 }
    return n * factorial(n - 1)
}

// print文ホスト関数経由
print("Hello WASM")

未実装(動作しないもの)

// Box操作
local str = new StringBox("hello")  // ❌ NewBox未実装
str.toUpperCase()                   // ❌ BoxCall未実装

// 配列
local arr = [1, 2, 3]              // ❌ 配列リテラル未実装
arr.push(4)                        // ❌ ArrayBox未実装

// プラグイン
local file = new FileBox()         // ❌ PluginInvoke未実装

🤔 なぜRust→WASMは動くのか

# Cargo.toml
[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"
  • すべてのBox実装がそのままWASMに: Arcも含めて
  • wasm-bindgenの魔法: JavaScript↔Rust境界を自動生成
  • 制限事項: 一部のBoxTimerBox、FileBox等は除外

🚀 改善案

Option 1: MIR→WASM実装の完成困難

;; BoxをWASMテーブルで管理
(table $boxes 1000 externref)
(global $next_box_id (mut i32) (i32.const 0))

;; NewBox実装
(func $new_string_box (param $str i32) (result i32)
  ;; 新しいBox IDを割り当て
  (local $box_id i32)
  (local.set $box_id (global.get $next_box_id))
  
  ;; JavaScriptでStringBoxを作成
  (table.set $boxes
    (local.get $box_id)
    (call $js_create_string_box (local.get $str)))
  
  ;; IDを返す
  (local.get $box_id)
)

問題点:

  • JavaScript側にBox実装が必要
  • 性能オーバーヘッドが大きい
  • プラグインシステムとの統合困難

Option 2: Rust→WASMの活用現実的

// NyashコードをRustに変換してからWASMに
nyash_code  rust_code  wasm

// 例:
// Nyash: local s = new StringBox("hello")
// Rust:  let s = Box::new(StringBox::new("hello".to_string()));
// WASM:  (自動生成)

Option 3: WASMランタイムの埋め込み革新的

;; 最小VMをWASMに埋め込む
(module
  ;; MIRバイトコードを格納
  (data (i32.const 0) "\01\02\03...")  
  
  ;; VMインタープリター
  (func $vm_execute
    ;; MIR命令をデコード・実行
  )
  
  ;; エントリーポイント
  (func (export "main")
    (call $vm_execute)
  )
)

🎯 推奨アプローチ

Phase 1: 現状維持

  • Rust→WASM: ブラウザでNyashを動かす用途で活用
  • MIR→WASM: 実験的機能として残す

Phase 2: Nyash→Rust変換

  • NyashコードをRustに変換する仕組みを作る
  • 生成されたRustコードをwasm-packでビルド

Phase 3: WasmGC待ち

  • WasmGC仕様が安定したら本格実装
  • Box型システムをWasmGCで表現

📝 結論

現在のMIR→WASM実装は実験的なもので、実用レベルには達していません。一方、Rust→WASMはすでに動作しており、ブラウザでNyashを体験してもらうには十分です。

当面は

  1. Rust→WASMでプレイグラウンド提供
  2. ネイティブ実行VM/JIT/AOTに注力
  3. WasmGCの成熟を待つ

これが現実的な戦略です!