2025-08-20 05:57:18 +09:00
|
|
|
|
# プラグインBoxのライフサイクルと nyash.toml methods 定義
|
|
|
|
|
|
|
|
|
|
|
|
本書は、プラグインBox(PluginBoxV2)の生成(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 registry` が `PluginLoaderV2::create_box(box_type, args)` を呼び出す。
|
|
|
|
|
|
2. `PluginLoaderV2` は `nyash.toml` から `type_id` と `methods` を読み込む。
|
|
|
|
|
|
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_id` は `nyash.toml` の `methods` から `fini` の `method_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 の定義例
|
|
|
|
|
|
|
|
|
|
|
|
```toml
|
|
|
|
|
|
[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
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
要点:
|
|
|
|
|
|
- `methods` に `fini` を定義すれば、差し替え時などに fini が呼ばれます。
|
|
|
|
|
|
- `fini` 未定義の場合、プラグインBoxの終了処理は呼ばれません(フォールバック動作)。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. WASM(wasm-bindgen)との関係
|
|
|
|
|
|
- WASMターゲットでは `libloading` が使えないため、プラグイン機構は features/cfg でスタブ化しています。
|
|
|
|
|
|
- `plugins` フィーチャを外す、または `target_arch = "wasm32"` のときは、プラグイン生成・fini 呼び出しのコードはコンパイル対象外になります(ビルド可能化のため)。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 将来拡張の方向
|
|
|
|
|
|
- ローカル変数のスコープ終了時(関数/メソッド呼び出しの戻りなど)に、InstanceBox/PluginBoxV2 の fini を安全に呼び出す仕組み(順序・例外耐性・二重呼び出し防止を含む)。
|
|
|
|
|
|
- `nyash.toml` にクラス名→プラグインBox型の `overrides` を加え、ユーザー定義Boxの外部置換を許可する設計(任意)。
|
|
|
|
|
|
|
|
|
|
|
|
以上。
|
2025-08-21 00:41:26 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. v2.1: BoxRef(Box引数)サポート
|
|
|
|
|
|
|
|
|
|
|
|
目的: プラグインメソッドの引数として、他のBoxインスタンスを不透明参照で受け渡し可能にする。
|
|
|
|
|
|
|
|
|
|
|
|
- 仕様詳細: `docs/reference/plugin-system/nyash-toml-v2_1-spec.md`
|
|
|
|
|
|
- 設定例(1引数にプラグインBoxを渡す):
|
|
|
|
|
|
|
|
|
|
|
|
```toml
|
|
|
|
|
|
[libraries."libnyash_filebox_plugin.so".FileBox.methods]
|
|
|
|
|
|
copyFrom = { method_id = 7, args = [ { kind = "box", category = "plugin" } ] }
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
注意:
|
|
|
|
|
|
- 当面は `category = "plugin"` のみ対応。ユーザー定義Boxや複雑なビルトインBoxは非対応。
|
|
|
|
|
|
- 戻り値の BoxRef は次版(v2.2)で検討。
|