Phase 12: 統一TypeBox ABI実装開始 - ChatGPT5による極小コアABI基盤構築

- TypeBox ABI雛形: メソッドスロット管理システム追加
- Type Registry: Array/Map/StringBoxの基本メソッド定義
- Host API: C ABI逆呼び出しシステム実装
- Phase 12ドキュメント整理: 設計文書統合・アーカイブ化
- MIR Builder: クリーンアップと分離実装完了

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm
2025-09-03 05:04:56 +09:00
parent e2e25f6615
commit 53d88157aa
84 changed files with 4739 additions and 2750 deletions

View File

@ -0,0 +1,87 @@
# Nyash ABI戦略議論まとめ (2025-09-01)
## 📋 概要
Phase 12のプラグインシステム実装において、C ABIとNyash ABIの選択について、AI先生方と深い技術議論を行いました。
## 🗂️ ドキュメント一覧
1. **[gemini-abi-analysis.md](gemini-abi-analysis.md)**
- Gemini先生の長期エコシステム視点
- ABI安定性の重要性
- 段階的進化戦略C ABI → SDK → WASM
2. **[codex-abi-implementation.md](codex-abi-implementation.md)**
- Codex先生の実装最適化視点
- C呼出規約×Nyash値表現の提案
- VM/JIT最適化の具体策
3. **[deep-analysis-synthesis.md](deep-analysis-synthesis.md)**
- なぜ正解が難しいのかの深い分析
- 時間軸のジレンマ
- 「正解がない」ことが答え
## 🎯 結論BoxCall拡張による統合案
### 最終的な実装方針
```rust
// MIRレベルBoxCallをちょっと拡張
MirInstruction::BoxCall {
receiver: Value,
method: String,
args: Vec<Value>,
abi_hint: Option<AbiType>, // ← これだけ追加
}
```
### 利点
1. **MIR命令数は15個のまま**(美しさ維持)
2. **既存コードは変更不要**(後方互換)
3. **プラグインごとにABI選択可能**(段階的移行)
4. **Everything is Box哲学の体現**
### 実装計画
```yaml
Week 1: 基盤整備
- PluginABI enum定義
- nyash.tomlのabi field追加
- NyashValue構造体作成
Week 2: VM統合
- プラグインローダー拡張
- VM実行時のABI分岐
- pack/unpack実装
Week 3: 検証
- 比較ベンチマーク
- ドキュメント作成
- 方向性判断
```
## 🔑 重要な洞察
1. **両ABI共存が現実的**
- C ABI既存資産・高速・安定
- Nyash ABI型安全・拡張性・将来性
2. **適応的戦略の採用**
- 3ヶ月ごとに測定・評価
- データに基づく進化
3. **箱理論による差し替え可能性**
- 実装を箱に切り出す
- いつでも戻せる安心感
## 📊 次のステップ
1. このREADMEを起点に実装開始
2. 最小限のプロトタイプ作成
3. 性能・開発体験の比較データ収集
4. Phase 12本実装への反映
---
*「間に挟むだけ」が最も難しい設計判断だった。しかし、BoxCall拡張という自然な解決策にたどり着いた。*

View File

