Files
hakorune/docs/guides/wasm-guide/wasm_quick_start.md
Moe Charm cc2a820af7 feat(plugin): Fix plugin BoxRef return and Box argument support
- Fixed deadlock in FileBox plugin copyFrom implementation (single lock)
- Added TLV Handle (tag=8) parsing in calls.rs for returned BoxRefs
- Improved plugin loader with config path consistency and detailed logging
- Fixed loader routing for proper Handle type_id/fini_method_id resolution
- Added detailed logging for TLV encoding/decoding in plugin_loader_v2

Test docs/examples/plugin_boxref_return.nyash now works correctly:
- cloneSelf() returns FileBox Handle properly
- copyFrom(Box) accepts plugin Box arguments
- Both FileBox instances close and fini correctly

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-21 00:41:26 +09:00

3.0 KiB
Raw Blame History

🚀 Nyash WASM クイックスタート実装

Step 1: Cargo.toml修正

[dependencies]
wasm-bindgen = "0.2"
web-sys = "0.3"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies.web-sys]
version = "0.3"
features = [
  "console",
  "Document",
  "Element",
  "HtmlElement",
  "HtmlCanvasElement",
  "CanvasRenderingContext2d",
  "Window",
]

Step 2: lib.rsにWASMエクスポート追加

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub struct NyashWasm {
    interpreter: NyashInterpreter,
}

#[wasm_bindgen]
impl NyashWasm {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Self {
        // panicをconsole.errorに
        console_error_panic_hook::set_once();
        
        let mut interpreter = NyashInterpreter::new();
        // WASMBox等を登録
        Self { interpreter }
    }
    
    #[wasm_bindgen]
    pub fn eval(&mut self, code: &str) -> String {
        match self.interpreter.eval(code) {
            Ok(result) => format!("{:?}", result),
            Err(e) => format!("Error: {}", e),
        }
    }
}

Step 3: ConsoleBox実装

// src/boxes/console_box.rs
pub struct ConsoleBox;

impl NyashBox for ConsoleBox {
    fn box_type(&self) -> &'static str { "ConsoleBox" }
    
    fn call_method(&self, name: &str, args: Vec<Arc<dyn NyashBox>>) -> Result<Arc<dyn NyashBox>, String> {
        match name {
            "log" => {
                let msg = args[0].to_string();
                web_sys::console::log_1(&msg.into());
                Ok(Arc::new(VoidBox))
            }
            _ => Err(format!("Unknown method: {}", name))
        }
    }
}

Step 4: 簡単なHTML

<!DOCTYPE html>
<html>
<head>
    <title>Nyash in Browser!</title>
    <style>
        #editor { width: 100%; height: 200px; }
        #output { border: 1px solid #ccc; padding: 10px; }
    </style>
</head>
<body>
    <h1>🐱 Nyash Browser Playground</h1>
    <textarea id="editor">
// Nyashコードをここに書くにゃ
console = new ConsoleBox()
console.log("Hello from Nyash in Browser!")

x = 10
y = 20
console.log("x + y = " + (x + y))
    </textarea>
    <br>
    <button onclick="runNyash()">実行!</button>
    <div id="output"></div>
    
    <script type="module">
        import init, { NyashWasm } from './nyash_wasm.js';
        
        let nyash;
        
        async function main() {
            await init();
            nyash = new NyashWasm();
            window.runNyash = () => {
                const code = document.getElementById('editor').value;
                const output = nyash.eval(code);
                document.getElementById('output').textContent = output;
            };
        }
        
        main();
    </script>
</body>
</html>

ビルドコマンド

# wasm-packインストール
cargo install wasm-pack

# ビルド
wasm-pack build --target web --out-dir www

# ローカルサーバー起動
cd www && python3 -m http.server 8000

これで http://localhost:8000 でNyashがブラウザで動く🎉