fix(joinir): Phase 241-EX - Remove hardcoded 'sum' check from Pattern3

Remove legacy hardcoded 'sum' carrier validation that was blocking
array_filter patterns with different accumulator names (e.g., 'out').

Before: Pattern3 required carrier named 'sum' to exist
After: Pattern3 uses carrier_info generically (any carrier name works)

Test results:
- phase49_joinir_array_filter_smoke: PASS 
- phase49_joinir_array_filter_fallback: PASS 
- phase49_joinir_array_filter_ab_comparison: PASS 
- Full suite: 909/909 PASS, 0 FAIL

Also: Archive old roadmap documentation (67k lines moved to docs/archive/)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-11 00:48:42 +09:00
parent a7dbc15878
commit 811dfebf98
387 changed files with 106 additions and 5551 deletions

View File

@ -0,0 +1,104 @@
# Phase 10.1: JIT→EXE via Plugin Box Unification
## 🎯 革新的発見:すべてはプラグインになる
### 核心的洞察
既存のプラグインシステムBID-FFIがすでに完全なC ABIを持っている。
これを活用することで、JIT→EXE変換が現実的に可能。
## 📊 フェーズ概要
### 目標
- ビルトインBoxをプラグイン化してC ABI統一
- JITから統一されたプラグインAPIを呼び出し
- スタティックリンクによるスタンドアロンEXE生成
### 背景
```
現在の構造:
- JIT → HostCall → Rustビルトイン複雑
- JIT → PluginInvoke → プラグインBoxC FFI
統一後:
- JIT → PluginInvoke → すべてのBox統一
- EXE → PluginInvoke → スタティックリンクされたBox
```
## 🚀 実装計画
### Week 1: ArrayBoxプラグイン化PoC詳細は phase_plan.md 参照)
- ArrayBoxをプラグインとして再実装
- JITからのプラグイン呼び出しテスト
- パフォーマンス測定HostCall vs Plugin
### Week 2: 主要Box移行詳細は phase_plan.md 参照)
- StringBox、IntegerBox、BoolBoxのプラグイン化
- JIT lowering層の統一plugin_invoke経由
- 既存HostCallとの共存メカニズム
### Week 3: 静的リンク基盤(詳細は phase_plan.md 参照)
- プラグインの`.a`ライブラリビルド
- 最小ランタイムnyash-runtime設計
- リンカースクリプト作成
### Week 4: EXE生成実証詳細は phase_plan.md 参照)
- Hello Worldレベルのスタンドアロン実行
- Linux/macOSでの動作確認
- デバッグ情報とunwind対応
## 📁 ディレクトリ構造(予定)
```
plugins/
├── nyash-core-boxes/ # ビルトインBox群
│ ├── nyash-array-plugin/
│ ├── nyash-string-plugin/
│ └── nyash-integer-plugin/
├── nyash-runtime-minimal/ # 最小ランタイム
└── existing/ # 既存プラグイン
├── nyash-file-plugin/
└── nyash-net-plugin/
```
## 🔗 関連資料(整備済み)
- フェーズ計画の詳細: [phase_plan.md](./phase_plan.md)
- C ABI v0 仕様JIT/AOT/Plugin共通: ../../../../docs/reference/abi/nyrt_c_abi_v0.md
- 命名: `nyrt_*`(コア)/ `nyplug_{name}_*`(プラグイン)
- 呼出規約: x86_64 SysV / aarch64 AAPCS64 / Win64
- `*_abi_version()` で fail-fastv0=1
## ストリームエラー対策(長文/大出力を避ける)
- 先頭に短い要約サマリを置く本READMEの冒頭にあり
- 詳細設計や長いコードは分割して参照phase_plan.md / nyrt_c_abi_v0.md
- コマンドやコードは三連バッククォートで閉じ忘れ防止
- [革新的アプローチ詳細](../../../ideas/new-features/2025-08-28-jit-exe-via-plugin-unification.md)
- [プラグインAPI仕様](../../../../reference/plugin-system/)
- [Phase 10.5: Python統合計画](../phase-10.5/) 旧10.1
- [Phase 10.10: 前段階の成果](../phase-10/phase_10_10/)
## ⚡ 成功指標
1. **技術的検証**
- ArrayBoxがプラグインとして動作
- JITからの呼び出し成功
- 性能劣化10%以内
2. **統合達成**
- 5つ以上のビルトインBoxがプラグイン化
- JIT lowering層の完全統一
3. **EXE生成**
- スタンドアロン実行ファイル生成
- 基本的なNyashプログラムの動作
## 🎉 期待される成果
- **Everything is Plugin** - 新たな設計哲学の確立
- 自己ホスティングへの現実的な道筋
- プラグインエコシステムの拡大可能性
---
*"Everything is Box → Everything is Plugin → Everything is Possible"*