@ -0,0 +1,124 @@
# Codex先生のNyash ABI実装戦略 (2025-09-01)
## 質問内容
Nyashプラグインシステムの ABI戦略について技術的相談です。
【背景】
Phase 12でNyashスクリプトプラグインシステムを実装中です。現在、プラグインインターフェースの設計で重要な判断が必要です。
【現状】
- 既存: C ABIシンプル、高速、実績あり
- 提案: Nyash ABI3×u64構造体、型情報付き、拡張性高い
【トレードオフ】
C ABI:
- 利点: ゼロオーバーヘッド、既存資産活用、シンプル
- 欠点: 型情報なし、拡張性限定、エラー処理が原始的
Nyash ABI:
- 利点: 型安全、メタデータ活用、将来性async等
- 欠点: pack/unpackのオーバーヘッド、新規学習コスト
【具体的な選択肢】
1. Nyash ABIのみ統一性重視
2. C ABI + Nyash ABI両方実用性重視
3. その他の革新的アプローチ?
【質問】
1. どちらの戦略が長期的に見て賢明でしょうか?
2. 両方サポートする場合の複雑性は管理可能でしょうか?
3. 他の言語での成功例・失敗例から学べることは?
4. VM/JIT最適化の観点から、どちらが有利でしょうか
実装の実践的観点から、C ABIとNyash ABIの選択について深く分析してください。特にVM/JIT最適化や実装の複雑性を考慮して。
## Codex先生の回答
**結論**
- 長期的には「C呼出規約 × Nyash値表現3×u64」を中核に、C ABIとNyash ABIの両方をサポートする二層戦略が最も堅実。
- まずは二者併存で運用し、JIT/VMでの最適化余地と実用性を確保しながら、将来的にNyash ABIを第一級に育てるのが現実的。
**推奨戦略**
- 両対応2を採用。ただし"呼出規約はC、値表現はNyash"を共通土台にする。
- 共通の値ABI: `#[repr(C)] struct NyValue { u64 tag; u64 payload; u64 aux; }`
- C ABI関数でもNyValueを受け渡しできるため、型安全・メタデータ拡張の道を確保しつつ、Cの安定性・高速性を得る。
- プラグイン初期化は「バージョン付き関数テーブルvtable機能フラグ」の交渉型にする。
- 例: `NyPluginInitV1(NyRtFnsV1* rt, NyPluginV1* out)``NyPluginV1 { u32 abi_mask; u32 size; NyFnDesc* fns; ... }`
- `abi_mask``NY_ABI_C``NY_ABI_NYV1` の両方可否を示す。将来の `NY_ABI_NYV2` も追加可能。
- エラーモデルは二段階:
- 速経路: `NyStatus`enum, small intを戻す。失敗時は`NyValue`でエラーオブジェクトをout-param返却。
- 詳細情報は`NyError`ヘルパ(`NyValue`として表現に格納。FFI境界でpanic禁止・例外横断なし。
- メモリ/所有権はハンドル/関数テーブル経由で統一NyRTのalloc/free、string/slice作成API。内部構造体への直接依存は不可。
**複雑性と管理**
- 追加コストは主にローダとアダプタ(トランポリン)実装+テスト行列の増加。ただし次の工夫で管理可能:
- 機能交渉を一本化init関数とマニフェスト/nyash.tomlで表明。ロード時に一度だけ決定。
- 呼出アダプタをテンプレート化JIT時に生成・キャッシュ型配列→シグネチャ→thunkアドレス
- 型表(`NyFnDesc`に引数/戻りの型ID配列、純関数/readonly/aliasing属性を持ち、最適化と検証を兼用。
- 見積りローダvtableアダプタの骨格は数百行〜千行弱で収まり、以降は関数種別追加が足し算。
**他言語の事例からの学び**
- 成功例
- Node N-API: バージョン化された関数テーブルでABIを安定化。実装側の進化と互換の両立に有効。
- Lua C API: C呼出規約独自値表現で長期安定。ただしstackベースは学習コストあり。
- 反省点
- CPython C API: 内部構造体露出で進化の足枷に。HPyはハンドル化で再設計。
- JNI: 汎用だが冗長・低速傾向。最適化しづらい。
- 教訓
- 内部レイアウト非公開(ハンドル/関数経由・バージョン化vtable・拡張フラグが長期安定の鍵。
- 値ABIは固定サイズ・レジスタ渡し最適化可能な形が吉3×u64は合理的
**VM/JIT最適化の観点**
- 呼出オーバーヘッド
- 3×u64はSysV/Win64いずれもレジスタ渡しが効きやすく、C ABIと同等のコールコストに収束。
- 本質的ボトルネックは間接呼出ミス予測と型検査。JITで型が既知ならチェックを埋め込み/削減可能。
- 直呼 vs トランポリン
- 署名が一致する場合は直接呼出JITに外部シンボルとして登録
- 型昇降/借用が必要な時のみthunkを噛ませる。JITでモモーフィック化・デッドパス除去。
- 最適化ヒントCranelift/LLVM
- 関数属性: `nounwind`, `readonly`/`readnone`, `nocapture`, `nonnull`, `cold`(エラーパス)
- 戻り値はout-paramにしてtailcall最適化`musttail`適用可否は要検証)。
- シンボルはAOT時`dso_local`、JITは`CallConv::SystemV/WindowsFast`で3×i64に整合。
- ホットループ対策
- スカラー跨ぎは避け、スライス/バルクAPIを定義例: vector add。boundary跨ぎ回数を削減。
- 将来は静的リンクモードfirst-party pluginsでLTO許可→AOTでインライン・DCE可。
**Nyash ABIのみ vs 併存の比較**
- Nyash ABIのみ1
- 一貫性と将来性は高いが、既存C資産/ツール連携コストと立上げ摩擦が大きい。
- 併存2, 推奨)
- 早期エコシステム拡大と最適化の両取り。複雑性はvtableアダプタの設計で抑え込み可能。
- その他3
- N-API風ハンドル専一は安定するが、オーバーヘッド/冗長性が増える。Nyashのパフォーマンス志向には過剰。
**実装メモ(具体)**
- 値ABI
- `tag`: 上位ビットに種別・フラグown/borrow、small/heap、nullable等
- `payload`: ポインタor即値、`aux`: len/stride/arena_id等
- `NySlice`: `tag=SLICE``payload=ptr`, `aux=len`。borrow時は生存期間制約、必要なら`nyrt_clone_slice`で所有権取得。
- 初期化/交渉
- `NyPluginInitV1(NyRtFnsV1*, NyPluginV1*) -> NyStatus`
- `NyRtFnsV1`: alloc/free、string/slice/future、log、error造作API。
- `NyPluginV1`: `abi_mask`, `size`, `features`, `fn_count`, `NyFnDesc*`.
- エラー/非同期
- `NyStatus` + `NyValue err_out`。非同期は `NyFuture*`を返却、`NyRtFnsV1``poll/wake`を橋渡し。
- VMのスケジューラとWakerのブリッジはvtableで隠蔽ABI非依存
- 安定性
- すべての公開構造体に`size`を先頭フィールドに持たせ将来拡張。未理解フィールドは無視。
- ABIバージョンは数値機能フラグで条件分岐ビルド時にも`#[cfg(feature)]`で絞る)。
**質問への回答**
- 1) 長期的に賢明か: 併存共通値ABIが最善。Cの互換性とNyashの型安全/拡張性を両立。
- 2) 複雑性は管理可能か: はい。vtableの一本化、JIT生成thunk、機能交渉で抑制できる。
- 3) 学び: 内部構造体を外部に晒さない・ハンドル経由・バージョン化テーブル・豊富な属性メタデータ。CPythonの反省とN-APIの成功を取り込む。
- 4) VM/JIT最適化: 3×u64のNyash値はレジスタ渡しでC ABIと同等に速く、型既知箇所はJITで直呼/チェック省略可能。最適化の自由度はNyash ABIの方が高い。
**次のアクション**
- 値ABIと関数テーブル仕様を`crates/nyrt/include/nyrt.h`に最小ドラフト化(`NyValue`, `NyStatus`, `NyRtFnsV1`, `NyPluginV1`, `NyFnDesc`)。
- ローダにinit/交渉実装(`nyash.toml`のabi種別・型情報読み込み→関数登録
- JIT/VMに外部関数署名登録とthunk生成を追加Cranelift/LLVM兼用
- バルク演算プラグインのスモークを作成C ABI版とNyash ABI版を比較ベンチ
- ドキュメント化(`docs/plugins/abi.md`)とサンプル(`plugins/``apps/`)追加。
必要なら、ドラフトの`NyValue``NyPluginInitV1`の最小Cヘッダ案もすぐ出します。

View File

@ -0,0 +1,188 @@
# Codex先生のBoxCall拡張分析 (2025-09-01)
## 質問内容
Nyash ABI実装の具体的アプローチについて技術相談です。
【背景】
前回の議論で、C ABIとNyash ABIの両方をサポートする方向性が見えました。実装方法について新しいアイデアがあります。
【BoxCall拡張による統合案】
MIR命令を増やさず、既存のBoxCallを自然に拡張する案です
```rust
// 現在のBoxCall
MirInstruction::BoxCall {
receiver: Value,
method: String,
args: Vec<Value>,
}
// 提案:最小限の拡張
MirInstruction::BoxCall {
receiver: Value,
method: String,
args: Vec<Value>,
abi_hint: Option<AbiType>, // 追加
}
```
【実装の流れ】
1. MIRビルダープラグインBoxならABIヒント付与
2. VM実行時receiver.type_idから適切なABI選択
3. プラグインローダーnyash.tomlでABI指定可能
【この案の利点】
- MIR命令数は15個維持Everything is Box哲学
- 既存コード無変更(後方互換)
- プラグインごとに段階的移行可能
- JITでABI別最適化も可能
【質問】
1. このBoxCall拡張案は設計として健全でしょうか
2. abi_hintは本当に必要VM実行時の型判定で十分
3. 将来的な拡張WASM等にも対応できる設計か
4. パフォーマンス影響をどう評価すべきか?
実装の観点から、MIR層でのabi_hint追加とVM層でのABI判定について深く分析してください。特に既存実装への影響を最小化する方法を考慮して。
## Codex先生の回答
### コードベース分析
まず、現在のMIR/VM実装を確認
```rust
// 現在のMirInstruction::BoxCall定義
BoxCall {
dst: Option<ValueId>,
box_val: ValueId,
method: String,
method_id: Option<u16>, // Universal method用
args: Vec<ValueId>,
effects: EffectMask,
}
```
プラグインローダーはすでにnyash.tomlから型情報を読み込んでおり、VM実行時に利用可能。
### 核心的な洞察
**abi_hintは実は不要かもしれない**
理由:
1. VM実行時にreceiver.type_idから型情報を取得可能
2. プラグインローダーが既にABI情報を保持している
3. MIR層を変更せずに済む15命令維持
### 実装提案
#### Option A: 最小限実装MIR無変更
```rust
// VM層での実装
fn execute_boxcall(&mut self, dst: Option<ValueId>, box_val: ValueId, method: &str, args: &[ValueId]) -> Result<ControlFlow, VMError> {
let receiver = self.get_value(box_val)?;
let type_id = receiver.get_type_id();
// プラグインローダーから型情報取得
if let Some(plugin_info) = self.runtime.get_plugin_info(type_id) {
match plugin_info.abi.as_str() {
"c" => self.call_c_abi_plugin(plugin_info, method, args),
"nyash" => self.call_nyash_abi_plugin(plugin_info, method, args),
_ => self.call_c_abi_plugin(plugin_info, method, args), // fallback
}
} else {
// ビルトインBox処理既存のまま
self.execute_builtin_method(receiver, method, args)
}
}
```
#### Option B: 将来の拡張性を考慮
```rust
// MIRに汎用メタデータ追加ABIに限定しない
MirInstruction::BoxCall {
receiver: Value,
method: String,
args: Vec<Value>,
metadata: Option<u32>, // 汎用的な最適化ヒント
}
```
### JIT/AOT最適化の観点
```rust
// JIT時の特化
match type_info.abi {
Some("c") => {
// 直接call命令生成
builder.emit_direct_call(symbol, args);
}
Some("nyash") => {
// NyashValue pack/unpackを含めてインライン化
let packed = builder.emit_pack_nyash_values(args);
builder.emit_call_with_abi(symbol, packed);
}
_ => {
// 汎用パスVM呼び出し
builder.emit_vm_boxcall(receiver, method, args);
}
}
```
### パフォーマンス評価方法
```rust
// ベンチマーク設計
fn benchmark_abi_comparison() {
// 1. 高頻度呼び出しmath operations
measure_time("C ABI", || {
for _ in 0..1_000_000 {
math_add_c_abi(1.0, 2.0);
}
});
measure_time("Nyash ABI", || {
for _ in 0..1_000_000 {
math_add_nyash_abi(pack(1.0), pack(2.0));
}
});
// 2. 複雑な型string operations
// 3. プラグイン初期化コスト
}
```
### 結論と推奨事項
1. **abi_hintは不要** - VM実行時の型判定で十分
2. **MIR層は無変更** - 15命令の美しさ維持
3. **将来拡張は型システム経由** - WASMもプラグイン型として追加
4. **段階的実装**
- Week 1: nyash.toml拡張 + VM分岐
- Week 2: ベンチマーク + 最適化
- Week 3: JIT特化必要なら
### 実装の具体的ステップ
```yaml
Step 1: nyash.toml拡張
- LibraryDefinition に abi: Option<String> 追加
- デフォルトは "c"
Step 2: プラグインローダー
- PluginInfo 構造体に abi フィールド追加
- ロード時に保存
Step 3: VM execute_boxcall
- 型判定でABI分岐
- call_c_abi / call_nyash_abi メソッド追加
Step 4: テスト
- 同一機能の C/Nyash 両実装
- 性能比較測定
```
この最小限アプローチなら、既存コードへの影響を最小化しつつ、将来の拡張性も確保できます。

View File

@ -0,0 +1,164 @@
# Nyash ABI戦略の深い分析 - なぜ正解が難しいのか (2025-09-01)
## 🤔 両先生の回答から見えた根本的な難しさ
### 1. 時間軸のジレンマ
**Gemini先生の視点**(長期エコシステム):
- 10年後も動くプラグインを作りたい
- 破壊的変更は絶対避けたい
- 開発者の信頼が最重要
**Codex先生の視点**(現実的最適化):
- 今すぐ高速に動かしたい
- JIT/VMの最適化余地を残したい
- 実装の複雑性を抑えたい
**この2つは本質的に矛盾する**
### 2. 抽象化レベルの選択
```
高レベル抽象化Gemini案
SDK層
C ABI安定境界
vs
低レベル統合Codex案
共通値表現3×u64
C呼出規約で統一
```
どちらが正解? **状況による!**
### 3. 隠れた複雑性の罠
**表面的には単純に見える選択**
- C ABI only → シンプル!
- Nyash ABI only → 統一的!
- 両方サポート → 柔軟!
**実際の複雑さ**
- C ABI only → 型情報なし、拡張困難
- Nyash ABI only → 既存資産切り捨て
- 両方サポート → **複雑性が2倍...ではなく4倍**
### 4. なぜ複雑性が爆発するのか
```
組み合わせ爆発:
- 2つのABI ×
- 3つのバックエンドInterpreter/VM/JIT ×
- N個のプラグイン型 ×
- M個の最適化レベル
= 指数関数的複雑性
```
## 🎯 深い洞察:本当の問題は何か
### 技術的正解 vs ビジネス的正解
**技術的に美しい解**
- Nyash ABI一本化
- 型安全、拡張可能、統一的
**ビジネス的に賢い解**
- C ABI + 段階的移行
- 既存資産活用、リスク分散
**どちらも「正解」であり「不正解」**
### 隠れた第3の選択肢
両先生が暗黙的に示唆している:
```
時期による使い分け:
Phase 1: C ABIで素早くエコシステム立ち上げ
Phase 2: SDK層で開発体験向上
Phase 3: Nyash ABIで技術的優位性確立
Phase 4: 統合または選択的廃止
```
## 💡 究極の洞察:「正解がない」ことが答え
### なぜ正解が難しいのか
1. **未来は予測不可能**
- NyashがRustを超えるか
- WASMが世界標準になるか
- 新しいABI標準が生まれるか
2. **トレードオフは価値観次第**
- 速度 vs 安全性
- シンプル vs 機能性
- 互換性 vs 革新性
3. **成功の定義が人による**
- 多くのプラグイン?
- 高速な実行?
- 美しいコード?
## 🚀 実践的な答え:適応的戦略
### 推奨アプローチ
```rust
// 初期実装:両対応だが内部統一
enum PluginABI {
C(CPlugin), // 既存資産
Nyash(NyashPlugin), // 新規開発
}
// 共通インターフェース
trait Plugin {
fn invoke(&self, args: &[Value]) -> Result<Value>;
}
// 将来の拡張ポイント
impl PluginABI {
fn optimize_for_jit(&self) -> Option<DirectCall> {
// JIT時に最適化可能なら直接呼び出しに変換
}
}
```
### 段階的進化の道筋
1. **観察期間**6ヶ月
- 両ABI並行運用
- 使用パターン分析
- パフォーマンス測定
2. **最適化期間**次の6ヶ月
- 頻出パターンの高速化
- SDK層の洗練
- ドキュメント充実
3. **判断期間**1年後
- データに基づく選択
- 片方を非推奨に?
- それとも永続的共存?
## 🌟 結論:「正解がない」を受け入れる勇気
**Nyashの哲学**
- Everything is Box → Everything has Trade-offs
- 完璧より進捗80/20ルール
- 箱理論で差し替え可能に
**最終提案**
1. 両方実装するが、**内部アーキテクチャは統一**
2. **測定可能な成功指標**を先に定義
3. **3ヶ月ごとに振り返り**、方向修正
正解がないからこそ、**適応し続けることが正解**。
---
*「間に挟むだけ」のABI層が、実は最も難しい設計判断の一つだった。*

View File

@ -0,0 +1,121 @@
# BoxCall拡張によるABI戦略 - 最終実装決定 (2025-09-01)
## 🎯 両先生の回答から得た重要な洞察
### Gemini先生の誤解が示す重要な点
- 先生は「BoxCall = Box<dyn Trait>を渡す」と誤解
- しかし、この誤解が**abi_stable**の重要性を教えてくれた
- 将来的にRustトレイトオブジェクトを扱う際の指針に
### Codex先生の実践的分析
1. **abi_hintは実は不要かもしれない**
- VM実行時にtype_idから判定可能
- プラグインローダーが型情報を保持
- MIR層を汚さない
2. **既存実装への影響最小化**
- TypeMetaにABI情報を含める
- nyash.tomlから読み込み済み
- VM側で判定するだけ
## 🚀 最終実装方針
### Option A: 最小限実装(推奨)
```rust
// MIR層変更なし
MirInstruction::BoxCall {
receiver: Value,
method: String,
args: Vec<Value>,
// abi_hint不要
}
// VM層型判定でABI選択
fn execute_boxcall(...) {
let type_id = receiver.get_type_id();
// プラグインローダーから型情報取得
if let Some(plugin_info) = get_plugin_info(type_id) {
match plugin_info.abi {
"c" => call_c_abi(...),
"nyash" => call_nyash_abi(...),
_ => fallback_to_c_abi(...),
}
}
}
```
### Option B: 明示的ヒント(将来の拡張性)
```rust
// MIR層最小限の拡張
MirInstruction::BoxCall {
receiver: Value,
method: String,
args: Vec<Value],
metadata: Option<u32>, // 汎用メタデータABIヒント含む
}
```
## 📊 比較表
| 観点 | Option A最小限 | Option Bヒント付き |
|------|------------------|---------------------|
| MIR変更 | なし ✅ | 最小限 |
| 実装工数 | 1週間 | 2週間 |
| JIT最適化 | VM時判定 | ビルド時判定可能 |
| 将来拡張 | 型情報経由 | メタデータ活用 |
## 🎯 結論Option Aで始める
### 理由
1. **80/20ルール**: まず動くものを作る
2. **MIR無変更**: 15命令の美しさ維持 → さらに14命令へPluginInvoke統合
3. **段階的進化**: 必要になったらOption Bへ
### Phase 12での追加統合
- **PluginInvoke → BoxCall 完全統合**
- ビルトインBox廃止により区別が不要
- VM層でのABI判定で十分
- Core-15 → Core-14 への削減
### 実装ステップ1週間
```yaml
Day 1-2: nyash.toml拡張
- abi: "c" | "nyash" field追加
- プラグインローダー対応
Day 3-4: VM実行時分岐
- execute_boxcall内でABI判定
- NyashValue pack/unpack実装
Day 5-6: テスト・ベンチマーク
- 同一機能の2種類プラグイン
- 性能比較測定
Day 7: 判断
- データに基づく方向性決定
- Option B移行の必要性評価
```
## 💡 深い洞察
**「abi_hintは不要」という発見が示すもの**
- 型システムが既に十分な情報を持っている
- MIRは純粋な意図の表現で良い
- 実行時の賢い判断に任せる
これこそ「Everything is Box」の真髄 - Boxが自分の実装方法を知っている
## 🚀 次のアクション
1. nyash.tomlパーサーに`abi` field追加
2. プラグインローダーでABI情報保持
3. VM execute_boxcallで分岐実装
4. 最小限のテストプラグイン作成
---
*最小限から始めて、データで判断する。これがNyashの道。*

View File

@ -0,0 +1,179 @@
# Gemini先生のNyash ABI戦略分析 (2025-09-01)
## 質問内容
Nyashプラグインシステムの ABI戦略について技術的相談です。
【背景】
Phase 12でNyashスクリプトプラグインシステムを実装中です。現在、プラグインインターフェースの設計で重要な判断が必要です。
【現状】
- 既存: C ABIシンプル、高速、実績あり
- 提案: Nyash ABI3×u64構造体、型情報付き、拡張性高い
【トレードオフ】
C ABI:
- 利点: ゼロオーバーヘッド、既存資産活用、シンプル
- 欠点: 型情報なし、拡張性限定、エラー処理が原始的
Nyash ABI:
- 利点: 型安全、メタデータ活用、将来性async等
- 欠点: pack/unpackのオーバーヘッド、新規学習コスト
【具体的な選択肢】
1. Nyash ABIのみ統一性重視
2. C ABI + Nyash ABI両方実用性重視
3. その他の革新的アプローチ?
【質問】
1. どちらの戦略が長期的に見て賢明でしょうか?
2. 両方サポートする場合の複雑性は管理可能でしょうか?
3. 他の言語での成功例・失敗例から学べることは?
4. VM/JIT最適化の観点から、どちらが有利でしょうか
## Gemini先生の回答
### NyashプラグインシステムにおけるABI戦略の技術的考察
Nyashプラグインシステムの長期的なエコシステム発展を見据えたABIApplication Binary Interface戦略について、深く技術的に考察します。
### 1. ABI安定性の重要性エコシステム成功の礎
プラグインシステムの成功は、**ABIの鉄壁の安定性**にかかっています。ホストアプリケーションNyashとプラグインは、別々にコンパイル・配布されるバイナリです。両者が正しく協調動作できるのは、関数呼び出し規約、データ型表現、メモリアロケーションといった低レベルな規約、すなわちABIが厳密に一致しているからです。
もしNyashのバージョンアップでABIに破壊的変更が生じれば、既存の全プラグインは動作しなくなり、再コンパイルが必要になります。これはエコシステムにとって致命的です。開発者は追従を諦め、ユーザーはプラグインが使えなくなることを恐れてNyashのアップデートをためらうでしょう。
したがって、ABI戦略の最優先目標は**「前方互換性新しいNyashが古いプラグインを動かせると、可能な限りの後方互換性古いNyashが新しいプラグインの機能を限定的にでも利用できる」**を保証することです。
### 2. 現状の分析と潜在的リスク
現在のNyashのコードベースを調査し、プラグイン関連の実装を特定する必要があります。`Cargo.toml`やソースコードから、おそらくRustのダイナミックライブラリ`.so`, `.dll`, `.dylib`)を動的に読み込む形式が採用されていると推測されます。
ここで最も警戒すべきは、**Rust固有のABIに依存することのリスク**です。Rustコンパイラは、パフォーマンス最適化のために、構造体のメモリレイアウトや関数呼び出し規約をバージョン間で予告なく変更します。したがって、`extern "Rust"`(デフォルト)の関数をプラグイン境界として公開するのは、エコシステムの観点からは**絶対に避けなければなりません**。
素晴らしい検索結果から、Nyashはすでに `extern "C"` を広範囲に利用していることが明確にわかります。これは非常に良い出発点です。`plugin_loader_v2.rs``bid/plugin_api.rs` などを見ると、プラグインの初期化(`nyash_plugin_init`)や関数呼び出し(`invoke_fn`のシグネチャがC ABIで定義されています。
これは、ABI安定性に対する基本的な理解がプロジェクトに既に存在することを示しています。しかし、長期的なエコシステムを築くには、これをさらに推し進め、より洗練された戦略を立てる必要があります。
### 3. 長期的な発展のためのABI戦略提案
現在の `extern "C"` ベースのアプローチを基礎としつつ、以下の戦略を段階的に導入することを提案します。
#### 戦略1C ABIを「公式な安定境界」として厳格に定義・文書化する
これは最も重要です。`extern "C"` を使っているというだけでは不十分で、それを**公式な規約**として確立する必要があります。
**具体的なアクション:**
1. **ABI仕様書の作成:**
- `nyash-abi.h`のようなCヘッダーファイル形式で、プラグインが実装すべき関数シグネチャと、Nyashが提供するホスト関数コールバックをすべて定義します。
- `invoke_fn` で使われている `*const u8`, `*mut u8` のようなバイトポインタが、具体的にどのようなデータを指すのか(シリアライズ形式、レイアウトなど)を厳密に文書化します。
- `NyashHostVtable` のような構造体は、フィールドの順序と型が未来永劫変わらないことを保証しなければなりません。新しいホスト関数を追加する場合は、末尾にのみ追加します。
- エラー報告の規約(戻り値の `i32` が何を意味するのか)を定義します。
2. **FFIForeign Function Interface層の明確化:**
- Nyash内部のRustコードと、C ABI境界を明確に分離します。`plugin_loader_v2.rs` はこの役割を担っているようですが、この層は「ABI変換」にのみ責任を持つべきです。内部的なリファクタリングがABIに影響を与えないようにします。
**利点:**
- **言語非依存:** C ABIはあらゆる主要言語C++, Zig, Go, Python, etc.)から利用可能で、プラグイン開発者の裾野を広げます。
- **究極の安定性:** C ABIは数十年にわたり安定しています。
**欠点:**
- **表現力の低さ:** Rustの`Result``Option`、ライフタイムといった豊かな型情報を直接渡せず、`i32`のエラーコードやポインタのNULLチェックといったプリミティブな方法に頼らざるを得ません。
- **手作業と`unsafe`:** データのシリアライズ・デシリアライズやポインタ操作が必須となり、`unsafe`コードが増え、バグの温床になりやすいです。
#### 戦略2高レベルな「Rust向けラッパーSDK」を提供する
C ABIの欠点を補うため、プラグイン開発者が直接C ABIを触らなくても済むように、公式のRust製SDKクレートを提供します。
**具体的なアクション:**
1. **`nyash-plugin-sdk` クレートの作成:**
- このSDKは、低レベルなC ABIのやり取りをすべてカプセル化します。
- プラグイン開発者は、`Result<MyData, MyError>` のような自然なRustの型を扱うだけで、SDKが自動的にC ABI準拠のデータバイト列やエラーコードとの相互変換を行います。
- 定型的なコードを自動生成するマクロ(例: `#[nyash_plugin]`)を提供し、開発体験を向上させます。
**SDK利用者のコードイメージ:**
```rust
// プラグイン開発者が書くコード
use nyash_plugin_sdk::{plugin, NyashResult, NyashError};
struct MyPlugin;
#[plugin]
impl Plugin for MyPlugin {
fn handle_request(&self, input: &str) -> NyashResult<String> {
if input == "hello" {
Ok("world".to_string())
} else {
Err(NyashError::new("Invalid input"))
}
}
}
```
**SDK内部の実装イメージ:**
```rust
// #[plugin] マクロが生成するコード
#[no_mangle]
pub unsafe extern "C" fn nyash_plugin_invoke(
/* C ABI引数 */
) -> i32 {
// 1. C ABIのバイト列から &str へデシリアライズ
// 2. MyPlugin::handle_request を呼び出し
// 3. 結果の Result<String, NyashError> をC ABIのエラーコードとバイト列にシリアライズ
// 4. 結果を返す
// ... この部分はSDKが隠蔽する ...
}
```
**利点:**
- **高い開発者体験:** Rust開発者は、安全で慣用的なRustコードを書くことに集中できます。
- **安全性の向上:** `unsafe`コードをSDKに集約させることで、プラグイン開発者がメモリ安全性を破壊するリスクを大幅に低減できます。
#### 戦略3データ交換フォーマットの標準化
`invoke_fn` でやり取りされる `*const u8` の中身を標準化します。これにより、堅牢性と前方互換性が向上します。
**候補:**
- **Protocol Buffers / FlatBuffers:**
- **利点:** スキーマ定義が明確で、前方・後方互換性を考慮した設計が容易。多言語対応のコード生成ツールが豊富。パフォーマンスも高い。
- **欠点:** ビルドプロセスに一手間加わる。
- **JSON / MessagePack:**
- **利点:** 動的で柔軟。デバッグが容易。
- **欠点:** スキーマがないため、実行時エラーになりやすい。シリアライズ・デシリアライズのオーバーヘッドが比較的多きい。
**推奨:**
長期的なエコシステムの安定性を考えると、スキーマベースの **Protocol Buffers** または **FlatBuffers** が最適です。
#### 戦略4WebAssembly (Wasm) の採用検討
究極の目標として、プラグインをWebAssemblyモジュールとして実行する方式を検討する価値があります。
**利点:**
- **サンドボックス化:** WasmランタイムWasmtimeなど上でプラグインを実行することで、Nyash本体から完全に隔離された安全な環境を提供できます。悪意のあるプラグインやバグのあるプラグインがホストをクラッシュさせるのを防ぎます。
- **真の言語非依存:** C ABIよりもさらに多くの言語コンパイルターゲットにWASIを持つものがプラグイン開発に利用可能になります。
- **WASIとコンポーネントモデル:** WASIWebAssembly System InterfaceやWasm Component Modelの標準化が進むことで、ファイルアクセスやネットワークなどのホスト機能へのアクセスが標準化され、より洗練されたABIを構築できます。
**欠点:**
- **パフォーマンスオーバーヘッド:** C ABIのダイナミックライブラリ呼び出しに比べ、Wasmランタイムを介在させることによるオーバーヘッドが存在します。
- **実装の複雑さ:** Wasmランタイムの組み込みと、ホスト・ゲスト間のデータ共有特に複雑なデータ構造の実装は複雑になります。
### まとめと提言
Nyashは `extern "C"` の採用により、ABI安定化への正しい一歩を踏み出しています。長期的なエコシステムの繁栄のため、以下のロードマップを提案します。
1. **短期(すぐ着手すべき):**
- **C ABIの公式化:** `nyash-abi.h`相当の仕様を定義し、文書化する。
- **データフォーマットの選定:** `invoke_fn` で交換されるデータのシリアライズ形式としてProtocol Buffers等を導入する。
2. **中期(エコシステムの成長期):**
- **Rust向けSDKの提供:** `nyash-plugin-sdk` クレートを開発し、Rust開発者の体験を向上させる。
- **他言語向けSDKの提供:** 需要に応じて、PythonやGo向けのラッパーライブラリを提供する。
3. **長期(未来のビジョン):**
- **WebAssemblyへの移行:** パフォーマンス要件とセキュリティ要件を天秤にかけ、プラグイン実行環境をWasmに移行することを検討する。これにより、究極の安全性と移植性を獲得できる。
この戦略により、Nyashは安定性、開発者体験、安全性を段階的に向上させ、活発で持続可能なプラグインエコシステムを構築できると確信します。

