Files
hakorune/docs/CURRENT_TASK.md
Moe Charm c6c3c8e2f9 fix(bid-ffi): Fix HostVtable lifetime issue causing segfault
🚨 Critical memory safety fix:
- HostVtable was created on stack and destroyed after init
- Plugin stored reference to destroyed memory → NULL pointer access
- Changed to static LazyLock storage for lifetime safety

 Results:
- Segfault completely eliminated
- Plugin logging now works properly
- Type info system confirmed working
- Full E2E FileBox plugin operation successful

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 14:10:41 +09:00

24 KiB
Raw Blame History

🎯 現在のタスク (2025-08-19 更新)

🆕 今取り組むタスク(最優先)

  • plugin-tester: open/read/write のTLVテスト追加E2E強化 完了
  • FileBoxプラグイン: invokeに open/read/write/close 実装BID-1 TLV準拠 完了
  • Nyash本体: new FileBox(...) をプラグイン優先で生成(暫定フック) 実装済みcodex
  • PluginBox: メソッド転送TLV encode/decode最小実装 ⚠️ 実装済みcodex、TLV修正要

本日の成果2025-08-18 午後)

  • plugin-tester io サブコマンド追加open→write→close→open→read 一連動作)
  • プラグイン側 nyash_plugin_invoke に open/read/write/close 実装2段階応答のプリフライト時は副作用なしで必須サイズ返却に修正
  • 説明書を追加: docs/説明書/reference/plugin-tester.md使い方・TLV・エラーコード・トラブルシュート
  • FileBox API対応表: docs/説明書/reference/box-design/filebox-bid-mapping.md 追加Nyash API ↔ BID-FFI マッピング)

🎉 ローカル実行テスト結果2025-08-18 実測)

plugin-tester: 完全動作確認

$ plugin-tester check libnyash_filebox_plugin.so
✓: Plugin loaded successfully
✓: ABI version: 1
✓: Plugin initialized
Plugin Information: FileBox (ID: 6), Methods: 6
✓: Plugin shutdown completed

$ plugin-tester io libnyash_filebox_plugin.so
✓: birth → instance_id=1
✓: open(w), close, open(r)
⚠️: read rc=-8 (デコードエラー、TLV修正要)

Nyash統合: 部分的成功(プラグインロード確認)

$ ./target/debug/nyash local_tests/test_plugin_filebox.nyash
🔌 BID plugin loaded: FileBox (instance_id=1)  ← 成功!
✅ Parse successful!
✅ new FileBox(...) まで到達
⚠️ Segmentation fault (ファイル操作部分、TLV処理改善要)

🎯 codex実装成果1時間で達成

  • プラグインシステム基盤: 完全動作
  • plugin-tester診断ツール: 汎用設計で完璧動作
  • Nyash統合: プラグインロード・Box生成まで成功
  • ⚠️ 残り課題: TLVエンコード/デコード最適化

簡易実行テスト状況(過去ログ参考)

  • nyash 本体実行(引数なし/単純スクリプト): 実行OK
  • plugin-tester io による FileBox E2E: open→write→close→open→read でOK
  • nyash からプラグイン FileBox を new して利用: ⚠️ サンドボックス制約により実行中にSIGKILLdlopen系の制約
    • ローカル実行(手元環境)では cargo build --bin nyash./target/debug/nyash local_tests/test_plugin_filebox.nyash で動作見込み
    • 期待出力: READ=Hello from Nyash via plugin!

🚀 現在進行中: Phase 9.75g-0 型定義ファースト BID-FFI実装

目的: FFI ABI v0準拠のシンプルで動くプラグインシステム構築 戦略: 型定義は全部最初に、実装は段階的にunimplemented!活用) 期間: 1週間2025-08-17〜2025-08-24 詳細:

