docs: add MIR13 mode doc and set PHI-off as default; bridge lowering split (if/loop/try); llvmlite resolver stabilization; curated runner default PHI-off; refresh CURRENT_TASK.md
This commit is contained in:
11
docs/development/current/llvm/00-Overview.md
Normal file
11
docs/development/current/llvm/00-Overview.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Self Current Task — Overview (llvm)
|
||||
|
||||
目的
|
||||
- LLVM AOT の Core‑13 前提化を完了し、VM と一致する代表ケースを安定化。
|
||||
- BitOps/Shift の構文着地に合わせ、AOT 側の IR 生成/実行互換を維持。
|
||||
|
||||
指針
|
||||
- Opaque Pointer 対応済(get_element_type 不使用)。
|
||||
- `env.box.new/_i64x` は NyRT shim に統一、引数は i64 正規化。
|
||||
- BinOp/Compare は i64/f64 必要分を網羅する。
|
||||
|
||||
17
docs/development/current/llvm/10-Now.md
Normal file
17
docs/development/current/llvm/10-Now.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Self Current Task — Now (llvm)
|
||||
|
||||
2025‑09‑08:現状と直近タスク
|
||||
- P0 完了(BitOps/Array/Echo/Map 緑)。
|
||||
- VInvoke(by‑name/by‑id vector) で戻り値マッピングの課題(ret_tag=3 でも 0 になる)。
|
||||
|
||||
直近タスク
|
||||
1) VInvoke 戻り値の短期特例:既知メソッド(例: MapBox.get)の整数返りは i64 として保持。
|
||||
2) by‑id vector(`nyash.plugin.invoke_tagged_v_i64`)も同様に統一。
|
||||
3) 受け入れ:
|
||||
- `NYASH_LLVM_VINVOKE_SMOKE=1` → `VInvokeRc: 42`
|
||||
- `NYASH_LLVM_VINVOKE_RET_SMOKE=1` → `Result: 42`
|
||||
|
||||
代表コマンド
|
||||
- `LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix) NYASH_LLVM_BITOPS_SMOKE=1 ./tools/llvm_smoke.sh release`
|
||||
- `NYASH_LLVM_VINVOKE_TRACE=1 NYASH_LLVM_VINVOKE_SMOKE=1 ./tools/llvm_smoke.sh release`
|
||||
|
||||
8
docs/development/current/llvm/20-Decisions.md
Normal file
8
docs/development/current/llvm/20-Decisions.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Self Current Task — Decisions (llvm)
|
||||
|
||||
2025‑09‑08
|
||||
- VInvoke(vector 経路)の戻り値:短期は既知メソッドの整数返りを i64 として保持(Unknown/Box でも整数扱いにする特例)。
|
||||
- 中期は正道へ:
|
||||
- nyash.toml に戻り型ヒント(primitive/handle/f64/bool)を追加し codegen に供給、または
|
||||
- NyRT シムに「期待戻り形式」フラグを追加し codegen から通知。
|
||||
|
||||
9
docs/development/current/llvm/30-Backlog.md
Normal file
9
docs/development/current/llvm/30-Backlog.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Self Current Task — Backlog (llvm)
|
||||
|
||||
短期
|
||||
- VInvoke(vector)の短期特例実装とスモーク更新(by‑name/by‑id 一致)。
|
||||
|
||||
中期
|
||||
- 正道化(戻り型ヒント or NyRT 期待フラグ)と IR 経路の統一。
|
||||
- AOT E2E 強化(plugins あり/なし両系統)。
|
||||
|
||||
16
docs/development/current/main/00-Overview.md
Normal file
16
docs/development/current/main/00-Overview.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Self Current Task — Overview (main)
|
||||
|
||||
目的
|
||||
- main ブランチで Core‑13(MIR13)前提の制御フローを整備し、LLVM/Cranelift(EXE)/VM に綺麗に降ろす土台を完成させる。
|
||||
- 箱言語の既存命令セット(Branch/Jump/Phi 他)を活かし、continue/break を新命令なしで表現する。
|
||||
|
||||
前提と指針
|
||||
- MIR13 前提(純化モードを含む)。
|
||||
- ループは canonical 形(preheader → header → body → latch → header、exit は単一)。
|
||||
- continue/break は分岐のみで表現(continue→ヘッダ/ラッチ、break→単一 exit)。
|
||||
- Verifier(支配関係/SSA)緑を最優先。post‑terminated 後の emit 禁止、合流点を明確化。
|
||||
|
||||
スコープ外
|
||||
- 新規 MIR 命令の追加。
|
||||
- try/finally と continue/break の相互作用(次段)。
|
||||
|
||||
25
docs/development/current/main/10-Now.md
Normal file
25
docs/development/current/main/10-Now.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Self Current Task — Now (main)
|
||||
|
||||
2025‑09‑08:現状と直近タスク
|
||||
- LLVM 側 P0 完了(BitOps/Array/Echo/Map 緑)。VInvoke(by‑name/by‑id vector) は戻り値マッピングの暫定課題を確認中(Decisions 参照)。
|
||||
- selfhosting-dev の作業を main に順次取り込み。VM/MIR 基盤は main で先に整える方針。
|
||||
|
||||
直近タスク(優先)
|
||||
1) continue/break の lowering(Builder 修正のみで表現)
|
||||
- ループ文脈スタック {head, exit} を導入。
|
||||
- continue に遭遇 → head(または latch)へ br を emit し終端。
|
||||
- break に遭遇 → exit へ br を emit し終端。
|
||||
- post‑terminated 後に emit しない制御を徹底。
|
||||
2) ループ CFG の厳密化
|
||||
- 単一 exit ブロックの徹底。
|
||||
- Phi はヘッダでキャリー変数を合流(SSA/支配関係が崩れない形)。
|
||||
3) 検証とスモーク
|
||||
- Verifier 緑(dominance/SSA)。
|
||||
- VM のループ代表(単純/ネスト/早期継続・脱出)。
|
||||
- LLVM/Cranelift EXE に綺麗に降りる(br/phi ベースで問題なし)。
|
||||
|
||||
代表コマンド(例)
|
||||
- ビルド: `cargo build --release`
|
||||
- LLVM smoke: `LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix) NYASH_LLVM_BITOPS_SMOKE=1 ./tools/llvm_smoke.sh release`
|
||||
- VInvoke 調査: `NYASH_LLVM_VINVOKE_TRACE=1 NYASH_LLVM_VINVOKE_SMOKE=1 ./tools/llvm_smoke.sh release`
|
||||
|
||||
9
docs/development/current/main/20-Decisions.md
Normal file
9
docs/development/current/main/20-Decisions.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Self Current Task — Decisions (main)
|
||||
|
||||
2025‑09‑08
|
||||
- ループ制御は既存命令(Branch/Jump/Phi)で表現し、新命令は導入しない。
|
||||
- Builder に loop_ctx({head, exit})を導入し、continue/break を分岐で降ろす。
|
||||
- Verifier の支配関係/SSA を崩さないよう、単一 exit と post‑terminated 後の emit 禁止を徹底。
|
||||
- VInvoke(vector 経路)の戻り値は、短期は「既知メソッドの整数返り」を特例扱いで保持し、
|
||||
中期は nyash.toml の戻り型ヒント or NyRT シムの期待フラグで正道化。
|
||||
|
||||
15
docs/development/current/main/30-Backlog.md
Normal file
15
docs/development/current/main/30-Backlog.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Self Current Task — Backlog (main)
|
||||
|
||||
短期
|
||||
- continue/break 降ろしの実装と単体/統合テストの追加。
|
||||
- Verifier の支配関係/SSA の確認強化(ループ exit 合流の一意性チェック)。
|
||||
- LLVM/Cranelift EXE スモーク(単純/ネスト/継続/脱出)。
|
||||
|
||||
中期
|
||||
- VInvoke(vector)戻り型の正道化(toml 記述 or NyRT 期待フラグ)。
|
||||
- ループ式として値を返す仕様が必要になった場合の設計(現状不要)。
|
||||
|
||||
周辺
|
||||
- selfhosting-dev への取り込みと Ny ツールでの continue/break 使用解禁。
|
||||
- docs 更新(言語ガイドに continue/break の記法・制約を明記)。
|
||||
|
||||
16
docs/development/current/self_current_task/00-Overview.md
Normal file
16
docs/development/current/self_current_task/00-Overview.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Self Current Task — Overview (main)
|
||||
|
||||
目的
|
||||
- main ブランチで Core‑13(MIR13)前提の制御フローを整備し、LLVM/Cranelift(EXE)/VM に綺麗に降ろす土台を完成させる。
|
||||
- 箱言語の既存命令セット(Branch/Jump/Phi 他)を活かし、continue/break を新命令なしで表現する。
|
||||
|
||||
前提と指針
|
||||
- MIR13 前提(純化モードを含む)。
|
||||
- ループは canonical 形(preheader → header → body → latch → header、exit は単一)。
|
||||
- continue/break は分岐のみで表現(continue→ヘッダ/ラッチ、break→単一 exit)。
|
||||
- Verifier(支配関係/SSA)緑を最優先。post‑terminated 後の emit 禁止、合流点を明確化。
|
||||
|
||||
スコープ外
|
||||
- 新規 MIR 命令の追加。
|
||||
- try/finally と continue/break の相互作用(次段)。
|
||||
|
||||
62
docs/development/current/self_current_task/10-Now.md
Normal file
62
docs/development/current/self_current_task/10-Now.md
Normal file
@ -0,0 +1,62 @@
|
||||
# Self Current Task — Now (main)
|
||||
|
||||
2025‑09‑08:現状と直近タスク(selfhosting)
|
||||
|
||||
## 🔴 重要:ループビルダーのバグ発見(詳細調査完了)
|
||||
|
||||
### 問題詳細
|
||||
- **症状**: dep_tree_min_string.nyashがVM実行でエラー `Invalid value: Value %57 not set`
|
||||
- **発生箇所**: `loop(i + m <= n) { if ... { return 1 } i = i + 1 }`のような構造
|
||||
|
||||
### 根本原因(深掘り調査結果)
|
||||
- **ループビルダーの致命的欠陥**: `build_statement`が親ビルダーに単純委譲するだけ
|
||||
```rust
|
||||
// src/mir/loop_builder.rs:397-399
|
||||
fn build_statement(&mut self, stmt: ASTNode) -> Result<ValueId, String> {
|
||||
self.parent_builder.build_expression(stmt) // スコープ管理が失われる!
|
||||
}
|
||||
```
|
||||
- **block_var_mapsの不完全性**: preheaderとlatchの2箇所しか保存しない
|
||||
- ループ内if文で生成される中間ブロックの変数状態が保存されない
|
||||
- 結果として変数の最終値が追跡できない
|
||||
|
||||
### 🎯 「箱を下に積む」解決策
|
||||
Nyashの開発哲学「Everything is Box」に従い、スコープも箱化する:
|
||||
|
||||
1. **ScopeBox構造の導入**
|
||||
```rust
|
||||
struct ScopeBox {
|
||||
block_id: BasicBlockId,
|
||||
variables: HashMap<String, ValueId>,
|
||||
parent: Option<Box<ScopeBox>>, // 親スコープへの参照
|
||||
}
|
||||
```
|
||||
|
||||
2. **全BasicBlockで変数スナップショットを保存**
|
||||
- ブロック遷移時に自動的に変数状態を箱として保存
|
||||
- 階層的な変数解決(現在の箱→親の箱→...)
|
||||
|
||||
3. **最小限の修正案**
|
||||
- `build_statement`でブロック遷移を検出し、変数マップを保存
|
||||
- phi node作成時に適切な箱から値を取得
|
||||
|
||||
## 進捗
|
||||
- MIR ビルダー(self_main)へ Loop CFG/continue/break を移植(単一 exit + 単一 backedge、post‑terminated 禁止)。
|
||||
- dep_tree(string最小版)の実装完了も、上記バグにより実行不可。
|
||||
|
||||
## 直近タスク(優先度順)
|
||||
1. **🔥 ループビルダーのバグ修正**(ブロッカー)
|
||||
- **推奨案**: 「箱を下に積む」アプローチで最小限の修正
|
||||
- `build_statement`を改修してブロック遷移検出
|
||||
- 各ブロックの変数状態を自動的に箱として保存
|
||||
- 実装工数: 中程度(既存構造を活用)
|
||||
- 代替案A: ループビルダーの根本的な再設計(工数大)
|
||||
- 代替案B: 一時的なワークアラウンド(dep_tree_min_string.nyashの書き換え)
|
||||
2. dep-tree 深さ1(直下 include)を children に反映(行ベースの素朴抽出、`//`/`#` 行コメントスキップ)。
|
||||
3. `make dep-tree` 結果の JSON 形を確認(先頭 `{`、必須キー、children のリーフが path のみ)。
|
||||
4. その後、深さ2→任意深さ(max-depth=64、visited)を段階的に解禁。
|
||||
|
||||
代表コマンド
|
||||
- ビルド: `cargo build --release`
|
||||
- 最小 dep-tree: `./target/release/nyash --backend vm apps/selfhost/tools/dep_tree_min_string.nyash`
|
||||
- 生成: `make dep-tree`(`tmp/deps.json`)
|
||||
@ -0,0 +1,9 @@
|
||||
# Self Current Task — Decisions (main)
|
||||
|
||||
2025‑09‑08
|
||||
- ループ制御は既存命令(Branch/Jump/Phi)で表現し、新命令は導入しない。
|
||||
- Builder に loop_ctx({head, exit})を導入し、continue/break を分岐で降ろす。
|
||||
- Verifier の支配関係/SSA を崩さないよう、単一 exit と post‑terminated 後の emit 禁止を徹底。
|
||||
- VInvoke(vector 経路)の戻り値は、短期は「既知メソッドの整数返り」を特例扱いで保持し、
|
||||
中期は nyash.toml の戻り型ヒント or NyRT シムの期待フラグで正道化。
|
||||
|
||||
15
docs/development/current/self_current_task/30-Backlog.md
Normal file
15
docs/development/current/self_current_task/30-Backlog.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Self Current Task — Backlog (main)
|
||||
|
||||
短期
|
||||
- continue/break 降ろしの実装と単体/統合テストの追加。
|
||||
- Verifier の支配関係/SSA の確認強化(ループ exit 合流の一意性チェック)。
|
||||
- LLVM/Cranelift EXE スモーク(単純/ネスト/継続/脱出)。
|
||||
|
||||
中期
|
||||
- VInvoke(vector)戻り型の正道化(トムル記述 or NyRT 期待フラグ)。
|
||||
- ループ式として値を返す仕様が必要になった場合の設計(現状不要)。
|
||||
|
||||
周辺
|
||||
- selfhosting-dev への取り込みと Ny ツールでの continue/break 使用解禁。
|
||||
- docs 更新(言語ガイドに continue/break の記法・制約を明記)。
|
||||
|
||||
39
docs/development/current/selfhost/dep_tree_min_string.md
Normal file
39
docs/development/current/selfhost/dep_tree_min_string.md
Normal file
@ -0,0 +1,39 @@
|
||||
# Include-only Dependency Tree (Phase 0)
|
||||
|
||||
Goal
|
||||
- Build a dependency tree using only Ny (no Array/Map), scanning source text for `include "..."`, and output stable JSON.
|
||||
|
||||
Scope (Phase 0)
|
||||
- Only `include` is supported. `using/module/import` are out of scope.
|
||||
- Runner bridge: `NYASH_DEPS_JSON=<path>` is read and logged only (no behavior change).
|
||||
|
||||
Tool
|
||||
- `apps/selfhost/tools/dep_tree_min_string.nyash`
|
||||
- Recursively reads source files, scans for `include "path"` outside of strings and comments.
|
||||
- Comments: `//` and `#` (line comments) are ignored.
|
||||
- Strings: `"..."` with `\"` escapes are honored.
|
||||
- Cycles: detected via a simple stack string; when detected, the child appears as a leaf node with empty `includes`/`children`.
|
||||
|
||||
Output format
|
||||
```
|
||||
{ "version": 1,
|
||||
"root_path": "<entry>",
|
||||
"tree": {
|
||||
"path": "<file>", "includes": ["..."], "children": [ <node> ]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Acceptance criteria
|
||||
- Running `make dep-tree` produces `tmp/deps.json` whose first non-empty line starts with `{` and conforms to the format above.
|
||||
- The scanner does not pick includes inside strings or comments.
|
||||
- Cycles do not crash or loop; the repeated node is represented as a leaf.
|
||||
|
||||
Examples
|
||||
- Root: `apps/selfhost/smokes/dep_smoke_root.nyash` (includes `dep_smoke_child.nyash`)
|
||||
- Cycle: `apps/selfhost/smokes/dep_smoke_cycle_a.nyash` ↔ `dep_smoke_cycle_b.nyash`
|
||||
|
||||
Validation (examples)
|
||||
- `echo apps/selfhost/smokes/dep_smoke_root.nyash | ./target/release/nyash --backend vm apps/selfhost/tools/dep_tree_min_string.nyash`
|
||||
- `make dep-tree`
|
||||
|
||||
46
docs/development/engineering/box_first_enforcement.md
Normal file
46
docs/development/engineering/box_first_enforcement.md
Normal file
@ -0,0 +1,46 @@
|
||||
# Box-First Enforcement Kit(運用メモ)
|
||||
|
||||
このプロジェクトでは「箱を先に積む(Box-First)」を最優先にし、実装速度のボトルネックを“下の箱(境界・足場)不足”で詰まらせない方針を採用します。
|
||||
|
||||
## PR テンプレ(.github/pull_request_template.md)
|
||||
PR で以下のチェックを通すことを習慣化します。
|
||||
|
||||
```
|
||||
### Box-First Check
|
||||
- [ ] 境界は1箇所に集約(変換はここだけ)
|
||||
- [ ] 設定は JitConfigBox 経由(env直読みなし)
|
||||
- [ ] フォールバック常設(panic→VM/CPython)
|
||||
- [ ] 観測追加(stats.jsonl / CFG dot)
|
||||
|
||||
### DoD(完了条件)
|
||||
- [ ] ゴールデン3件(成功/失敗/境界)更新
|
||||
- [ ] 回帰CI green(env直読み検出なし)
|
||||
- [ ] stats: fallback率・理由が記録される
|
||||
```
|
||||
|
||||
## CI ガード(.github/workflows/box_first_guard.yml)
|
||||
現状は「アドバイザリ(continue-on-error)」で運用。違反箇所を可視化します。
|
||||
|
||||
- 直の `std::env::var(` を `src/jit/config.rs` と `src/jit/rt.rs` 以外で禁止(アドバイザリ)
|
||||
- B1 署名のスイッチ箇所以外での `B1` 文字列の出現を禁止(アドバイザリ)
|
||||
- 将来的に `stats.jsonl` 出力の有無も検査予定
|
||||
|
||||
必要になったら `continue-on-error: false` にして強制化します。
|
||||
|
||||
## “下の箱”不足の早期警報(運用ルール)
|
||||
進みが悪い/壊れやすい兆候が出たら、まず以下から最小1個だけ足して再挑戦:
|
||||
|
||||
- BoundaryBox(変換一本化)
|
||||
- JitConfigBox(設定の箱)
|
||||
- ObservabilityBox(json/dot出力)
|
||||
- Effect Token(副作用の明示)
|
||||
|
||||
## Box-Fitness ミニ指標(PRに1行)
|
||||
|
||||
- `boundary_changes=1`(変換点の個数)
|
||||
- `env_reads=0`(env直読の個数)
|
||||
- `fallback_paths>=1`(逃げ道の数)
|
||||
- `stats_fields>=5`(記録の粒度)
|
||||
|
||||
この4つを満たせていれば「箱の足場は十分」の合図。
|
||||
|
||||
47
docs/development/issues/arraybox_invalid_args.md
Normal file
47
docs/development/issues/arraybox_invalid_args.md
Normal file
@ -0,0 +1,47 @@
|
||||
# ArrayBox get/set -> Invalid arguments (plugin side)
|
||||
|
||||
Status: open
|
||||
|
||||
Summary
|
||||
|
||||
- Error messages observed during AOT/LLVM smoke that touches ArrayBox:
|
||||
- "Plugin invoke error: ArrayBox.set -> Invalid arguments"
|
||||
- "Plugin invoke error: ArrayBox.get -> Invalid arguments"
|
||||
- VInvoke(MapBox) path is stable; issue is isolated to ArrayBox plugin invocation.
|
||||
|
||||
Environment
|
||||
|
||||
- LLVM 18 / inkwell 0.5.0 (llvm18-0)
|
||||
- nyash-rust with Phase 11.2 lowering
|
||||
- tools/llvm_smoke.sh (Array smoke is gated via NYASH_LLVM_ARRAY_SMOKE=1)
|
||||
|
||||
Repro
|
||||
|
||||
1) Enable array smoke explicitly:
|
||||
- `NYASH_LLVM_ARRAY_SMOKE=1 ./tools/llvm_smoke.sh release`
|
||||
2) Observe plugin-side errors for ArrayBox.get/set.
|
||||
|
||||
Expected
|
||||
|
||||
- Array get/set should be routed to NyRT safety shims (`nyash_array_get_h/set_h`) with handle + index/value semantics that match the core VM.
|
||||
|
||||
Observed
|
||||
|
||||
- Plugin path is taken for ArrayBox.get/set and the plugin rejects arguments as invalid.
|
||||
|
||||
Notes / Hypothesis
|
||||
|
||||
- LLVM lowering is intended to map ArrayBox.get/set to NyRT shims. The plugin path should not be engaged for array core operations.
|
||||
- If by-name fallback occurs (NYASH_LLVM_ALLOW_BY_NAME=1), the array methods might route to plugin-by-name with i64-only ABI and mismatched TLV types (index/value encoding).
|
||||
|
||||
Plan
|
||||
|
||||
1) Confirm lowering branch for BoxCall(ArrayBox.get/set) always selects NyRT shims under LLVM, regardless of by-name flag.
|
||||
2) If by-name fallback is unavoidable in current scenario, ensure integer index/value are encoded/tagged correctly (tag=3 for i64) and receiver is a handle.
|
||||
3) Add a targeted smoke (OFF by default) that calls only `get/set/length` and prints deterministic result.
|
||||
4) Optional: Add debug env `NYASH_PLUGIN_TLV_DUMP=1` to print decoded TLV for failing invokes to speed diagnosis.
|
||||
|
||||
Workarounds
|
||||
|
||||
- Keep `NYASH_LLVM_ARRAY_SMOKE=0` in CI until fixed.
|
||||
|
||||
40
docs/development/issues/llvm_binop_string_mismatch.md
Normal file
40
docs/development/issues/llvm_binop_string_mismatch.md
Normal file
@ -0,0 +1,40 @@
|
||||
# LLVM lowering: string + int causes binop type mismatch
|
||||
|
||||
Status: open
|
||||
|
||||
Summary
|
||||
|
||||
- When compiling code that concatenates a string literal with a non-string (e.g., integer), LLVM object emission fails with a type mismatch in binop.
|
||||
- Example from `apps/ny-map-llvm-smoke/main.nyash`: `print("Map: v=" + v)` and `print("size=" + s)`.
|
||||
|
||||
Environment
|
||||
|
||||
- LLVM 18 / inkwell 0.5.0
|
||||
- Phase 11.2 lowering
|
||||
|
||||
Repro
|
||||
|
||||
1) Run: `NYASH_LLVM_ARRAY_SMOKE=1 ./tools/llvm_smoke.sh release` (or build/link the map smoke similarly)
|
||||
2) Observe: `❌ LLVM object emit error: binop type mismatch`
|
||||
|
||||
Expected
|
||||
|
||||
- String concatenation should be lowered to a safe runtime shim (e.g., NyRT string builder or `nyash_string_concat`) that accepts `(i8* string, i64/int)` and returns `i8*`.
|
||||
|
||||
Observed
|
||||
|
||||
- `+` binop is currently generated as integer addition for non-float operands, leading to a type mismatch when one side is a pointer (string) and the other is integer.
|
||||
|
||||
Plan
|
||||
|
||||
1) Introduce string-like detection in lowering: if either operand is `String` (or pointer from `nyash_string_new`), route to a NyRT concat shim.
|
||||
2) Provide NyRT APIs:
|
||||
- `nyash.string.concat_ss(i8*, i8*) -> i8*`
|
||||
- `nyash.string.concat_si(i8*, i64) -> i8*`
|
||||
- Optional: `concat_sf`, `concat_sb` (format helpers)
|
||||
3) As an interim simplification for smoke, emit `print("..." )` in two steps to avoid mixed-type `+` until the concat shim is ready.
|
||||
|
||||
CI
|
||||
|
||||
- Keep `apps/ny-llvm-smoke` OFF by default. Re-enable once concat shim lands and binop lowering is updated.
|
||||
|
||||
26
docs/development/issues/parser_unary_asi_alignment.md
Normal file
26
docs/development/issues/parser_unary_asi_alignment.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Parser/Bridge: Unary and ASI Alignment (Stage‑2)
|
||||
|
||||
Context
|
||||
- Rust parser already parses unary minus with higher precedence (parse_unary → factor → term) but PyVM pipe path did not reflect unary when emitting MIR JSON for the PyVM harness.
|
||||
- Bridge(JSON v0 path)is correct for unary by transforming to `0 - expr` in the Python MVP, but Rust→PyVM path uses `emit_mir_json_for_harness` which skipped `UnaryOp`.
|
||||
- ASI in arguments split over newlines is not yet supported in Rust (e.g., newline inside `(..., ...)` after a comma in a chained call), while Bridge/Selfhost cover ASI for statements and operators.
|
||||
|
||||
Proposed minimal steps
|
||||
- Unary for PyVM harness:
|
||||
- Option A (preferred later): extend `emit_mir_json_for_harness[_bin]` to export a `unop` instruction and add PyVM support. Requires schema change.
|
||||
- Option B (quick): legalize unary `Neg` to `Const(0); BinOp('-', 0, v)` before emitting, by inserting a synthetic temporary. This requires value id minting in emitter to remain self‑consistent, which we currently do not have. So Option B is non‑trivial without changing emitter capabilities.
|
||||
- Decision: keep Bridge JSON v0 path authoritative for unary tests; avoid relying on Rust→PyVM for unary until we add a `unop` schema.
|
||||
|
||||
- ASI inside call arguments (multi‑line):
|
||||
- Keep as NOT SUPPORTED for Rust parser in Phase‑15. Use single‑line args in tests.
|
||||
- Selfhost/Bridge side already tolerate semicolons optionally after statements; operator‑continuation is supported in Bridge MVP.
|
||||
|
||||
Tracking
|
||||
- If we want to support unary in the PyVM harness emitter:
|
||||
- Add `unop` to tools/pyvm_runner.py and src/llvm_py/pyvm/vm.py (accept `{op:"unop", kind:"neg", src: vid, dst: vid}`)
|
||||
- Teach emitters to export `UnaryOp` accordingly (`emit_mir_json_for_harness[_bin]`).
|
||||
|
||||
Status
|
||||
- Bridge unary: OK(ny_stage2_bridge_smoke includes unary)
|
||||
- Rust→PyVM unary: not supported in emitter; will stay out of CI until schema update
|
||||
- ASI in args over newline: not supported by Rust parser; keep tests single‑line for now
|
||||
50
docs/development/mir/MIR13_MODE.md
Normal file
50
docs/development/mir/MIR13_MODE.md
Normal file
@ -0,0 +1,50 @@
|
||||
MIR13 Mode (PHI-off by default)
|
||||
|
||||
Overview
|
||||
- Goal: Stabilize execution by turning off PHI emission in the Bridge/Builder and letting the LLVM (llvmlite) layer synthesize PHIs as needed.
|
||||
- Default: MIR13 is ON by default (PHI-off). Use env flags to flip.
|
||||
|
||||
Why
|
||||
- Fewer SSA obligations in the front-end (Bridge/Builder) reduces CFG corner cases (short‑circuit, nested if/loop merges).
|
||||
- Centralizes SSA invariants in a single place (llvmlite resolver/finalizer), improving correctness and maintenance.
|
||||
|
||||
Flags and Behavior
|
||||
- NYASH_MIR_NO_PHI (default: 1)
|
||||
- 1: Bridge/Builder emit edge copies instead of PHIs at merges (MIR13).
|
||||
- 0: Bridge/Builder may emit PHIs (MIR14 experimental).
|
||||
- NYASH_VERIFY_ALLOW_NO_PHI (default: 1)
|
||||
- Relaxes verifier checks that assume PHIs at merges.
|
||||
- NYASH_LLVM_USE_HARNESS=1 (AOT via llvmlite harness)
|
||||
- Resolver/finalizer synthesize PHIs at block heads when needed.
|
||||
|
||||
LLVM (llvmlite) Responsibilities
|
||||
- setup_phi_placeholders(): predeclare JSON‑provided PHIs and collect incoming metadata.
|
||||
- block_end_values: snapshot per block end to materialize predecessor values (dominance‑safe).
|
||||
- finalize_phis(): wire incoming edges for declared PHIs at block heads.
|
||||
- Resolver.resolve_i64():
|
||||
- single‑pred: take predecessor end value;
|
||||
- multi‑pred + declared PHI: reuse placeholder at block head;
|
||||
- multi‑pred + no PHI: synthesize a localization PHI at the current block head (MIR13 compatibility);
|
||||
- avoids reusing non‑dominating vmap values across blocks.
|
||||
|
||||
Bridge/Builder (JSON v0) Behavior
|
||||
- If/Loop/Try are lowered without PHIs when MIR13 is ON; merges are performed with edge copies (merge_var_maps) and the final value is reconstituted by the LLVM layer if needed.
|
||||
- Helper split for readability (no behavior change):
|
||||
- lowering/{if_else.rs, loop_.rs, try_catch.rs, merge.rs}
|
||||
|
||||
Testing
|
||||
- Curated LLVM (default = PHI‑off):
|
||||
- tools/smokes/curated_llvm.sh (use --phi-on to exercise MIR14)
|
||||
- PHI invariants/parity (AOT vs PyVM):
|
||||
- tools/pyvm_vs_llvmlite.sh (default compares exit code; use CMP_STRICT=1 for stdout+exit)
|
||||
- Bridge/PyVM:
|
||||
- tools/selfhost_stage2_bridge_smoke.sh
|
||||
|
||||
How to Force PHI‑on (MIR14 experimental)
|
||||
- Set: NYASH_MIR_NO_PHI=0 and run tools/smokes/curated_llvm.sh --phi-on
|
||||
- Known: loop_if_phi may trip dominance issues in PHI‑on; MIR13 is the recommended default.
|
||||
|
||||
Known Limitations (current)
|
||||
- No full tracing GC; object lifetime is managed via handle registries and Arc lifetimes.
|
||||
- PHI‑on path is still being refined for some control‑flow patterns.
|
||||
|
||||
45
docs/development/refactoring/candidates_phase15.md
Normal file
45
docs/development/refactoring/candidates_phase15.md
Normal file
@ -0,0 +1,45 @@
|
||||
# Refactoring Candidates — Phase 15 (Mainline only)
|
||||
|
||||
Scope: PyVM/LLVM/Runner mainline. JIT/Cranelift is explicitly out of scope for this pass.
|
||||
|
||||
Goals
|
||||
- Improve maintainability and locality of logic in the primary execution paths.
|
||||
- Reduce ad-hoc env access; prefer `src/config/env.rs` helpers.
|
||||
- Clarify control-flow lowering responsibilities in LLVM codegen.
|
||||
|
||||
High‑Value Candidates
|
||||
- Runner CLI directives
|
||||
- Extract header‐comment directives scanning from `runner/mod.rs` → `runner/cli_directives.rs` (done).
|
||||
- Next: Move using/alias/env merge traces behind a `runner::trace` helper to keep `mod.rs` slim.
|
||||
|
||||
- LLVM codegen structure
|
||||
- Introduce `instructions/terminators.rs` (return/jump/branch emit glue) and `instructions/select.rs` (cond/short‑circuit pre‑normalize). Initially re‑export from `flow.rs`; later migrate implementations.
|
||||
- Keep `function.rs` focused on BB visitation + delegations (no heavy logic inline).
|
||||
|
||||
- VM dispatch integration
|
||||
- Gradually route the big `match` in VM through `backend/dispatch.rs` (already scaffolded). Start with side‑effect‑free ops (Const/Compare/TypeOp) to de‑risk.
|
||||
- Add opt‑in flag `NYASH_VM_USE_DISPATCH=1` to gate behavior during the transition.
|
||||
|
||||
- Env access centralization
|
||||
- Replace scattered `std::env::var("NYASH_*")` with `config::env` getters in hot paths (VM tracing, GC barriers, resolver toggles).
|
||||
- Add tiny wrappers where a tri‑state is needed (off/soft/on).
|
||||
|
||||
- MIR builder granularity (non‑breaking)
|
||||
- Extract loop helpers: `mir/builder/loops.rs` (headers/exits/latch snapshot utilities).
|
||||
- Extract phi helpers: `mir/builder/phi.rs` (if‑else merge, header normalize for latch).
|
||||
|
||||
Low‑Risk Cleanups
|
||||
- Tools scripts: dedupe `tools/*smoke*.sh` into `tools/smokes/` with common helpers (env, timeout, exit filtering).
|
||||
- Tests naming: prefer `*_test.rs` and `apps/tests/*.nyash` consistency for smokes.
|
||||
- Logging: add `NYASH_CLI_VERBOSE` guards consistently; provide `runner::trace!(...)` macro for concise on/off.
|
||||
|
||||
Suggested Sequencing
|
||||
1) Runner small extractions (directives/trace). Validate with existing smokes.
|
||||
2) LLVM `terminators.rs`/`select.rs` scaffolding + staged migration; zero behavior change initially.
|
||||
3) VM dispatch gating: land flag and migrate 3–5 simple opcodes; parity by unit tests.
|
||||
4) MIR builder helpers: extract without API changes; run PyVM/LLVM curated smokes.
|
||||
|
||||
Notes
|
||||
- Keep JIT/Cranelift untouched in this phase to avoid drift from the mainline policy.
|
||||
- Prefer file‑level docs on new modules to guide incremental migration.
|
||||
|
||||
@ -33,7 +33,7 @@ Avoid: deep AOT emission/linking, cross-platform toolchain work, or scope creep
|
||||
## Deliverables
|
||||
|
||||
- `tools/aot_plan/` Nyash scripts and helpers
|
||||
- `docs/specs/aot_plan_v1.md` (lightweight schema)
|
||||
- `docs/design/aot-plan-v1.md` (lightweight schema)
|
||||
- Compiler entry to import AOT-Plan → MIR13 (feature-gated)
|
||||
- 3 smokes + 1 golden JSON sample
|
||||
|
||||
@ -86,4 +86,3 @@ Key takeaways aligned into this document:
|
||||
- Importer can read that JSON and construct MIR13 module(s) without panics
|
||||
- VM runs those modules and matches expected string/number results for trivial bodies
|
||||
- Events present when enabled; counters reflect plan/import activity; no AOT emit performed
|
||||
|
||||
|
||||
Reference in New Issue
Block a user