View File

@ -0,0 +1,37 @@
# Nyash ABI議論アーカイブ
このディレクトリには、Nyash ABIの設計に関する重要な議論や考察が保存されています。
## 📚 ドキュメント一覧
### 🌟 AI専門家の深い考察
- **[gemini-codex-deep-thoughts.md](gemini-codex-deep-thoughts.md)** - Gemini先生とCodex先生によるNyash ABI C実装の深い考察2025年9月2日
- セルフホスティング実現への技術的妥当性
- 具体的な実装提案16バイトアライメント、セレクターキャッシング等
- 哲学的観点からの分析
### 🎯 設計の進化過程
- 初期提案: 複雑なFactory設計
- 転換点: 「型をC ABIの箱として渡す共通ルール」という洞察
- 最終形: TypeBox + Nyash ABI C実装による統一設計
## 💡 重要な洞察
### 「Everything is Box」の究極形
ABIそのものをBoxとして扱うことで、言語の哲学が技術的実装と完全に一致しました。
### セルフホスティングへの道
1. C Shim実装既存Rustへのラッパー
2. フルC実装基本型・参照カウント
3. Nyashで再実装AOTでC ABI公開
4. Nyashコンパイラ自身をNyashで実装
### AI専門家の評価
- **Gemini**: 「技術的妥当性が高く、言語哲学とも合致した、極めて優れた設計」
- **Codex**: 「Feasible and attractive: ABI-as-Box completes the idea」
- **ChatGPT5**: 「実装に耐える設計。10の改善点で完璧」
## 📝 関連ドキュメント
- [../NYASH-ABI-C-IMPLEMENTATION.md](../NYASH-ABI-C-IMPLEMENTATION.md) - 実装仕様書
- [../UNIFIED-ABI-DESIGN.md](../UNIFIED-ABI-DESIGN.md) - 統合ABI設計
- [../README.md](../README.md) - Phase 12概要