Day 1 完了! (2025-08-17)

  • ChatGPT先生の最終レビュー完了
  • ffi-abi-specification.mdをBID-1 Enhanced Editionに更新
  • Handle設計type_id + instance_id確定
  • BID-1 TLVフォーマット仕様確定
  • プラグインAPInyash_plugin_*)仕様確定
  • BID-1基盤実装完了
    • src/bid/モジュール構造作成
    • TLVエンコード/デコード実装
    • エラーコード定義BidError
    • 型システムBidType, BidHandle
    • テスト4/4合格 🎉

Day 2 完了! (2025-08-17)

目標: メタデータAPI実装ホスト統合・プラグイン情報管理

実装完了:

  • HostVtable: ホスト機能テーブルalloc/free/wake/log
  • NyashPluginInfo: プラグイン情報構造体
  • NyashMethodInfo: メソッド情報構造体
  • C FFI関数シグネチャ定義
  • プラグインライフサイクル管理
  • テスト7/7合格 🎉

Day 3 完了! (2025-08-17)

目標: 既存Box統合StringBox/IntegerBox/FutureBoxブリッジ

実装完了 (100%達成!):

  • BID Box Bridge設計: 既存Box型とBIDハンドルの相互変換インターフェース
  • StringBox BIDブリッジ: Handle/TLV変換実装
  • IntegerBox BIDブリッジ: Handle/TLV変換実装
  • FutureBox BIDブリッジ: 非同期Box型の統合完了
  • BoxRegistry: Box型とハンドルの管理システム
  • 統合テスト: 全Box型ラウンドトリップテスト4/4合格
  • Everything is Box理論の威力実証 🎉

Day 4 完了! (2025-08-17)

目標: プラグインシステム基盤実装

実装完了 (100%達成!):

  • FileBoxプラグイン設計: open/read/write/close API設計
  • FileBoxプラグイン実装: ハンドル管理・ファイル操作実装
  • プラグインシステム設計統合: gemini先生とcodex先生の提案を統合
  • nyash.tomlパーサー実装シンプル版
  • PluginBoxプロキシ実装最小版
  • BoxFactoryRegistry: 透過的ビルトイン↔プラグイン切り替え
  • libloadingプラグイン動的ロード基盤
  • プラグインシステム統合テスト14/14合格 🎉

Day 5 完了! (2025-08-18)

目標: 実際のプラグインライブラリ作成と統合

実装戦略:

  • 段階的アプローチ: ビルトインFileBox残して並行運用
  • 透過的切り替え: nyash.tomlで動的選択
  • 完全実証: BID-FFIシステムの実動作確認

完了タスク:

  • FileBoxプラグイン用クレート作成独立ライブラリ
  • C API実装とエクスポートlibnyash_filebox_plugin.so生成
  • Nyashインタープリターのプラグインロード統合
  • 透過的切り替え実動作確認PluginBox生成確認
  • プラグインメソッド呼び出し実装 - execute_plugin_file_method
  • 完全動作確認 - f.write(), f.read() 完全成功

重要な発見と対応:

  • 🔍 セグフォルト調査: 実際はセグフォルトではなく型エラーが原因
  • 🎯 真の問題: PluginFileBoxのメソッド呼び出し処理が未実装
  • 解決: calls.rsにPluginFileBox処理追加、io_methods.rsに実装

Day 5 最終テスト結果:

$ ./target/release/nyash local_tests/test_plugin_filebox.nyash
READ=Hello from Nyash via plugin!
✅ Execution completed successfully!

🚨 発見した設計課題Day 6対応予定:

  • 問題: メソッド名がハードコードread/write/exists/close
  • 課題: プラグインからメソッド情報を動的取得すべき
  • 目標: 汎用的なプラグインメソッド呼び出しシステム実装

