Files
hakorune/docs/development/roadmap/phases/phase-12/archive/c-abi-compatibility.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

5.0 KiB
Raw Blame History

C ABIとの整合性Phase 12スクリプトプラグインシステム

🚨 重要な発見

Phase 10.1で既にC ABI v0が定義されており、これとPhase 12の提案を整合させる必要があります。

📊 現状のC ABIPhase 10.1

既存のBID-FFIプラグイン用

// 現在のプラグインFFITLVベース
extern "C" fn nyash_plugin_invoke(
    type_id: u32,
    method_id: u32,
    instance_id: u32,
    args: *const u8,      // TLVエンコード
    args_len: usize,
    result: *mut u8,      // TLVエンコード
    result_len: *mut usize,
) -> i32

新しいNyRT C ABI v0

// コア関数
int32_t  nyrt_abi_version(void);
NyBox    nyrt_box_new(uint64_t typeid, uint64_t size);
void     nyrt_box_free(NyBox b);

// プラグイン関数Array
int32_t  nyplug_array_abi_version(void);
NyBox    nyplug_array_new(void);
int32_t  nyplug_array_get(NyBox arr, uint64_t i, NyBox* out);

🎯 Phase 12の修正案

問題点

  • Gemini/Codexの提案したBoxInterfaceトレイトはRust専用
  • C ABIとの相互運用性が考慮されていない
  • TLVエンコーディングとの整合性が不明

解決策C ABIラッパー戦略

// ❌ 元の提案Rust専用
trait BoxInterface {
    fn invoke(&self, method_id: u32, args: NyashValue) -> NyashValue;
}

// ✅ 修正案C ABI互換
pub struct ScriptPluginWrapper {
    // Nyashスクリプトインスタンス
    script_box: NyashValue,
    
    // C ABI互換性のためのFFI関数
    ffi_invoke: extern "C" fn(
        type_id: u32,
        method_id: u32,
        instance_id: u32,
        args: *const u8,
        args_len: usize,
        result: *mut u8,
        result_len: *mut usize,
    ) -> i32,
}

impl ScriptPluginWrapper {
    // 既存のBID-FFIと完全互換
    pub extern "C" fn invoke_ffi(
        &self,
        type_id: u32,
        method_id: u32,
        instance_id: u32,
        args: *const u8,
        args_len: usize,
        result: *mut u8,
        result_len: *mut usize,
    ) -> i32 {
        // 1. TLVデコード
        let nyash_args = decode_tlv(args, args_len);
        
        // 2. Nyashスクリプト呼び出し
        let result_value = self.script_box.invoke(method_id, nyash_args);
        
        // 3. TLVエンコード
        encode_tlv(result_value, result, result_len)
    }
}

🔄 統合アーキテクチャ

[JIT/AOT] ---> C ABI (nyrt_*/nyplug_*) --+--> [ネイティブプラグイン]
                                          |
                                          +--> [ScriptPluginWrapper] --> [Nyashスクリプト]

利点

  1. 完全な後方互換性 - 既存のプラグインがそのまま動作
  2. 統一されたFFI - JIT/AOT/プラグインすべて同じC ABI
  3. 透過的な利用 - 呼び出し側はネイティブ/スクリプトを区別しない

📝 実装修正案

Phase 12.1(修正版)

  1. ScriptPluginWrapperの実装

    • BID-FFI互換のC関数エクスポート
    • TLVエンコード/デコード処理
    • Nyashスクリプトへの橋渡し
  2. プラグインレジストリ拡張

    pub struct PluginRegistry {
        // 既存のネイティブプラグインC ABI
        native_plugins: HashMap<u32, PluginHandle>,
    
        // スクリプトプラグインC ABIラッパー経由
        script_plugins: HashMap<u32, ScriptPluginWrapper>,
    }
    
  3. export box構文の実装

    export box CustomMathPlugin {
        // BID-FFI互換のためのメタ情報
        __type_id__ = 100  // 動的割り当てor設定ファイル
        __methods__ = {
            "cached_sin": 1,
            "cached_cos": 2
        }
    
        // 通常のNyashコード
        init { ... }
        cached_sin(x) { ... }
    }
    

🚀 移行パス

段階1既存プラグインの動作確認

  • FileBox、NetBox等がC ABI経由で正常動作
  • パフォーマンステスト

段階2簡単なスクリプトプラグイン

  • MathBoxの一部機能をNyashで再実装
  • C ABIラッパー経由での動作確認

段階3高度な統合

  • ネイティブとスクリプトの混在
  • 動的ロード/アンロード

パフォーマンス影響

呼び出しチェーン:
1. JIT → C ABI関数呼び出し既存
2. C ABI → ScriptPluginWrapper追加
3. Wrapper → TLVデコード追加
4. Wrapper → Nyashスクリプト実行追加
5. Wrapper → TLVエンコード追加

予想オーバーヘッド: 100-500ns/呼び出し

🎯 結論

Phase 12のスクリプトプラグインシステムは、C ABIを尊重しつつ実装可能です。

  • BoxInterfaceトレイトは内部実装詳細に留める
  • 外部インターフェースは既存のC ABIBID-FFIを維持
  • ScriptPluginWrapperがブリッジとして機能

これにより、**「Everything is Plugin」**の哲学を保ちながら、スクリプトプラグインを実現できます。