View File

@ -0,0 +1,113 @@
# Codex先生のNyash ABI実装戦略 (2025-09-01)
## 質問内容
Nyash ABIという統一ブリッジ規格の実装について技術的相談です。
【背景】
Gemini先生から以下の評価をいただきました
- COM/GObject/WASM Component Modelとの類似性
- 3つのu64は十分な表現力
- GC言語との循環参照が最大の課題
- 非同期処理はmetadataフラグで統一可能
- 「間に挟むだけ」だが世界を変える可能性あり
【Nyash ABIの基本設計】
```c
typedef struct NyashValue {
uint64_t type_id; // 型識別子
uint64_t box_handle; // Arc<T>のポインタ
uint64_t metadata; // フラグ・インライン値
} NyashValue;
typedef NyashValue (*NyashFunc)(
uint32_t argc,
NyashValue* args,
void* context
);
```
【具体的な実装相談】
1. MIR統合: ExternCallにabi_type追加で十分それとも新命令
2. バインディング生成: #[nyash_abi]マクロの実装戦略は?
3. 型レジストリ: type_idの生成と管理方法ハッシュ連番
4. インライン最適化: metadata活用で整数をbox化回避する設計
5. 移行戦略: 既存のC ABIプラグインとの共存方法
実装の観点から、最もシンプルで段階的に導入できる方法を教えてください。
## Codex先生の回答
以下は「まず壊さず、少しずつ置き換える」ための、最小実装から拡張していく導入方針です。現行の MIR/ランタイム構成を踏まえ、後方互換を維持しつつ Nyash ABI を段階導入できます。
**最小導入方針**
- 入口統一: ランタイム側で常に `NyashFunc`3×u64に呼び出しを揃える。既存C ABIはランタイム内の薄いトランポリンで包んで `NyashFunc` に見せる。
- MIRは無変更: まずは `MirInstruction::ExternCall` のままで十分。ABI種別はレジストリが関数ポインタ解決時に吸収。
- 段階移行: プラグインが新旧どちらでも動くよう、`nyash.toml` で ABI 種別を宣言。未宣言は旧C ABI扱いにし、ランタイムが自動でトランポリン生成。
**1. MIR統合ExternCallの扱い**
- 現状の `MirInstruction::ExternCall { iface_name, method_name, args, effects }``Semantics::extern_call(&str, &str, &[Val])` をそのまま使用。
- ランタイムの「外部呼び出し解決レイヤ(ユニファイドレジストリ)」で `(iface, method)` → 事前に登録済みの「NyashFuncポインタ」を返す。
- 既存C ABI実装はロード時に「C→Nyash ABI 変換トランポリン」を自動作成し、そのポインタを登録。JIT/LLVM/VM の各バックエンドは常に同じ `NyashFunc` 呼び出しシグネチャだけを生成すればよい。
- 将来的に ABI ヒントが必要なら、`ExternCall` にオプショナルな `abi: AbiKind` 追加は可能だが、初期段階では不要。
**2. バインディング生成(#[nyash_abi]**
- 戦略: プロシージャルマクロで「Rust普通関数 ↔ NyashFuncシグネチャ」間の自動ラッパを生成。
- 生成内容:
- `#[no_mangle] extern "C" fn exported(argc, *args, ctx) -> NyashValueABI` の外側関数NyashFunc
- 内側で ABI 配列 `NyashValueABI` を内部 `crate::value::NyashValue` にデコード、Rust関数を呼び、戻りを再度 ABI へエンコード。
- 型境界は `FromAbi/ToAbi` トレイトで実装i64/bool/string/box など)し、`#[nyash_abi] fn f(a: i64, b: String) -> bool` のような自然な記述で書けるようにする。
- 配布: `crates/nyrt/``nyash_abi.h`C向けヘッダ`abi.rs`Rust向けを置く。プラグインはこのヘッダ/クレートにだけ依存。
**3. 型レジストリtype_idの生成と管理**
- 方式: 64bit固定ハッシュ安定化のための固定シードで「完全修飾名」をハッシュ。
- 例: `"nyash.core/Integer"`, `"plugin.math/BigInt@1"` のように namespace + 型名 + バージョンを連結して xxhash/siphash で 64bit に。
- 衝突対策: 初回登録時に「同一IDだが異なる完全名」の場合は起動時に失敗CIで検知。内蔵型は予約IDを定数定義Null, Void, Bool, I64, String など)。
- レジストリ: 既存の `src/runtime/unified_registry.rs` に統合、あるいは `abi_registry.rs` を新設。
- `id -> vtable`dtor/trace/to_string/cast`name -> id` を保持。
- `nyash.toml` で型やメソッドの宣言を受け取り、ロード時に登録。プラグイン側も `#[nyash_abi(type = "...")]` で露出。
**4. インライン最適化metadataの使い方**
- 目的: 小さい値は box を避け、`box_handle=0``metadata` に即値を入れる。
- 提案レイアウト(初期版・シンプル):
- 最上位4bit: タグ0=Boxed, 1=I63, 2=Bool, 3=Null, 4=Void, 5=Reserved(Future/Async)
- `I63`: 下位63bitに符号付き整数。`type_id=NYASH_TID_I64`, `box_handle=0`
- `Bool`: bit0 に値。`type_id=NYASH_TID_BOOL`, `box_handle=0`
- `Null/Void`: `box_handle=0``type_id` はそれぞれの予約ID。
- `Boxed`: `box_handle``Arc<T>` のアドレス(生ポインタまたはハンドル値)。`metadata` の低位にフラグweak/async/readonly 等)を拡張可能。
- 浮動小数は第1段では Boxed のまま(安全優先)。将来 NaN-boxing 等は別フェーズで検討。
**5. 移行戦略既存C ABIとの共存**
- プラグイン宣言: `nyash.toml``abi = "c" | "nyash"` を追加。未指定は `"c"` と見做す。
- ローダ:
- `"nyash"`: 直接 `NyashFunc` を dlsym。
- `"c"`: 既存C関数を dlsym → ランタイム側トランポリンを生成(呼び出し前後で ABI <-> 旧C の変換)。
- 呼び出し側MIR/バックエンド): 常に `NyashFunc` を呼ぶのでコード生成は単純化。JIT/LLVM/VM の差異を ABI 解決層が吸収。
- 段階移行:
- Phase 1: トランポリンで全プラグインが動く状態を作るMIR無変更
- Phase 2: 新規プラグインは `#[nyash_abi]` を使うガイドを提示。
- Phase 3: ホットパスのプラグインだけ順次Nyash ABIネイティブ化ボックス回避の恩恵
**GC/循環参照(要点)**
- 既定は「外部境界のエッジは弱参照扱い」。強参照を持つ場合のみ明示 pin/unpin API`metadata` の weak/pinned フラグで伝達)を導入。
- レジストリの vtable に `trace()`/`finalize()` を用意し、GC 言語ブリッジは自前 GC へ協調Mark 時にクロス境界を報告)。
- 非同期や Future は、「Boxed + asyncフラグor 専用 type_id=Future」で統一し、`await` 時に解決。メタデータビットで「非同期値(未解決)」を示す。
**実装ステップ(具体)**
- NyRT:
- `crates/nyrt/include/nyash_abi.h``crates/nyrt/src/abi.rs` を追加(`NyashValueABI`、エンコード/デコード、予約 type_id、タグ定義
- `FromAbi/ToAbi` トレイトと安全ヘルパ。
- レジストリ:
- `src/runtime/abi_registry.rs`(または既存の unified_registry に統合)で `(iface, method) -> NyashFunc*` を解決。
- `nyash.toml` から ABI 種別と型宣言を読み取り登録。
- ローダ/トランポリン:
- `"c"` プラグイン呼び出しを包む小さな C→Nyash ラッパ(呼出前後で値配列を変換)。
- マクロ:
- `crates/nyash-macros``#[nyash_abi]` を実装。Rust関数に対して NyashFunc エクスポート型ID登録。
**最小で得られる効果**
- MIRやバックエンドは変更最小もしくは無変更で、呼出境界が統一。
- まず整数/真偽/null/void が即値で走り、箱化コストが減少。
- 既存プラグインは壊れず、徐々に `#[nyash_abi]` へ移行可能。
必要なら、この方針で最初のスケルトン(`nyash_abi.h/abi.rs`、トランポリン、レジストリ拡張)の差分案まで作ります。どの順から着手しますか?

View File

@ -0,0 +1,235 @@
# Gemini先生とCodex先生のNyash ABI C実装についての深い考察
2025年9月2日、Nyashのセルフホスティング実現に向けて、2人のAI専門家が深い考察を提供しました。
## 🌟 Gemini先生の考察
### 総評
**「技術的妥当性が高く、言語哲学とも合致した、極めて優れた設計」**
### 1. 技術的妥当性
#### C言語によるNyash ABI実装の現実性
- **現実的です。** C言語は、OSのカーネルから他のプログラミング言語のランタイムまで、システムコンポーネントを記述するためのデファクトスタンダードです。
- 参照カウント、動的な型情報メソッドテーブルなどの管理、メモリレイアウトの精密な制御といった、ABIの実装に必要な低レベルな操作は、すべてC言語の得意分野です。
#### TypeBoxシステムとの統合の自然さ
- **極めて自然です。** TypeBoxがC ABIベースのプラグインシステムであるため、Cで実装されたNyash ABIをTypeBoxの一種として動的にロードする、というアイデアは既存の仕組みに完璧に乗っかります。
- `abi_tag: 'NABI'` のような識別子で他のTypeBoxと区別するのも、クリーンで拡張性の高い方法です。
- これは、システムの複雑性を爆発させることなく、コア機能の差し替えを実現するエレガントなソリューションです。
#### セルフホスティングへの道筋の明確さ
- **明確かつ論理的です。** 提示された3段階の移行戦略は、セルフホスティングを達成するための古典的かつ実績のあるブートストラップ手順を踏んでいます。
1. **Rust製コンパイラ** を使って、**C実装ABI**上で動く **Nyash製コンパイラ** をコンパイルする。
2. 生成された **Nyash製コンパイラ** を使って、**それ自身を再度コンパイル**する。
- この時点でRustツールチェインへの依存が切れ、セルフホスティングが達成されます。
### 2. 実装上の課題と解決策
#### メモリ管理の具体的な実装方法
- **参照カウント:** 提案通り、参照カウントが基本になります。
- 具体的には、Nyashの各Boxオブジェクトが確保するメモリブロックのヘッダ部分に、参照カウント数を格納するフィールド例: `atomic_size_t ref_count;`)を設けます。
- `retain` / `release` は、このカウンタを**アトミック操作**で増減させる必要があります。これにより、マルチスレッド環境下でも安全なメモリ管理が保証されます。C11の `<stdatomic.h>` が利用できます)
- **循環参照への対策:** 初期段階では「循環参照は未定義動作(メモリリーク)」と割り切ることも可能ですが、長期的には**弱参照Weak Reference**の仕組みをABIレベルで導入することを強く推奨します。
#### 型安全性をどう保証するか
- `type_id` が鍵となります。これは単なる整数ではなく、**グローバルな型情報テーブルへのインデックス(またはポインタ)**として機能させるべきです。
- このテーブルには、型名、メソッドテーブル(メソッド名と関数ポインタのマップ)、親の型への参照などの情報が含まれます。
- `invoke_method` を実行する際は、まずオブジェクトの `type_id` から型情報を引き、メソッドテーブル内に要求されたメソッドが存在するかを検証します。
#### パフォーマンスへの影響
- **ディスパッチのオーバーヘッド:** 文字列比較によるメソッド検索は遅延の原因になります。これを緩和するため、コンパイル時にメソッド名をハッシュ化し、ランタイムでは整数(ハッシュ値)で比較する方法が効果的です。
- **インライン値Tagged Pointers:** `NyashValue_C` の設計はパフォーマンスの鍵です。64bit環境では、ポインタの下位ビットがアラインメントにより常に0であることを利用し、このビットを「タグ」として使うことで、小さな整数や真偽値などをポインタに直接埋め込めます。
### 3. 段階的移行戦略
#### 既存Rust実装との共存方法
- 移行期間中、Nyashランタイムは**2種類のBox表現Rustネイティブ版とC ABI版を同時に扱える**必要があります。
- 両者の間で値をやり取りするための**ブリッジ(変換層)**が不可欠です。
- 最初は、コアな組み込み型はRust実装のまま、新しいプラグインや一部のモジュールをC ABI版で実装していくのが安全な進め方でしょう。
#### 互換性維持とテスト戦略
- **ABIインターフェースの凍結:** `nyash_ops` の関数シグネチャとセマンティクス(所有権のルールなど)を一度定義したら、それを厳格に守ることが極めて重要です。
- **大規模なテストスイート:** 移行を成功させるには、テストがすべてを決定します。
1. **振る舞いの一致テスト:** 同じNyashソースコードを「Rust ABIのみ」「C ABIのみ」「両者混在」の3つのモードで実行し、出力や結果が完全に一致することを検証するテストスイートを構築します。
2. **ユニットテスト:** Cで実装されたABIの各関数`create_value`, `retain`, `release`などを、Cのテストフレームワーク例: `check`)で徹底的にテストします。
3. **ベンチマーク:** 各フェーズでパフォーマンスを計測し、意図しない性能劣化(リグレッション)が起きていないかを常に監視します。
### 4. 哲学的な観点
#### 「Everything is Box」哲学との整合性
- **完璧に整合しています。** これは「Everything is Box」という哲学の究極的な表現です。
- 言語を構成するユーザーレベルのオブジェクトだけでなく、言語の実行基盤であるABIそのものまでもが「Box」という統一された概念で扱われる。
- これは、LISPがコードとデータをS式で統一的に扱う美しさに通じる、自己言及的なエレガンスを持っています。
#### ABIをBoxとして扱うことの意味
- これは、**言語の振る舞いを定義する「メタオブジェクト」**を導入することに他なりません。
- これにより、Nyashは自分自身の実行セマンティクスすら、理論上は動的に差し替えたり拡張したりできる可能性を秘めることになります。
- 例えば、デバッグ用のABI、プロファイリング用のABI、あるいは全く異なるメモリ管理モデル例: GCを持つABIを、同じTypeBoxの仕組みでロードすることも夢ではありません。
### 5. 他の選択肢との比較
#### Rust依存を維持する場合
- 実装は楽ですが、言語としての独立性を永遠に失います。
- Nyashをビルドするのに常にRustが必要というのは、言語のポータビリティと自己完結性を著しく損ないます。
#### 他のセルフホスティング戦略(例: LLVMへのコンパイル
- LLVM IRのような中間言語にコンパイルするのも強力な戦略です。
- しかし、それはNyashの実行モデルをLLVMのモデルにマッピングする作業であり、依存先がRustからLLVMに変わるだけとも言えます。
- ご提案の「ABIのBox化」は、**Nyash自身の実行モデルを維持したまま独立を果たす**という点で、より自己完結的で野心的なアプローチです。
#### 長期的な保守性
- C ABIは、コンピューティングの世界で最も安定し、普遍的なインターフェースです。
- ここに基盤を置くことで、Nyashは将来にわたって非常に高い安定性とポータビリティを獲得できます。
### 結論と最終的なアドバイス
ご提案の設計は、Nyashを真に独立した言語へと飛躍させ、その哲学を完成させるための、**実装可能かつ美しいブループリント**です。この方向性で進むことを強く推奨します。
**追加のアドバイス:**
- **所有権ルールの厳密な定義:** ABIの関数呼び出しにおける値の所有権誰が`release`の責任を持つか)を、ドキュメントで厳密に定義してください。
- **エラーハンドリング:** `invoke_method`などが失敗した場合に、どのようにエラー情報(型ミスマッチ、メソッド未定義など)を呼び出し元に伝えるか。
---
## 🔧 Codex先生の考察
### Executive Summary
- Feasible and attractive: treating the Nyash ABI itself as a TypeBox (C ABI) is a clean way to deRust the runtime boundary while aligning with "Everything is Box".
- Key to success: keep the ABI surface minimal, versioned, allocator/contextcentric, and futureproofed; treat reflection, invocation, and async as Boxes too.
- Migration: start as a C shim over current Rust NyRT, run conformance tests in parallel, then swap implementations behind the same ABI, and finally reimplement in Nyash.
### Technical Feasibility
- C implementation: realistic if the ABI is small, pure C (no exceptions), with explicit lifetimes, error/status returns, and allocator control. Similar precedents exist (CPython C-API, Lua C API, COMstyle vtables).
- TypeBox integration: natural fit if the ABI object is "just another Box" exposing a stable vtable plus discovery via `nyash.toml`/plugin loader.
- Selfhosting path: clear when the compiler and runtime only depend on the C ABI Box; the compiler written in Nyash can build itself by linking against that Box.
### ABI Shape: Recommended Adjustments
- Versioning and size: include `api_version` and `struct_size` in the TypeBox header so older loaders can detect compatibility.
- Context first: most functions accept a `nyash_ctx*` holding allocator, scheduler, TLS, and feature flags; this avoids global state.
- Status + outparams: adopt `nyash_status` enum return, with outputs via outparams; do not return ownership in a raw return position.
- Object model: make every heap object implement retain/release via a common header/layout and expose a `nyash_obj_vtable` for method lookup.
- Method invocation: prefer selector/handle lookup over raw string calls. Pattern:
- `nyash_status lookup_selector(ctx, type_id, name, out nyash_selector*)`
- `nyash_status call(ctx, obj, selector, argv, argc, out result)`
- Allows caching and JIT fast paths; string lookup happens at most once per callsite.
### Minimal core surface:
- `retain(obj)`, `release(obj)`
- `type_of(value) -> type_id`
- `is_null`, `eq`, `hash`
- `lookup_selector`, `call`
- `create_value(type_id, data, flags)`
- `alloc`, `free`, `mem_stats` via `nyash_allocator`
- `error_new`, `error_code`, `error_message` (errors are Boxes)
- Async primitives as Boxes (see below)
- Binary hygiene: add `vendor_tag`, `abi_tag = 'NABI'`, reserved fields, and explicit alignment requirements.
### Value Layout and Type Identity
- `nyash_value`: 16byte payload recommended for portability and JIT friendliness:
- `u64 type_id; u64 payload; u64 meta;` or `u64[2] payload` if you want 128bit immediates later. Ensure 16byte alignment for vector ops and stable lowering in LLVM.
- Inline vs heap:
- Use low meta bits for immediate tags (small int, bool, null, small enum).
- Heap payloads are opaque pointers to refcounted objects with a common header.
- `type_id`: stable 64bit value with namespacing: top 16 bits vendor, 8 bits kind (struct, enum, trait/interface, array, func), remaining bits a stable hash of the fullyqualified name + version.
### Memory Model
- Intrusive refcount header: for all heap Boxes:
- `struct header { atomic_uintptr_t rc; const nyash_obj_vtable* vtable; u64 type_id; u64 flags; }`
- Thread safety: use atomic increments/decrements; defer destruction on the owning scheduler thread if the vtable marks "affine".
- Cycle handling: three options; pick one early and document:
- No crosscycle guarantee, plus "weakref" Boxes and explicit `close()` for graph owners (lowest complexity).
- Trialdeferred cycle detection (BaconRajan) at safepoints.
- Arena/region Boxes for compiler/IR lifetimes (good for selfhosting).
- Allocation: `nyash_allocator` in `nyash_ctx` allows embedding, custom arenas, and leak accounting. Every allocation path must route through it.
### Type Safety Guarantees
- Validate `type_id` on every API entry that consumes a `nyash_value`. Return `NYASH_E_TYPE`.
- Provide `nyash_cast(ctx, value, target_type_id, out value2)` that performs runtime checks (and potentially conversion) in one place.
- For generics/parametric types, define a "type constructor" `type_id` plus encoded parameters hashed into a derived `type_id`.
### Performance Considerations
- Selector caching: make `nyash_selector` a stable handle (contains resolved vtable slot + inline cache cookie). JIT can inline calls directly via the slot.
- Avoid string dispatch in hot paths: strings resolve only once per callsite; ABI preserves handles to avoid repeated lookups.
- Small immediates: keep i31/i61, bool, small enum as immediates; `meta` carries tag; JIT emits zerobranch unbox.
- Error handling: status codes + separate error Box avoids exceptions; zerooverhead fast path.
- Marshaling: keep `argv` as a flat `nyash_value*` slice; for varargs heavy sites, support `nyash_tuple` Box to amortize allocations.
- Layout stability: document alignment and endianness; avoid bitfields in the ABI; use masks and shifts.
### Async and Errors
- Async as Box: define `nyash_future` TypeBox with
- `poll(ctx, self, out ready, out result_or_err)`
- `awaitable` integration at the language level; scheduler belongs to `nyash_ctx`.
- Cancellation: `cancel(ctx, self, reason)`; guarantee idempotence.
- Errors as Box: `nyash_error` carries `code`, `message`, `data` (Box). Every API returning nonOK can also optionally fill an out error Box.
### Versioning and Compatibility
- Feature negotiation: `supports(ctx, feature_id)` and a `capabilities` bitmask in the provider header.
- Semantic version in header, strict size check: reject if `struct_size < required`.
- Reserved fields: pad both the provider and object vtables with reserved pointers for forward extension.
- Crossplatform: define `NYASH_ABI_API` macro for visibility/calling convention; test x86_64 Linux, macOS, Windows (MSVC) early.
### Coexistence and Migration
- Phase 1 (C shim over Rust):
- Implement the C TypeBox provider whose functions forward to existing Rust NyRT via `extern "C"` glue. This validates the ABI without rewriting runtime logic.
- Place under `plugins/nyash_abi_c/` and add mapping in `nyash.toml`.
- Phase 2 (feature parity in C):
- Incrementally reimplement hot paths: small immediates, retain/release, allocator, string, array. Keep complex features (async, reflection) temporarily forwarded to Rust until replaced.
- Phase 3 (Nyash reimplementation):
- Recode the C provider in Nyash, but keep the exact same C ABI surface via an AOT target producing the same symbols.
- Coexistence:
- Loader picks provider by name and version from `nyash.toml`. Keep Rust and C providers shippable concurrently; choose via env (`NYASH_ABI_IMPL=c,rust`).
- Compatibility:
- Add a conformance suite that exercises only the ABI; run it against both providers until results match.
### Testing Strategy
- Conformance tests under `tests/abi/`:
- Retain/release semantics, crossthread retain, immediate encoding, selector lookup caching, error propagation, async poll semantics.
- Fuzz/property tests for `nyash_value` encode/decode and `type_id` canonicalization.
- ABI stability:
- Generate a C header from a single source of truth; forbid breaking changes unless version bumps.
- Integration smokes:
- Use `tools/llvm_smoke.sh` with `NYASH_C_ABI=1` to validate JIT/AOT endtoend with the C provider loaded.
### Philosophical Fit
- ABIasBox completes the idea that "runtime powers" are themselves values. It turns reflection, invocation, and scheduling into firstclass participants rather than privileged side channels.
- Beauty comes from uniform dispatch: the compiler, runtime, and plugins all talk through the same Box vocabulary with selectors and capabilities.
### Alternatives and Tradeoffs
- Keep Rust dependency:
- Pro: faster to evolve; borrowchecker catches many bugs.
- Con: selfhosting depends on Rust toolchain; ABI surface must still be C for plugins; harder for other ecosystems to embed.
- WASM/WASI ABI:
- Pro: portable sandbox, good for plugins.
- Con: host interop and lowlatency GC/RC semantics are harder; JIT integration overhead.
- Minimal microkernel runtime in C + highlevel services in Rust:
- Pro: balance; critical ABI in C, complex features in Rust behind handles.
- Con: more moving parts, boundary crossings remain.
### Concrete Next Steps
- Define and freeze a v0 ABI header:
- Add `api_version`, `struct_size`, `nyash_ctx*`, `nyash_allocator*`, `nyash_status`, `nyash_value` 16byte layout, `retain/release`, `lookup_selector`, `call`, `error` primitives, and capability bits.
- Scaffold `plugins/nyash_abi_c/`:
- Provide a stub provider that returns `NYASH_E_NOT_IMPL` but passes header/version checks; wire it in `nyash.toml`.
- Add a conformance test crate in `tests/abi/` that loads the provider by name and validates the header, alloc, retain/release, and immediate encodes.
- Implement small immediates + retain/release + strings:
- Backed by a simple threadsafe RC and arena allocator in C.
- Introduce selector caching in the VM/JIT:
- Plumb `nyash_selector` handles in the call path; deopt to string lookup on cache miss.
If you want, I can draft the minimal v0 header (with versioning/capabilities and 16byte value layout) and a stub `plugins/nyash_abi_c` skeleton that loads in the current repo, plus a small conformance test to exercise header negotiation.
---
## まとめ
両AI専門家が一致して、Nyash ABIをC実装TypeBoxとして提供する設計案を高く評価しています。
共通する重要ポイント:
1. **技術的に実現可能** - C言語でのABI実装は現実的で実績もある
2. **哲学的に美しい** - Everything is Boxの究極的表現
3. **段階的移行が鍵** - C Shim → フル実装 → Nyash再実装
4. **パフォーマンス最適化** - Tagged Pointers、セレクターキャッシング
5. **セルフホスティング実現** - Rust依存を完全に排除可能
この深い考察により、Nyashのセルフホスティングへの道筋が明確になりました。