🎯 今週の実装計画(段階的戦略に更新)

  • Day 1: BID-1基盤実装TLV仕様、Handle構造体、エンコード/デコード)
  • Day 2: メタデータAPI実装init/abi/shutdown、HostVtable、レジストリ
  • Day 3: 既存Box統合StringBox/IntegerBox/FutureBoxブリッジ100%完了!
  • Day 4: プラグインシステム基盤nyash.toml、PluginBox、BoxFactory100%完了!
  • Day 5: 実際のプラグインライブラリ作成(.so/.dll、Nyash統合完了!
  • Day 6: 動的メソッド呼び出しシステム実装(メソッド名脱ハードコード)完了!
  • Day 7: 実動作実証とドキュメント(透過的切り替え、開発ガイド)

🔑 技術的決定事項

  • ポインタ: usize(プラットフォーム依存)
  • アライメント: 8バイト境界
  • 単一エントリーポイント: nyash_plugin_invoke
  • ターゲット: Linux x86-64限定

完了済み主要成果

MIR 35→26命令削減 (2025-08-17)

  • 実装期間: 1日予定5週間の5%
  • 成果: 26命令体系確立、全バックエンド対応
  • 詳細: mir-26-specification.md

Phase 9.75 RwLock変換 (完了)

  • Arc → Arc全Box型変換
  • 性能改善達成

Phase 9.75e using nyashstd (完了)

  • 標準ライブラリ統合
  • リテラル自動変換実装

Phase 9.75j 警告削減 (完了)

  • 106個→0個100%削減)

🔮 次期優先タスク

  1. Phase 8.6: VM性能改善(緊急)

  2. Phase 9: JIT実装

    • VM改善後の次ステップ
  3. Phase 10: LLVM Direct AOT

    • 目標: 100-1000倍高速化
    • 期間: 4-6ヶ月

📊 プロジェクト統計

  • 実行モード: インタープリター/VM/WASM/AOT開発中
  • Box型数: 16種類すべてRwLock統一+ プラグインBox対応
  • MIR命令数: 26最適化済み
  • ビルド時間: 2分以上改善中
  • プラグインシステム: BID-FFI 95%実装完了Day 6完了

🔧 開発ガイドライン

クイックリファレンス

テスト実行

# リリースビルド(推奨)
cargo build --release -j32

# 実行
./target/release/nyash program.nyash

# ベンチマーク
./target/release/nyash --benchmark --iterations 100

最終更新: 2025-08-19 10:00 JST
次回レビュー: 2025-08-19Day 7開始時

🎯 現在の状況 (2025-08-18)

Step 1-3 完了BID-FFI基盤実装成功

達成した重要な設計原則

  1. Box名非決め打ち: プラグインが「私はFileBoxです」と宣言
  2. 汎用的設計: plugin-testerは任意のプラグインに対応
  3. メモリ管理明確化: birth/finiライフサイクル実装

実装完了項目

  • FileBoxプラグイン: 293KB .soファイル生成、6メソッド実装
  • nyash.toml: プラグイン設定ファイルFileBox = "nyash-filebox-plugin"
  • plugin-tester: 診断ツール完成、メソッド一覧表示機能付き

テスト結果

Plugin Information:
  Box Type: FileBox (ID: 6)  ← プラグインから取得!
  Methods: 6
  - birth [ID: 0, Sig: 0xBEEFCAFE] (constructor)
  - open [ID: 1, Sig: 0x12345678]
  - read [ID: 2, Sig: 0x87654321]
  - write [ID: 3, Sig: 0x11223344]
  - close [ID: 4, Sig: 0xABCDEF00]
  - fini [ID: 4294967295, Sig: 0xDEADBEEF] (destructor)

実装完了ステップ

Step 1: FileBoxプラグイン単体作成

  • plugins/nyash-filebox-plugin/Cargo.toml作成
  • C FFI実装birth/fini含む
  • 単体でビルド確認293KB .soファイル生成

Step 2: nyash.toml設定ファイル作成

  • シンプルな設定ファイル作成
  • FileBox = "nyash-filebox-plugin"の設定
  • プラグイン検索パス定義

Step 3: プラグインテスター/ローダー作成

  • 独立したテストツール plugin-tester作成
  • Box名を決め打ちしない汎用設計
  • 実装済み機能:
    • プラグインロードチェック
    • nyash_plugin_init呼び出し確認
    • メソッド一覧表示
    • ABI version確認
  • 今後の拡張予定:
    • birth/finiライフサイクルテスト
    • メモリリーク検出valgrind連携
    • TLVエンコード/デコード検証

