Files
hakorune/docs/reference/boxes-system/plugin_lifecycle.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

4.1 KiB
Raw Blame History

プラグインBoxのライフサイクルと nyash.toml methods 定義

本書は、プラグインBoxPluginBoxV2の生成birthと終了finiの流れ、ならびに nyash.toml v2 における methods 定義の役割をまとめたものです。


1. 用語

  • birth: プラグインBoxのインスタンス生成method_id=0
  • fini: プラグインBoxの終了処理任意の method_id。例: 4294967295
  • invoke_fn: プラグイン側の単一エントリポイント(nyash_plugin_invoke

2. 生成birthの流れ

  1. unified registryPluginLoaderV2::create_box(box_type, args) を呼び出す。
  2. PluginLoaderV2nyash.toml から type_idmethods を読み込む。
  3. invoke_fn(type_id, method_id=0 /* birth */, instance_id=0, ...) を呼び、戻り値出力TLVの先頭4バイトから instance_id を取得。
  4. PluginBoxV2 { type_id, instance_id, invoke_fn, fini_method_id } を生成して返す。

補足:

  • fini_method_idnyash.tomlmethods から finimethod_id を取り出して保持します。未定義の場合は None

3. 終了finiの流れ現状

  • フィールド差し替え時(代入で旧値を置き換えるとき):
    • 旧値が InstanceBox の場合: インタプリタが fini() を呼び、finalized としてマーキングします。
    • 旧値が PluginBoxV2 の場合: fini_method_id が設定されていれば invoke_fn(type_id, fini_method_id, instance_id, ...) を呼びます。
  • 破棄Drop時:
    • RustのDropでFFIを呼ぶのは安全性の観点でリスクがあるため、現状は「明示タイミングフィールド差し替えなど」での fini 呼び出しを優先しています。

注意:

  • ローカル変数のスコープ終了時に自動で fini を呼ぶ実装は、現時点では入っていません(将来検討)。

4. nyash.toml v2 の定義例

[libraries]
[libraries."libnyash_filebox_plugin.so"]
boxes = ["FileBox"]
path = "./plugins/nyash-filebox-plugin/target/release/libnyash_filebox_plugin.so"

[libraries."libnyash_filebox_plugin.so".FileBox]
type_id = 6

[libraries."libnyash_filebox_plugin.so".FileBox.methods]
birth = { method_id = 0 }
open  = { method_id = 1 }
read  = { method_id = 2 }
write = { method_id = 3 }
close = { method_id = 4 }
fini  = { method_id = 4294967295 } # 任意の終端ID

要点:

  • methodsfini を定義すれば、差し替え時などに fini が呼ばれます。
  • fini 未定義の場合、プラグインBoxの終了処理は呼ばれませんフォールバック動作

5. WASMwasm-bindgenとの関係

  • WASMターゲットでは libloading が使えないため、プラグイン機構は features/cfg でスタブ化しています。
  • plugins フィーチャを外す、または target_arch = "wasm32" のときは、プラグイン生成・fini 呼び出しのコードはコンパイル対象外になります(ビルド可能化のため)。

6. 将来拡張の方向

  • ローカル変数のスコープ終了時(関数/メソッド呼び出しの戻りなどに、InstanceBox/PluginBoxV2 の fini を安全に呼び出す仕組み(順序・例外耐性・二重呼び出し防止を含む)。
  • nyash.toml にクラス名→プラグインBox型の overrides を加え、ユーザー定義Boxの外部置換を許可する設計任意

以上。


7. v2.1: BoxRefBox引数サポート

目的: プラグインメソッドの引数として、他のBoxインスタンスを不透明参照で受け渡し可能にする。

  • 仕様詳細: docs/reference/plugin-system/nyash-toml-v2_1-spec.md
  • 設定例1引数にプラグインBoxを渡す:
[libraries."libnyash_filebox_plugin.so".FileBox.methods]
copyFrom = { method_id = 7, args = [ { kind = "box", category = "plugin" } ] }

注意:

  • 当面は category = "plugin" のみ対応。ユーザー定義Boxや複雑なビルトインBoxは非対応。
  • 戻り値の BoxRef は次版v2.2)で検討。