View File

@ -0,0 +1,141 @@
# Gemini先生のNyash ABI分析 (2025-09-01)
## 質問内容
Nyash ABIという統一ブリッジ規格について技術的相談です。
【背景】
Nyashプログラミング言語で、あらゆる言語を繋ぐ統一的なABIを作る構想です。
【Nyash ABIの基本設計】
```c
// C ABIベースだが、Nyash型システムを載せる
typedef struct NyashValue {
uint64_t type_id; // 型識別子
uint64_t box_handle; // BoxハンドルArc<T>のポインタ)
uint64_t metadata; // 拡張用async flag等
} NyashValue;
// 統一関数シグネチャ
typedef NyashValue (*NyashFunc)(
uint32_t argc,
NyashValue* args,
void* context
);
```
【目的】
- Rust、Python、JavaScript、C++等、すべての言語とNyashを繋ぐ
- C ABIの安定性 + Nyash型システムの表現力
- Everything is Box哲学の外部拡張
【技術的な質問】
1. このような統一ABIの前例はありますかCOM、GObject等との比較
2. 3つのu64で十分な表現力がありますか
3. パフォーマンスへの影響をどう評価しますか?
4. GCやメモリ管理の課題は
5. 非同期処理の統一的な扱い方は?
正直「間に挟むだけ」ですが、世界を変える可能性について深く考察してください。
## Gemini先生の回答
Nyash ABI構想、拝見しました。これは非常に野心的で、プログラミング言語の相互運用性における根源的な課題に挑戦する、素晴らしい着想だと思います。「間に挟むだけ」とご謙遜されていますが、その「中間層」こそが、ソフトウェア工学における最も困難で価値のある部分です。
ご提示いただいた設計とご質問に基づき、深く考察させていただきます。
---
### Nyash ABIの技術的考察
#### 1. このような統一ABIの前例はありますか
はい、数多くの前例が存在します。それらとの比較から、Nyash ABIの独自性と課題が見えてきます。
* **COM (Component Object Model) / WinRT:** Microsoftが提唱したバイナリ互換性のあるコンポーネント技術。参照カウントによるメモリ管理、インターフェースクエリ`QueryInterface`による動的な型チェックなど、Nyash ABIの思想と非常に近いです。しかし、COMはレジストリへの登録やIDLインターフェース定義言語が必須で、Windows中心の複雑なエコシステムでした。Nyash ABIは、これをよりシンプルでクロスプラットフォームな形で実現しようとしていると解釈できます。
* **GObject:** C言語でオブジェクト指向プログラミングを実現するためのライブラリで、GTK+の基盤です。こちらも参照カウント、プロパティ、シグナルイベントといった高度な機能を持ち、動的な型システムを備えています。Nyash ABIは、GObjectの核心的なアイデア型情報を持つ汎用的な値コンテナを、よりミニマルな形で抽出したものと言えるでしょう。
* **WebAssembly Component Model:** これが現在最も思想的に近い最先端の取り組みです。Wasmは当初、単純な数値型しかやり取りできませんでしたが、Component Modelは、文字列、レコード、バリアントといった高レベルな型を言語間でどう受け渡すかを定義する仕様です。その内部では、すべての高レベルな型が最終的に単純な数値型`i32`, `i64`などに「下げられlowering」てWasmコアABIを通過し、受け取り側で再度高レベルな型に「上げられlifting」ます。Nyash ABIの`NyashValue`は、この「高レベルな型を表現するコンテナ」そのものであり、Component Modelが目指す世界を、ネイティブコードの世界で直接実現しようとする試みと見なせます。
* **結論:** アイデア自体は新しいものではありません。しかし、これは弱みではなく、むしろ**「この方向性が正しいことの証明」**です。COMやGObjectの複雑さを乗り越え、Wasm Component Modelのような現代的なシンプルさをネイティブABIとして提供できるなら、大きな価値があります。
#### 2. 3つのu64で十分な表現力がありますか
はい、**十分すぎるほどの表現力**を持っています。これは非常に優れた設計です。
* `type_id (uint64_t)`: 64bitもあれば、型名のハッシュ値や、階層的な型IDなど、事実上無限の型を表現できます。衝突の心配はまずありません。
* `box_handle (uint64_t)`: 64bitアーキテクチャのポインタを格納するのに最適です。`Arc<T>`のポインタをそのまま格納することで、言語間で所有権(参照カウント)を共有する核心的な役割を担います。
* `metadata (uint64_t)`: このフィールドが鍵です。64個のビットフラグとして使えます。
* 非同期フラグ (`IS_ASYNC`)
* ミュータブルフラグ (`IS_MUTABLE`)
* 所有権ヒント(呼び出し側が所有権を放棄するかどうか等)
* **インライン値の格納:** `box_handle``NULL`の場合、この`metadata`フィールドに小さな整数や浮動小数点数を直接格納する(ポインタタグ付けのような)最適化も可能です。これにより、単純な数値の受け渡しでヒープ確保が不要になります。
この`3 * uint64_t`の設計は、シンプルさ、拡張性、そして最適化の余地を兼ね備えた、非常に堅牢な基盤です。
#### 3. パフォーマンスへの影響をどう評価しますか?
これは最大のトレードオフです。
* **オーバーヘッド:**
1. **間接参照:** すべての値にアクセスするために、`NyashValue` -> `box_handle` -> `Arc<T>` -> `T`というポインタの連鎖をたどる必要があり、キャッシュ効率が悪化する可能性があります。
2. **ヒープ確保:** すべてをBox化`Arc`化)するため、単純な整数を渡すだけでもヒープ確保と参照カウントのオーバーヘッドが発生します。(前述のインライン値最適化で緩和可能)
3. **動的ディスパッチ:** `type_id`に基づいた実行時の型チェックとディスパッチは、静的な関数呼び出しよりも遅くなります。
* **評価方法:**
* **粒度Granularityが重要です。**
* **粗い粒度Chunky:** 大きなデータ画像データ、長いテキストを一度渡して、言語の内部で長時間処理する場合は、ABIのオーバーヘッドは無視できるほど小さくなります。これはNyash ABIが得意とする領域です。
* **細かい粒度Chatty:** ループの中で、小さな値を何度も頻繁にやり取りする場合(例: `for i in 0..1_000_000 { foreign_add(1, 2) }`)、オーバーヘッドが致命的になります。
* **ベンチマーク:** C言語のネイティブ関数呼び出しをベースライン1.0)として、以下のようなシナリオで性能を測定すべきです。
* 整数、浮動小数点数の受け渡し
* 短い文字列、長い文字列の受け渡し
* 大きなバイト配列の受け渡し
* コールバック関数Nyash -> C -> Nyashの呼び出し
パフォーマンスが最重要視される場面では、このABIをバイパスする「高速パス」を用意することも検討すべきでしょう。
#### 4. GCやメモリ管理の課題は
`Arc<T>`アトミック参照カウントをベースにしているのは素晴らしい選択です。これにより、RustやC++のような手動メモリ管理言語との連携は非常に堅牢になります。
**最大の課題は、GCガベージコレクションを持つ言語Python, JavaScript, Javaなどとの連携です。**
* **課題:** GCを持つ言語のオブジェクトをNyash側で`Arc`でラップし、同時にNyashのオブジェクトをGC言語側で参照すると、**循環参照**が容易に発生し、メモリリークの原因となります。
* **解決策:**
1. **プロキシオブジェクト:** 各言語のバインディング層で、「プロキシオブジェクト」を生成します。例えば、Python側でNyashオブジェクトを扱う場合、その`__del__`メソッドで`Arc`の参照カウントをデクリメントするPythonクラスを作ります。
2. **弱参照Weak References:** 循環を断ち切るために、片方の参照を弱参照にする必要があります。`Arc``Weak`へのダウングレードをサポートしているため、これを活用できます。
3. **明示的な破棄:** `dispose()``close()`のようなメソッドを公開し、ユーザーが手動でリソースを解放できるようにすることも、確実な方法です。
このGCとの連携は、バインディングライブラリの設計で最も注意を要する部分です。
#### 5. 非同期処理の統一的な扱い方は?
`metadata`フィールドがここでも活躍します。
* **統一Future/Promiseモデル:**
1. 非同期関数は、`IS_ASYNC`フラグを立てた`NyashValue`を即座に返します。
2. この`box_handle`は、`Box<dyn NyashFuture>`のような、非同期処理の状態を持つオブジェクトを指します。
3. `NyashFuture`トレイト(インターフェース)には、`poll(callback: NyashValue)`のようなメソッドを定義します。
4. 各言語のバインディング層が、この`NyashFuture`をその言語の非同期プリミティブRustの`Future`、JSの`Promise`、Pythonの`awaitable`)に変換します。
5. `poll`メソッドに渡す`callback`もまた`NyashValue`(関数オブジェクト)であるため、言語をまたいで非同期処理の結果を返すことができます。
これにより、ある言語のイベントループが、別の言語の非同期処理を駆動することが可能になります。これは非常に強力です。
---
### 世界を変える可能性についての考察
「間に挟むだけ」のレイヤーが世界を変えた例は、歴史上数多くあります。コンテナリゼーションDocker、仮想化VMware、そしてウェブHTTP/HTMLも、すべては抽象化レイヤーです。Nyash ABIもその可能性を秘めています。
* **真のポリグロット・エコシステムの実現:** 現在、言語間の連携は多大な努力を要する「特殊な作業」です。Nyash ABIが普及すれば、それが「当たり前の作業」に変わります。高性能な数値計算はRustで、AIモデルはPythonで、UIはJavaScriptで書き、それらをあたかも単一言語内のモジュールのようにシームレスに組み合わせる。これが当たり前になれば、開発者は「どの言語で作るか」ではなく**「どのタスクにどの言語が最適か」**だけを考えればよくなります。
* **ソフトウェア資産の再利用と延命:** C++で書かれた巨大なレガシーライブラリ、科学技術計算で使われるFortranのコード、そういったものを一度`NyashValue`でラップしてしまえば、未来のどんな言語からも安全に呼び出せる「不滅のコンポーネント」と化します。これはソフトウェア資産の価値を最大化します。
* **複雑性の削減:** `N`個の言語と`M`個のライブラリを繋ぐのに、現状では`N*M`通りのバインディングが必要です。Nyash ABIが中心にあれば、`N+M`個のバインディングで済みます。これはエコシステム全体の複雑性を劇的に削減します。
* **新しいアーキテクチャの創出:** プラグインシステム、ゲームのMOD改造、動的なサーバー機能拡張などが、言語に依存しない統一的な方法で実現できます。Nyash ABIは、単なるFFIForeign Function Interfaceを超え、**ユニバーサルなプラグイン・アーキテクチャの基盤**となり得ます。
**結論として、Nyash ABI構想は、単なる技術的挑戦ではなく、ソフトウェア開発のあり方そのものを変革する可能性を秘めた壮大なビジョンです。** パフォーマンスのトレードオフを理解し、GC言語との連携という困難な課題を乗り越え、高品質な多言語バインディングを提供できたとき、この「間に挟むだけ」のレイヤーが、ソフトウェアの世界を繋ぐ、不可欠なインフラになるでしょう。
ぜひ、この挑戦を続けてください。応援しています。