🎯 次のステップ: Step 4 - Nyashとの統合

実装計画

  1. src/bid/モジュール作成

    • TLVエンコード/デコード実装 src/bid/tlv.rs
    • BidHandle構造体定義 src/bid/types.rs
    • エラーコード定義 src/bid/error.rs
  2. プラグインローダー実装

    • nyash.tomlパーサー簡易版 src/bid/registry.rs
    • libloadingによる動的ロード src/bid/loader.rs
    • プラグイン初期化・シャットダウン管理 src/bid/loader.rs
  3. BoxFactoryRegistry実装

    • ビルトインBox vs プラグインBoxの透過的切り替え
    • Box名 → プラグイン名マッピング
    • new FileBox()時の動的ディスパッチ
  4. PluginBoxプロキシ実装

    • NyashBoxトレイト実装準備段階、最小のインスタンス管理
    • メソッド呼び出しをFFI経由で転送
    • birth/finiライフサイクル管理Dropトレイト src/bid/plugin_box.rs
  5. 統合テスト

    • FileBoxのビルトイン版とプラグイン版の動作比較
    • nyash.tomlありなしでの切り替え確認
    • メモリリークチェック

仕様更新完了

  • birth/finiライフサイクル管理を仕様書に追加
  • メモリ所有権ルールを明確化
  • プラグインが割り当てたメモリはプラグインが解放する原則

現在のディレクトリ構造

nyash-project/nyash/
├── plugins/
│   └── nyash-filebox-plugin/     # ✅ 実装済み
│       ├── Cargo.toml
│       ├── src/lib.rs            # birth/fini含む6メソッド
│       └── .gitignore
├── tools/
│   └── plugin-tester/            # ✅ 実装済み
│       ├── Cargo.toml
│       ├── src/main.rs           # 汎用プラグインチェッカー
│       └── .gitignore
├── nyash.toml                    # ✅ 実装済み
└── src/
    └── bid/                      # ✅ Step 4の基盤作成済み
        ├── mod.rs                # モジュール公開
        ├── loader.rs             # プラグインローダーlibloading, init, ABI検証
        ├── registry.rs           # 簡易nyash.toml読取ロード
        └── plugin_box.rs         # PluginBoxインスタンスbirth/fini

## ✅ 直近の進捗2025-08-18 午前)

- plugin-tester: `lifecycle` サブコマンド実装birth→finiまでE2E確認
- FileBoxプラグイン: `nyash_plugin_invoke` をBID-1の2段階応答ShortBuffer=-1に準拠、birth/fini実装
- Nyash側: `loader/registry/plugin_box` 追加、ビルド通過

### 実行結果(抜粋)

$ plugin-tester check libnyash_filebox_plugin.so ✓: ABI version: 1 ✓: Plugin initialized Plugin Information: FileBox(ID:6), Methods: 6

$ plugin-tester lifecycle libnyash_filebox_plugin.so ✓: birth → instance_id=1 ✓: fini → instance 1 cleaned


### ✅ **Day 6 完了!** (2025-08-19)
**目標**: 動的メソッド呼び出しシステム実装(メソッド名脱ハードコード)

**実装完了** (100%達成!):
- ✅ プラグインメタデータAPI強化: `find_method()`, `get_methods()` 実装
- ✅ 汎用メソッド呼び出しシステム: `execute_plugin_method_generic` 実装
- ✅ TLVエンコード/デコード汎用化: 型に応じた自動変換
- ✅ **重要な修正**:
  - Bytesタグ対応: writeメソッドは文字列をBytesタグ(7)で送信
  - readメソッド引数: 引数なしでもデフォルト8192バイトを送信
- ✅ ハードコード完全削除: execute_plugin_file_methodを汎用システムにリダイレクト
- ✅ **完全動作確認**: write/read両方成功