View File

@ -0,0 +1,157 @@
# C ABI統一設計 - JIT/AOT共通基盤
*ChatGPT5さんからのアドバイスに基づく設計文書*
## 🎯 核心的洞察
**プラグインBoxのC ABI = そのままJIT/AOTの呼び出し土台**
JITで今呼んでいるC ABIをAOTでは静的リンクに差し替えるだけでexe化まで一直線
## 📊 全体アーキテクチャ
```
Nyash → MIR → VM/JIT/Cranelift ──┐
├─ 呼ぶ先は全部 C ABI: nyrt_* / nyplug_*
NyRT (libnyrt.a/.so) ←──────────┘
PluginBox 実装 (libnyplug_*.a/.so)
```
- **JIT**: `extern "C"` シンボル(`nyrt_*`/`nyplug_*`)をその場で呼ぶ
- **AOT**: 同じシンボルを`.o`に未解決のまま出力→`libnyrt.a`とプラグイン`.a`をリンク
- **動的配布**: `.so/.dll`に差し替え同じC ABIでOK
## 🔧 C ABIルール小さく強い
### 1. 命名/可視性
- コア: `nyrt_*`Box/weak/bus/gc/sync/alloc...
- プラグイン: `nyplug_{name}_*`ArrayBox, StringBox など)
- `extern "C"` + 明示の可視性ELF: `__attribute__((visibility("default")))`
### 2. ABIの型
- 引数/戻り: `int32_t/int64_t/uint64_t/double/void*` のみに限定
- `bool``uint8_t`統一、構造体は不透明ポインタ(ハンドル)
- `varargs`と例外のABI横断は**禁止**(戻り値でエラーコード/out-paramで返す
### 3. レイアウト/アライン
```c
// Boxハンドル例
struct NyBox {
void* data;
uint64_t typeid;
uint32_t flags;
uint32_t gen;
};
```
※JIT側は中身に触らない。操作はAPI経由のみ。
### 4. 呼び出し規約
- x86_64 SysV / aarch64 AAPCS64 / Win64 をターゲットごとに固定
- Craneliftの`call_conv`を上記に合わせるJIT/AOT共通
### 5. バージョン管理fail-fast
- `nyrt_abi_version()` / `nyplug_{name}_abi_version()`v0=1。不一致は起動時に即failローダ側で検査
## 📝 最小ヘッダ雛形
### nyrt.hコアランタイム
```c
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct NyBox {
void* data;
uint64_t typeid;
uint32_t flags;
uint32_t gen;
} NyBox;
int32_t nyrt_abi_version(void);
// Box/weak
NyBox nyrt_box_new(uint64_t typeid, uint64_t size);
void nyrt_box_free(NyBox b);
int32_t nyrt_adopt(NyBox parent, NyBox child);
int32_t nyrt_release(NyBox parent, NyBox child, NyBox* out_weak);
NyBox nyrt_weak_load(NyBox weak); // gen一致ならBox, 失効なら{0}
// GC/epoch
void nyrt_epoch_collect(void);
// Sync最低限
void* nyrt_mutex_lock(NyBox sync);
void nyrt_mutex_unlock(void* guard);
// Bus
int32_t nyrt_bus_send(NyBox port, NyBox msg);
#ifdef __cplusplus
}
#endif
```
### nyplug_array.hプラグイン例ArrayBox
```c
#pragma once
#include "nyrt.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t nyplug_array_abi_version(void);
NyBox nyplug_array_new(void);
int32_t nyplug_array_get(NyBox arr, uint64_t i, NyBox* out);
int32_t nyplug_array_set(NyBox arr, uint64_t i, NyBox v);
uint64_t nyplug_array_len(NyBox arr);
int32_t nyplug_array_push(NyBox arr, NyBox v);
#ifdef __cplusplus
}
#endif
```
## 🚀 ビルド・配布フローAOT静的リンク
1. **JITと同じLowering**でCLIF生成
2. **ObjectWriter**で`mod.o`出力(未解決:`nyrt_*`/`nyplug_*`
3. **リンク**
- Linux/macOS: `cc mod.o -static -L. -lnyrt -lnyplug_array -o app`
- Windows: `link mod.obj nyrt.lib nyplug_array.lib /OUT:app.exe`
4. 実行:`./app`でJIT無しに動作
補足: 現行実装ではプラグインは `nyash_plugin_invoke`BID-FFI v1, TLVを用いる。v0ではこれを固定し、将来的に `nyplug_*` 直関数を併置する場合も `*_abi_version()` で互換を担保する。
## ⚡ 実装順序(重要!)
1. **必要なビルトインBoxをプラグインBoxに変換**
2. **VM動作確認**
3. **JIT動作確認**
4. **AOT実装**
## ⚠️ 地雷と回避策
- **名前修飾/装飾**: C++で実装するなら`extern "C"`を絶対忘れない
- **サイズ違い**: `bool`/`size_t`のプラットフォーム差 → 明示幅型で統一
- **例外越境**: C ABI越しに`throw`/`panic`禁止。エラーコードout-paramで返す
- **並行**: JITから`nyrt_mutex_*`を呼ぶ箇所はSafepointとも整合するように長保持しない
## 📋 即実行ToDo30分で前進
- [ ] `nyrt.h`最小セット確定上の雛形でOK
- [ ] Craneliftの`call_conv`をターゲットに合わせて固定
- [ ] JIT経路で`nyrt_abi_version()==NYRT_ABI`を起動時チェック
- [ ] AOT試作`add.o`を吐いて`libnyrt.a`とリンク→`add()`を呼ぶ最小exe
## 💡 まとめ
> プラグインBoxのC ABIJIT/AOTの土台だから、
> **いまのJITが動いている静的リンクexeの最短ルートはもう目の前。**
> まずは`nyrt.h`を固定して、JITとAOTの両方で同じシンボルを呼ぶ状態にしよう。
> それで**"今日のJIT"が"明日のexe"**に化けるにゃ。
---
*最終更新: 2025-08-28*

View File

@ -0,0 +1,180 @@
# Phase 10.1 実装ステップガイド
## 🎯 実装の鉄則:必ずこの順序で!
ChatGPT5さんの指摘通り、緻密な計画と順序が成功の鍵にゃ。
## 📊 実装ステップ
### Step 1: ArrayBoxのプラグイン化最小実装
#### 1.1 プロジェクト作成
```bash
cd plugins/
cargo new nyash-array-plugin --lib
cd nyash-array-plugin
```
#### 1.2 最小限のC FFI実装
```rust
// src/lib.rs
#[repr(C)]
pub struct NyBox {
data: *mut u8,
typeid: u64,
flags: u32,
gen: u32,
}
#[no_mangle]
pub extern "C" fn nyplug_array_abi_version() -> i32 { 1 }
#[no_mangle]
pub extern "C" fn nyplug_array_new() -> NyBox {
// 簡略実装Vec<i64>のみサポート
let vec = Box::new(Vec::<i64>::new());
NyBox {
data: Box::into_raw(vec) as *mut u8,
typeid: 3, // ArrayBox
flags: 0,
gen: 1,
}
}
#[no_mangle]
pub extern "C" fn nyplug_array_len(arr: NyBox) -> u64 {
unsafe {
let vec = &*(arr.data as *const Vec<i64>);
vec.len() as u64
}
}
```
#### 1.3 ビルド設定
```toml
# Cargo.toml
[lib]
crate-type = ["cdylib", "staticlib"] # 動的・静的両対応
```
### Step 2: VM動作確認
#### 2.1 プラグインローダーとの統合
```rust
// src/runtime/plugin_loader_v2.rsに追加
fn load_builtin_plugins(&mut self) {
// 既存のFileBox等に加えて
self.register_plugin("nyash-array-plugin", 3); // ArrayBox type_id = 3
}
```
#### 2.2 テストプログラム
```nyash
// test_array_plugin.hako
local arr
arr = new ArrayBox() // プラグイン版を呼ぶ
print(arr.length()) // 0が出力されれば成功
```
#### 2.3 VM実行
```bash
./target/release/nyash --backend vm test_array_plugin.hako
```
### Step 3: JIT動作確認
#### 3.1 LowerCoreの修正
```rust
// src/jit/lower/core.rs
match box_type {
"ArrayBox" => {
// HostCallからPluginInvokeに切り替え
b.emit_plugin_invoke(3, method_id, args);
}
// 他のBoxは従来通り
}
```
#### 3.2 JIT実行テスト
```bash
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 ./target/release/nyash --backend vm test_array_plugin.hako
```
### Step 4: 段階的移行
#### 4.1 移行優先順位
1. **ArrayBox** - 最も使用頻度が高い
2. **StringBox** - 基本的なデータ型
3. **IntegerBox/BoolBox** - プリミティブ型
4. **MapBox** - コレクション型
5. **その他** - 順次移行
#### 4.2 互換性維持
```rust
// フラグで切り替え可能に
if env::var("NYASH_USE_PLUGIN_BUILTINS").is_ok() {
// プラグイン版を使用
} else {
// 従来のビルトイン版
}
```
### Step 5: パフォーマンス測定
#### 5.1 ベンチマーク作成
```nyash
// bench_array_ops.hako
local arr = new ArrayBox()
local start = Timer.now()
loop(i in 0..1000000) {
arr.push(i)
}
local elapsed = Timer.now() - start
print("Time: " + elapsed)
```
#### 5.2 比較測定
```bash
# 従来版
./target/release/nyash --benchmark bench_array_ops.hako
# プラグイン版
NYASH_USE_PLUGIN_BUILTINS=1 ./target/release/nyash --benchmark bench_array_ops.hako
```
## 🎯 成功基準
### Phase 11週間
- [ ] ArrayBoxプラグインが動作
- [ ] VM経由で基本操作new, length, push, getが可能
- [ ] パフォーマンス劣化が10%以内
### Phase 22週間
- [ ] JIT経由でも動作
- [ ] 5つ以上のビルトインBoxがプラグイン化
- [ ] 既存テストがすべてパス
### Phase 31ヶ月
- [ ] すべての主要ビルトインBoxがプラグイン化
- [ ] 静的リンクでの最小exe生成
- [ ] Linux/macOSで動作確認
## ⚠️ 注意事項
1. **TLVエンコーディング**: 既存のプラグインシステムに合わせる
2. **エラー処理**: panicではなくエラーコードを返す
3. **メモリ管理**: Box化されたデータのライフサイクルに注意
## 💡 デバッグ時のヒント
```bash
# プラグインロード確認
NYASH_DEBUG_PLUGIN=1 ./target/release/nyash test.hako
# JIT呼び出し確認
NYASH_JIT_EVENTS=1 ./target/release/nyash --backend vm test.hako
```
---
*"手順を守れば大丈夫" - 一歩ずつ確実に進めるにゃ!*

View File

@ -0,0 +1,87 @@
# Phase 10.1 Plugin Unification Path (MIR→JIT/AOT via C ABI)
This plan refines how we leverage the existing plugin system (BID-FFI) to unify JIT and AOT (EXE) paths using a single C ABI surface.
## Goals
- Unify calls from JIT and AOT to the same C ABI (`nyrt_*` / `nyplug_*`).
- Convert builtin Boxes to Plugin Boxes in small steps (read-only first).
- Produce a minimal standalone EXE via static linking after unification.
## Feasibility Summary
- JIT: emit calls to `extern "C"` symbols (no change in semantics, only target).
- AOT: emit `.o` with unresolved `nyrt_*` / `nyplug_*` and link with `libnyrt.a` + plugin `.a`.
- Compatibility: guard with `NYASH_USE_PLUGIN_BUILTINS` and keep HostCall fallback.
## Phase Breakdown
### 10.1: Plugin PoC + C ABI base (1 week)
- Deliverables:
- Minimal headers: `nyrt.h` (runtime), `nyplug_array.h` (ArrayBox plugin).
- ArrayBox as a plugin (`cdylib` + `staticlib`), ABI version functions.
- VM loader integration and `NYASH_USE_PLUGIN_BUILTINS` switch.
- Smoke: `new/len/push/get` working via plugin.
- DoD:
- Array plugin works on VM path; perf regression ≤10% on micro bench.
### 10.2: JIT Lowering unification (Array first) (11.5 weeks)
- Deliverables:
- IRBuilder: `emit_plugin_invoke(type_id, method_id, args, sig)`.
- LowerCore BoxCall for Array routes to `plugin_invoke` (events/stats intact).
- Feature-flagged enablement: `NYASH_USE_PLUGIN_BUILTINS=1`.
- DoD:
- JIT execution of Array read/write (policy-constrained) via plugin path.
- Behavior parity with HostCall; no regressions on CI smoke.
### 10.2b: JIT Coverage Unblockers (0.51 week)
- Goal:
- Remove practical blockers so plugin_invoke can be exercised in typical Nyash functions and `.o` can be produced.
- Deliverables:
- Lowering for `NewBox` of pluginized builtins → translate `new <Box>()` to plugin `birth()` via `emit_plugin_invoke(type_id, 0, argc=1 recvr-param)` with appropriate handle threading.
- Treat `Print/Debug` as no-op/hostcall for v0 to avoid function-wide skip.
- Keep conservative skip policy by default; document `NYASH_AOT_ALLOW_UNSUPPORTED=1` for validation-only `.o` emission.
- DoD:
- Minimal demo function with `String.length()` compiled by JIT (Cranelift) and `.o` emitted. Plugin events visible under JIT.
### 10.3: Broaden plugin coverage + Compatibility (2 weeks)
- Targets: String/Integer/Bool/Map (read-only first).
- Deliverables:
- Pluginized Boxes and `plugin_invoke` lowering for BoxCall.
- HostCall route retained; whitelist-driven co-existence.
- Added smoke and microbenches comparing HostCall vs Plugin.
- DoD:
- ≥5 builtin Boxes pluginized; `NYASH_USE_PLUGIN_BUILTINS=1` green on smoke.
### 10.4: AOT/EXE minimal pipeline (23 weeks)
- Deliverables:
- ObjectWriter path to emit `.o` with unresolved `nyrt_*`/`nyplug_*`.
- `libnyrt.a` minimal runtime + selected plugin `.a`.
- Link scripts and `nyc build-aot` proof-of-concept.
- Hello World-level standalone EXE on Linux/macOS.
- DoD:
- `nyc build-aot <file.hako> -o app` runs without JIT/VM.
- Basic debug info and minimal unwind.
### 10.5: Python Integration (moved; separate phase)
- Python work is deferred to 10.5 and builds on the plugin/AOT foundation.
## Flags & Compatibility
- `NYASH_USE_PLUGIN_BUILTINS=1` enables plugin path for builtin Boxes.
- `NYASH_JIT_HOSTCALL=1` preserves HostCall path for comparison.
- Call conv alignment: x86_64 SysV, aarch64 AAPCS64, Win64.
- ABI version checks: `nyrt_abi_version()`, `nyplug_*_abi_version()` hard-fail on mismatch.
## Risks & Mitigations
- ABI drift: minimal headers + version checks.
- Linking complexity: start with the smallest set (Array/Print/GC-minimal), expand gradually.
- Performance: keep RO-first; benchmark and fall back to HostCall if needed.
- Windows linkage: prioritize Linux/macOS, then handle Win specifics in a follow-up task.
- JIT coverage: adopt staged lowering (NewBox→birth, Print/Debug no-op) to clear blockers; retain strict skip policy otherwise.
## References
- `c_abi_unified_design.md`
- `implementation_steps.md`
- `../phase-10.5/` (Python integration)
---
Everything is Plugin → unified paths for JIT and AOT.