View File

@ -0,0 +1,102 @@
# Nyash ABI革命 - AI大会議統合まとめ (2025-09-01)
## 🎯 結論:「間に挟むだけ」が世界を変える
Gemini先生哲学的視点とCodex先生実装視点の両方が、Nyash ABIの革命的可能性を認めた。
## 📊 両先生の共通認識
### 1. 既存技術との比較
- **COM/GObject**: 複雑すぎる先行例
- **WASM Component Model**: 最も思想的に近い
- **Nyash ABI**: 上記の良いとこ取り+シンプルさ
### 2. 3×u64の表現力は十分
```c
typedef struct NyashValue {
uint64_t type_id; // 無限の型を表現可能
uint64_t box_handle; // Arc<T>ポインタ格納に最適
uint64_t metadata; // 64bitフラグインライン値
} NyashValue;
```
### 3. 主要な技術的課題
- **パフォーマンス**: 粒度による(粗い粒度なら影響小)
- **GC連携**: 循環参照が最大の課題
- **非同期処理**: metadataフラグで統一可能
## 🔧 実装戦略の統合
### Phase 1: 最小実装MIR変更なし
```rust
// 既存のExternCallをそのまま使用
MirInstruction::ExternCall {
iface_name,
method_name,
args,
effects
}
// ランタイムでNyashFunc統一呼び出しに変換
```
### Phase 2: インライン最適化
```
metadata上位4bit = タグ
- 0: Boxed通常のBox
- 1: I6363bit整数を直接格納
- 2: Bool真偽値
- 3: Null
- 4: Void
- 5: ReservedFuture/Async
```
### Phase 3: 段階的移行
```toml
# nyash.toml
[plugin.math]
abi = "nyash" # 新ABI
# abi = "c" # 旧ABIデフォルト
```
## 🌟 革命的インパクト
### Gemini先生の視点
> 「単なる技術的挑戦ではなく、ソフトウェア開発のあり方そのものを変革する可能性を秘めた壮大なビジョン」
- **真のポリグロット・エコシステム**: 言語の壁が消える
- **ソフトウェア資産の不滅化**: レガシーコードが永遠に生きる
- **複雑性の劇的削減**: N×M → N+M のバインディング
### Codex先生の視点
> 「まず壊さず、少しずつ置き換える」
- **即座の効果**: 整数/Bool/Null/Voidの即値化
- **後方互換**: 既存プラグインは自動トランポリン
- **段階的移行**: nyash.tomlで個別切り替え
## 🚀 実装優先順位
1. **nyash_abi.h/abi.rs**: 基本型定義とエンコード/デコード
2. **トランポリン層**: 既存C ABI→Nyash ABI変換
3. **#[nyash_abi]マクロ**: 自動バインディング生成
4. **型レジストリ**: 64bitハッシュによる型ID管理
5. **GC協調API**: trace/finalize/weak参照
## 💡 「Everything is Box」から「Everything is NyashValue」へ
Nyashの哲学が、言語の境界を超えて世界を統一する。
- **内部**: NyashValue enumRust表現
- **境界**: NyashValue structC ABI表現
- **統一**: すべての言語がNyashValueで会話
## 📝 次のアクション
1. Phase 12ドキュメントとの比較・統合
2. nyash_abi.h の初版作成
3. 最小トランポリン実装の検証
4. 既存プラグイン1つでの動作確認
---
*「間に挟むだけ」が、プログラミング言語の未来を変える。*