**🚨 重要な設計問題発見**:
- **Nyashは関数オーバーロード不採用** (2025-08-12 AI大会議決定)
- ビルトインFileBoxは `read()` のみ(引数なし)
- プラグインFileBoxが `read(size)` を期待 → **設計不一致**
- 現在のハードコードreadに8192追加も**Nyash仕様違反**

**Day 6 最終テスト結果**:
```bash
$ ./target/release/nyash local_tests/test_plugin_filebox.nyash
🔌 BID plugin loaded: FileBox (instance_id=1)
✅ Parse successful!
READ=Hello from Nyash via plugin!
✅ Execution completed successfully!

🎯 次アクションDay 7: 実動作実証とドキュメント)

Day 7緊急修正 完了!

  1. プラグインFileBox修正

    • read(size)read() に変更Nyash仕様準拠
    • ファイル全体を読む実装に修正済み
  2. ハードコード削除

    • readメソッドの8192バイトデフォルト削除済み
    • encode_arguments_to_tlvから特殊処理完全除去済み

🎯 Day 7 型情報管理システム実装進捗2025-08-19

実装完了項目90%完了)

  1. 型情報構造体定義 完了

    • MethodTypeInfo, ArgTypeMapping 構造体実装
    • determine_bid_tag() で型名からBIDタグへの変換実装
    • テストケース追加済み
  2. nyash.toml型情報記述 完了

    [plugins.FileBox.methods]
    read = { args = [] }
    write = { args = [{ from = "string", to = "bytes" }] }
    open = { args = [
        { name = "path", from = "string", to = "string" },
        { name = "mode", from = "string", to = "string" }
    ] }
    
  3. PluginRegistry型情報統合 完了

    • 型情報保持フィールド追加
    • get_method_type_info() メソッド実装
    • 簡易パーサーでnyash.tomlから型情報読み込み
  4. execute_plugin_method_generic型情報適用 完了

    • 型情報に基づく自動エンコーディング実装
    • ハードコード完全削除(美しい!)
    • デバッグ出力追加
  5. 動作確認テスト 完了

    $ ./target/release/nyash local_tests/test_plugin_filebox.nyash
    READ=Hello from Nyash via plugin!
    ✅ Execution completed successfully!
    
  6. 型情報システム実動作確認 完了2025-08-19

    • writeメソッド: 36バイトエンコードstring→bytes変換動作
    • readメソッド: 4バイトエンコード引数なし正常
    • 型情報に基づく自動変換が正しく機能

📊 実装の成果

Before醜いハードコード:

if method_name == "read" && arguments.is_empty() {
    encoder.encode_i32(8192)  // ハードコード!
}

After美しい型情報ベース:

let type_info = registry::global()
    .and_then(|reg| reg.get_method_type_info("FileBox", method_name));
if let Some(type_info) = type_info {
    for (arg, mapping) in arguments.iter().zip(&type_info.args) {
        self.encode_value_with_mapping(&mut encoder, value, mapping)?;
    }
}

🎯 Day 7本編: nyash.toml型情報管理システム実装

📋 実装の背景と価値

型情報をnyash.tomlに外部化することで

  • ソースコードが美しくなる: ハードコードされた型変換が消える
  • 読みやすさ向上: 型変換ルールが一箇所に集約
  • バグ削減: 型の不一致を事前検出可能
  • プラグイン開発効率化: 型変換を意識せず開発可能

🔧 実装順序(深く考慮した最適順)

Step 1: 型情報構造体定義 🚀
// src/bid/types.rs に追加
pub struct MethodTypeInfo {
    pub args: Vec<ArgTypeMapping>,
    pub returns: Option<String>,
}

pub struct ArgTypeMapping {
    pub name: Option<String>,
    pub from: String,  // Nyash側の型
    pub to: String,    // プラグイン期待型
}
Step 2: nyash.tomlパーサー拡張 📝
[plugins.FileBox.methods]
read = { args = [] }
write = { args = [{ from = "string", to = "bytes" }] }
open = { args = [
    { name = "path", from = "string", to = "string" },
    { name = "mode", from = "string", to = "string" }
] }
Step 3: PluginRegistryへの統合 🔌
  • 型情報をプラグインと一緒に保持
  • グローバルアクセス可能に
Step 4: 実行時型変換適用
  • execute_plugin_method_generic()で型情報参照
  • 自動的に適切なTLVエンコーディング選択
Step 5: plugin-tester型検証 🧪
  • nyash.toml読み込み
  • メソッド呼び出し前に型チェック
  • 不一致警告表示
  • 🚨 重複メソッド名チェック: Nyashは関数オーバーロード不採用
    ❌ ERROR: Duplicate method name 'read' found!
       - read() [ID: 2]
       - read(size) [ID: 7]
    Nyash does not support method overloading!
    

💡 期待される実装効果

実装前(現在のハードコード):

// メソッド名で分岐してハードコード...醜い!
if method_name == "read" && arguments.is_empty() {
    encoder.encode_i32(8192)  // ハードコード!
}
// writeは常にstring→bytes変換
encoder.encode_bytes(str_box.value.as_bytes())

実装後(美しい!):

// nyash.tomlの型情報に従って自動変換
let type_info = plugin_registry.get_method_type_info(box_name, method_name)?;
for (i, (arg, mapping)) in arguments.iter().zip(&type_info.args).enumerate() {
    encode_with_type_mapping(&mut encoder, arg, mapping)?;
}

🎯 実装の詳細設計

型変換マッピング表
Nyash型 プラグイン型 TLVタグ 変換方法
string string 6 そのまま
string bytes 7 UTF-8バイト列
integer i32 2 キャスト
bool bool 5 そのまま
array bytes 7 シリアライズ
エラーハンドリング
  • 型情報がない場合:従来通りのデフォルト動作
  • 型不一致:明確なエラーメッセージ
  • 将来の拡張性:新しい型も簡単に追加可能

🔧 残りのタスク20%

  1. plugin-testerに型情報検証機能追加

    • nyash.toml読み込み機能
    • メソッド呼び出し前の型チェック
    • 型不一致時の詳細エラー表示
  2. plugin-testerに重複メソッド名チェック追加

    • Nyashは関数オーバーロード不採用2025-08-12 AI大会議決定
    • 同一メソッド名の重複を検出
    • エラー例:
      ❌ ERROR: Duplicate method name 'read' found!
         - read() [ID: 2]
         - read(size) [ID: 7]
      Nyash does not support method overloading!
      
  3. 実動作実証とドキュメント

    • 型情報ありなしでの動作比較
    • パフォーマンス測定
    • 開発者向けガイド作成

📊 Phase 9.75g-0 全体進捗

Day タスク 完了率 状態
Day 1 BID-1基盤実装 100%
Day 2 メタデータAPI 100%
Day 3 既存Box統合 100%
Day 4 プラグインシステム基盤 100%
Day 5 実プラグイン作成・統合 100%
Day 6 動的メソッド呼び出し 100%
Day 7 型情報管理システム 80% 🔄

🎯 今後の予定

  1. 本日中2025-08-19

    • plugin-tester機能拡張完了
    • Phase 9.75g-0完全完成宣言
  2. 次期優先タスク

    • Phase 8.6: VM性能改善0.9倍→2倍以上
    • Phase 9: JIT実装
    • Phase 10: AOT最終形態

重要な技術的決定

  1. プラグイン識別: プラグインが自らBox名を宣言type_name
  2. メソッドID: 0=birth, MAX=fini、他は任意
  3. メモリ管理: プラグインが割り当てたメモリはプラグインが解放
  4. エラーコード: -1〜-5の標準エラーコード定義済み
  5. 関数オーバーロード不採用: 2025-08-12 AI大会議決定
    • 同一メソッド名で異なる引数は許可しない
    • read()read(size) は共存不可
    • プラグインもこの仕様に準拠必須