Files
hakorune/docs/development/roadmap/phases/phase-12/archive/PLUGIN-BOX-HANDLE-SUPPORT.md
Moe Charm 11506cee3b Phase 11-12: LLVM backend initial, semantics layer, plugin unification
Major changes:
- LLVM backend initial implementation (compiler.rs, llvm mode)
- Semantics layer integration in interpreter (operators.rs)
- Phase 12 plugin architecture revision (3-layer system)
- Builtin box removal preparation
- MIR instruction set documentation (26→Core-15 migration)
- Cross-backend testing infrastructure
- Await/nowait syntax support

New features:
- LLVM AOT compilation support (--backend llvm)
- Semantics layer for interpreter→VM flow
- Tri-backend smoke tests
- Plugin-only registry mode

Bug fixes:
- Interpreter plugin box arithmetic operations
- Branch test returns incorrect values

Documentation:
- Phase 12 README.md updated with new plugin architecture
- Removed obsolete NYIR proposals
- Added LLVM test programs documentation

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-01 23:44:34 +09:00

3.3 KiB
Raw Blame History

プラグインBoxは既に箱を引数に取れる

🎯 重要な発見

プラグインBoxは既にC ABIレベルで箱を引数に取ることができます

📊 実装の詳細

1. TLVプロトコルでのハンドルサポート

// TLVタグ定義
const TAG_HANDLE: u8 = 8;  // プラグインハンドル用

// ハンドルエンコード関数
pub fn plugin_handle(buf: &mut Vec<u8>, type_id: u32, instance_id: u32) {
    buf.push(TAG_HANDLE);
    buf.push(0u8); // reserved
    buf.extend_from_slice(&(8u16).to_le_bytes());  // size = 8
    buf.extend_from_slice(&type_id.to_le_bytes());      // 4 bytes
    buf.extend_from_slice(&instance_id.to_le_bytes());  // 4 bytes
}

2. プラグイン呼び出し時の処理

// Nyashコード
box1.process(box2, box3)

// ↓ VM/プラグインローダーでの処理
for arg in args {
    if let Some(p) = arg.as_any().downcast_ref::<PluginBoxV2>() {
        // 箱引数はハンドルとしてエンコード
        encode::plugin_handle(&mut tlv, p.type_id, p.instance_id);
    }
    // ... 他の型の処理
}

// ↓ C ABIプラグイン側
int32_t nyash_plugin_invoke(
    uint32_t type_id,
    uint32_t method_id,
    uint32_t instance_id,
    const uint8_t* args,    // TLVエンコードされた引数
    size_t args_len,
    uint8_t* result,
    size_t* result_len
) {
    // TLVデコード
    uint8_t tag;
    uint32_t arg_type_id, arg_instance_id;
    
    if (decode_handle(args, &tag, &arg_type_id, &arg_instance_id)) {
        // ハンドル引数を処理
        // arg_type_id と arg_instance_id で箱を特定
    }
}

🔄 実際の使用例

Nyashレベル

// FileBoxがStringBoxを引数に取る例
local file = new FileBox()
local path = new StringBox("/tmp/test.txt")
file.open(path)  // StringBoxプラグインBoxを引数に

// ArrayBoxがMapBoxを引数に取る例
local array = new ArrayBox()
local map = new MapBox()
array.push(map)  // MapBoxプラグインBoxを引数に

プラグイン間の相互運用

// NetBoxがJSONBoxを引数に取る例
local net = new NetBox()
local json = new JSONBox()
json.set("url", "https://api.example.com")
net.post(json)  // JSONBoxを引数として渡す

💡 重要なポイント

1. ハンドルによる間接参照

  • 箱の実体は渡さない(メモリ安全性)
  • (type_id, instance_id)のペアで識別
  • プラグイン側でハンドルから実体にアクセス

2. 型安全性

  • type_idで型を識別可能
  • 不正な型の場合はエラー返却

3. 所有権管理

  • インスタンスIDで参照管理
  • プラグイン間でも安全に共有

🎯 結論

C ABIの制約があっても、ハンドル機構により箱は箱を引数に取れる

これは既に実装済みの機能であり、プラグイン間での高度な連携が可能です。

埋め込みVMへの示唆

既存のTLVハンドル機構をそのまま使えば、埋め込みVMでも同じように箱引数をサポートできます

  1. Nyashスクリプト内で箱を引数に使用
  2. MIRバイトコードにBoxCall命令を含める
  3. 埋め込みVMがTLVエンコードでC ABIプラグインを呼び出し
  4. ハンドル経由で箱を渡す

Everything is Box、そしてC ABIでも箱は箱を扱える