View File

@ -0,0 +1,100 @@
# Phase 12 × Nyash ABI 統合戦略
## 🎯 核心的発見
Phase 12NyashスクリプトプラグインとNyash ABI多言語ブリッジは、**同じ統一インターフェースの内側と外側**だった!
## 🏗️ 統合アーキテクチャ
```
外部言語Python/JS/C++/Rust等
┌─────────────────────────────────┐
│ Nyash ABI (C境界) │ ← 3×u64構造体
│ NyashFunc統一呼び出し規約 │
├─────────────────────────────────┤
│ 統一レジストリ・ディスパッチャ │
├─────────────────────────────────┤
│ BoxInterface (Rust内部) │ ← trait実装
│ invoke/get_methods/init/drop │
├─────────────┬─────────────────┤
│ Nyashスクリプト │ ネイティブ │
│ プラグイン │ プラグイン │
└────────────┴─────────────────┘
```
## 🔧 実装フェーズ
### Phase 1: 基盤統合1-2週間
- BoxInterfaceにNyashFunc変換レイヤー追加
- NyashValueenumとNyashValuestructの相互変換
- method_idをmetadataフィールドに統合
### Phase 2: export box拡張2-3週間
```nyash
export box MyPlugin {
// 以下を自動生成:
// 1. BoxInterface実装
// 2. NyashFunc extern "C"関数
// 3. 型レジストリ登録
}
```
### Phase 3: 多言語バインディング3-4週間
- Python: `@nyash_plugin`デコレータ
- JavaScript: `NyashPlugin`クラス
- Rust: `#[nyash_abi]`マクロ
- C++: `NYASH_PLUGIN`マクロ
### Phase 4: 最適化(継続的)
- インライン値(整数/Boolの高速化
- method_id による高速ディスパッチ
- JIT/AOTでの境界最適化
## 💡 革命的な統合効果
### 1. プラグイン開発の完全民主化
- **Nyashで書く**: ビルド不要、即座に実行
- **他言語で書く**: Nyash ABIで統一的に接続
- **相互運用**: NyashプラグインをPythonから、PythonプラグインをNyashから
### 2. エコシステムの爆発的拡大
```
従来: Rust/C++開発者のみ → 狭いエコシステム
統合後: 全言語の開発者 → 巨大エコシステム
```
### 3. 実装の簡潔性
- MIR変更最小ExternCallのまま
- 既存プラグイン後方互換(トランポリン自動生成)
- 段階的移行nyash.tomlで制御
## 📊 技術的シナジー
| Phase 12の強み | Nyash ABIの強み | 統合による相乗効果 |
|---------------|----------------|------------------|
| スクリプトで即開発 | 多言語対応 | どの言語でも即開発 |
| BoxInterface統一 | C ABI安定性 | 内外統一インターフェース |
| ホットリロード | メモリ安全 | 安全な動的更新 |
| 既存Box活用 | インライン最適化 | 高速かつ柔軟 |
## 🚀 次期アクション
1. **仕様統合**: BoxInterfaceとNyashFuncの正確なマッピング定義
2. **プロトタイプ**: 1つの既存プラグインで両方式を実装
3. **ベンチマーク**: 性能影響の測定(特にインライン値)
4. **ドキュメント**: 統合APIリファレンス作成
## 🌟 ビジョン
**「Everything is Box」が「Everything can be a Plugin」へ進化**
- Nyashで書いたコードが、そのままプラグイン
- どの言語で書いたコードも、Nyashプラグイン
- プラグインがプラグインを呼び、言語の壁が消える
これは単なる技術統合ではなく、**プログラミングの未来そのもの**。
---
*Phase 12とNyash ABIの統合により、史上最も開かれたプラグインエコシステムが誕生する。*