Major changes: - Update all MIR13 references to MIR14 throughout paper-a-mir13-ir-design/ - Add evolution history: 27 → 13 → 14 instructions (UnaryOp restoration) - Create new paper-d-ssa-construction/ for SSA implementation struggles - Add PAPER_INDEX.md consolidating ChatGPT5's 3-paper analysis MIR14 updates: - README.md: Add instruction evolution timeline - abstract.md: Emphasize practical balance over pure minimalism - main-paper*.md: Update titles and core concepts - MIR13_CORE13_SPEC.md: Add UnaryOp to instruction list - chapters/01-introduction.md: Reframe as "14-Instruction Balance" - RENAME_NOTE.md: Document folder naming consideration SSA paper structure: - README.md: Paper overview and positioning - current-struggles.md: Raw implementation challenges - technical-details.md: BuilderCursor, Sealed SSA, type normalization - abstract.md: English/Japanese abstracts LoopForm experiments continue in parallel (minor adjustments to detection). 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
322 lines
24 KiB
Markdown
322 lines
24 KiB
Markdown
# Current Task (2025-09-11) — Phase 15 LLVM‑only
|
||
|
||
Summary
|
||
- LLVM is the authoritative path; VM/Cranelift/Interpreter are not MIR14‑ready.
|
||
- Keep fallbacks minimal; fix MIR annotations first.
|
||
- ExternCall(console/debug) auto‑selects ptr/handle by IR type.
|
||
- StringBox NewBox i8* fast path; print/log choose automatically.
|
||
- Implement multi-function lowering and Call lowering for MIR14.
|
||
|
||
Update — 2025-09-12 (LLVM flow + BB naming)
|
||
- codegen/mod.rs match arms cleanup:
|
||
- BinOp: unify to instructions::lower_binop(...)
|
||
- BoxCall: delegate solely to instructions::lower_boxcall(...); removed unreachable legacy code
|
||
- BasicBlock naming made function‑scoped and unique: create_basic_blocks now prefixes with function label (e.g., Main_join_2_bb23)
|
||
- Terminator fallback: when a MIR block lacks a terminator, emit a conservative jump to the next block (or entry if last)
|
||
- Build: cargo build --features llvm passes
|
||
- AOT emit status: improved (bb name collision resolved), but verifier still flags a missing terminator in Main.esc_json/1 (e.g., Main_esc_json_1_bb88)
|
||
- Likely cause: flow lowering edge case; MIR dump is correct, LLVM lowering missed a terminator
|
||
- Plan below addresses this with hardened flow lowering and instrumentation
|
||
|
||
Hot Update — 2025-09-12 (quick)
|
||
- Flow: moved function verify to post‑lower; added terminator fallback only when MIR lacks one
|
||
- PHI(sealed): seal_block isolates cast insertion by saving/restoring the insertion point in the predecessor block and wires incoming only for the current predecessor (zero-synth as a last resort, logged). Avoids duplicate incoming and builder state leaks.
|
||
- Compare: allow ptr↔int comparisons for all ops via ptr→i64 bridge
|
||
- Strings: substring now accepts i64(handle) receiver (i2p); len/lastIndexOf stable
|
||
- Arrays: method_id未注入でも get/set/push/length を NyRT 経由で処理
|
||
- BoxCall: println→env.console.log フォールバック、同モジュール関数呼び出し/名前指定 invoke_by_name 経路を追加
|
||
- PHI: 文字列/Box等を含む場合は i8* を選択する型推定に改善
|
||
- 現在のブロッカー: esc_json/1 で「phi incoming value missing」
|
||
- 対応: emit_jump/emit_branch の incoming 配線をログ付きで点検し、値未定義箇所(by‑name/fast‑path戻り)を補完
|
||
|
||
Hot Repro — esc_json/1 PHI 配線(2025‑09‑12)
|
||
- 対象: apps/selfhost/tools/dep_tree_min_string.nyash
|
||
- 実行(LLVM):
|
||
- Sealed OFF: `NYASH_CLI_VERBOSE=1 NYASH_LLVM_TRACE_PHI=1 NYASH_DISABLE_PLUGINS=1 ./target/release/nyash --backend llvm apps/selfhost/tools/dep_tree_min_string.nyash`
|
||
- Sealed ON: `NYASH_LLVM_PHI_SEALED=1 NYASH_CLI_VERBOSE=1 NYASH_LLVM_TRACE_PHI=1 NYASH_DISABLE_PLUGINS=1 ./target/release/nyash --backend llvm apps/selfhost/tools/dep_tree_min_string.nyash`
|
||
- 観測:
|
||
- Sealed OFF: Main.esc_json/1 で PHI incoming 不足(`PHINode should have one entry for each predecessor`)。
|
||
- Sealed ON: `phi incoming (seal) value missing`(pred側終端値の取得ができていない)。別途 Terminator 欠落も検知→終端フォールバックを実装して解消済み。
|
||
- 原因仮説: Sealed ON で `seal_block` が pred終端時点の値(value_at_end_of_block)ではなく関数作業用 vmap を参照しているため、未定義扱いになっている。
|
||
|
||
Next Steps(Sealed SSA 段階導入)
|
||
1) block_end_values を導入し、各BB降下完了時に vmap スナップショットを保存。`seal_block` は pred のスナップショットから in_vid を取得。
|
||
2) Sealed=ON で apps/selfhost/tools/dep_tree_min_string.nyash を再確認(PHIログ=ON)。OFF/ON の一致を比較し、incoming が pred数で揃うことを検証。
|
||
3) 足りない型整合(String/Box/Array→i8*)があれば `coerce_to_type` を拡張。
|
||
4) グリーン後、Sealed をデフォルトONにする前にスモーク一式で回帰確認。
|
||
|
||
TODO — Sealed SSA 段階導入(実装タスク)
|
||
- [x] block_end_values 追加(LLVM Lower 内の per-BB 終端スナップショット)
|
||
- 追加先: `src/backend/llvm/compiler/codegen/mod.rs`
|
||
- 形式: `HashMap<BasicBlockId, HashMap<ValueId, BasicValueEnum>>`
|
||
- タイミング: 各BBの命令をすべて Lower した「直後」、終端命令を発行する「直前」に `vmap.clone()` を保存
|
||
- 目的: `seal_block` で pred 終端時点の値を安定取得する(現在の vmap 直接参照をやめる)
|
||
- [x] `seal_block` をスナップショット参照に切替
|
||
- 対象: `src/backend/llvm/compiler/codegen/instructions/flow.rs::seal_block`
|
||
- 取得: `block_end_values[bid].get(in_vid)` を用いて `val` を取得
|
||
- フォールバック: もしスナップショットが無ければ(例外ケース)従来の `vmap` を参照し、警告ログを出す
|
||
- ログ: `NYASH_LLVM_TRACE_PHI=1` 時に `[PHI] sealed add pred_bb=.. val=.. ty=.. (snapshot)` と明示
|
||
- [x] 非 sealed 経路の維持(回帰防止)
|
||
- `emit_jump/emit_branch` は sealed=OFF の時のみ incoming を追加(現状仕様を維持)
|
||
- sealed=ON の時は incoming 配線は一切行わず、`seal_block` のみで完結
|
||
- [x] 型整合(coerce)の継続強化
|
||
- 対象: `src/backend/llvm/compiler/codegen/instructions/flow.rs::coerce_to_type`
|
||
- 方針: PHI の型は i8* 優先(String/Box/Array を含む場合)。ptr/int 混在は明示 cast で橋渡し
|
||
- 検討: i1 ブリッジ(bool)の zext/trunc の置き場所は PHI 外側に寄せる(必要時)
|
||
- [ ] 代表スモークの回帰
|
||
- 再現対象: `apps/selfhost/tools/dep_tree_min_string.nyash`
|
||
- 実行: `NYASH_LLVM_PHI_SEALED=1 NYASH_LLVM_TRACE_PHI=1 NYASH_DISABLE_PLUGINS=1 ./target/release/nyash --backend llvm apps/selfhost/tools/dep_tree_min_string.nyash`
|
||
- 期待: `PHINode should have one entry for each predecessor` が解消し、OFF/ON で等価な結果
|
||
|
||
補足(実装メモ)
|
||
- `block_end_values` の寿命はコード生成のライフタイムに束縛されるため、`BasicValueEnum<'ctx>` の所有は問題なし(`Context` が生きている間は有効)
|
||
- 収集は `compile_function` の BB ループ内で行い、`phis_by_block` と同スコープで管理すると取り回しが良い
|
||
- 将来の拡張として `value_at_end_of_block(var, bb)` ヘルパを導入し、sealed/unsealed を内部で吸収する API 化を検討
|
||
|
||
Hot Plan — Structured Terminators(RAII BuilderCursor)
|
||
- 目的: 末端処理を設計で保証(未終端や終端後挿入を構造で不可能に)し、終端まわりのフォールバック重複を削減する
|
||
- ポリシー: 「開いているブロックにのみ命令を挿入できる。終端を置いた瞬間に閉じる。閉じたブロックへの挿入は即panic」
|
||
|
||
TODO — BuilderCursor 導入と段階適用
|
||
- [ ] 新規: `builder_cursor.rs` を追加(`BuilderCursor` / `BlockState` / `with_block`)
|
||
- API: `at_end(bid, llbb)`, `emit_instr(f)`, `emit_term(f)`, `assert_open(bid)`
|
||
- 実装: inkwell::Builder を参照で保持し、`closed_by_bid: HashMap<BasicBlockId,bool>` を管理
|
||
- [ ] 既存終端APIを置換
|
||
- 変更: `emit_return / emit_jump / emit_branch` を `BuilderCursor::emit_term` 経由に
|
||
- 呼び出し元: codegen/mod.rs 側から `&mut BuilderCursor` を渡す
|
||
- [ ] 位置ずれの解消(最小)
|
||
- cast 等の補助命令は「pred終端直前」へ(position_before)を維持
|
||
- 既存の entry_builder 経路で位置ずれが起きないよう、必要箇所のみ `with_block` を使用
|
||
- [ ] 関数終端の最終保証
|
||
- `finalize_function`: 未終端BBには `unreachable` を挿入(最後の砦)
|
||
- [ ] 代表スモークの回帰(Sealed=ON)
|
||
- 期待: 未終端エラー・終端後挿入エラーの消滅。PHI配線は snapshot により安定
|
||
|
||
Note
|
||
- フェーズ1では「終端APIと位置ずれの構造化」の最小適用に留め、フォールバック(最終unreachable)を併用
|
||
- フェーズ2で with_block の適用範囲を広げ、余剰なガード・分岐フォールバックを削除していく(ソースは小さくシンプルに)
|
||
|
||
Progress — 2025-09-12(Sealed + RAII 最小導入)
|
||
- Sealed: block_end_values(BB内定義のみをフィルタ)を導入し、incoming は pred 終端時点の snapshot から配線
|
||
- Cast 挿入: pred 終端直前(position_before)に限定、終端後挿入を回避
|
||
- BuilderCursor: emit_return/emit_jump/emit_branch を構造化(closed ブロックへの挿入を禁止)
|
||
- Call/BoxCall: 実引数を callee の型へ coerce(i2p/p2i/zext/trunc 等)
|
||
- Const String: nyash_string_new を entry ブロックで Hoist し、支配性違反を解消
|
||
- Fallback(暫定): PHI 欠落や lhs/rhs missing に対し型ゼロを合成して進行(ログ付)
|
||
|
||
Open Issues(要対応)
|
||
- Sealed配線: 一部合流で『各predに1 incoming』が未充足(synth で穴埋め中)
|
||
- Dominance: ループ/合流で稀に「Instruction does not dominate all uses!」が再出
|
||
- 位置ずれ: Sealed 内の cast 生成が builder の挿入位置に影響する可能性(要隔離)
|
||
|
||
Next TODO(優先度順)
|
||
1) flow::seal_block の挿入位置を完全隔離
|
||
- 専用Builder or Cursor.with_block で pred 終端直前に cast を挿入(メインbuilder位置を汚さない)
|
||
2) preds_by_block を構築し、PHI incoming を実CFGの pred へ正規リマップ
|
||
- snapshot から in_vid を取得し、pred 数ぶんを網羅(synth は最終手段)
|
||
- 検証: incoming=pred数 を assert/ログ
|
||
3) with_block の適用拡大(entry_builder/配列alloca等のホットスポット)
|
||
- 位置ずれ温床を解消 → 余剰ガード/フォールバックを削除(コード縮小)
|
||
4) 回帰: Sealed=ON/OFF の一致確認(dep_tree_min_string ほか代表)
|
||
- NYASH_LLVM_TRACE_PHI=1 で配線ログ確認、ゼロ合成が消えることを目標
|
||
|
||
Plan — PHI/SSA Hardening (Sealed SSA)
|
||
- Sealed SSA 入れ替え(安全に段階導入)
|
||
- Blockごとに `sealed: bool` と `incomplete_phis: Map<Var, Phi>` を保持
|
||
- 値取得APIを一本化: `value_at_end_of_block(var, bb)` で vmap を再帰解決+仮PHI生成
|
||
- `seal(bb)` で pred 確定後に incomplete_phis を埋め、`fold_trivial_phi` で単純化
|
||
- 配線の方向を整理
|
||
- emit_jump/emit_branch では直接 incoming を配線しない(to 側で必要時に解決)
|
||
- fast/slow 両レーンは同じ Var に書く(合流で拾えるように)
|
||
- 型の前処理を一箇所へ
|
||
- Bool は i1 固定(必要なら zext は PHI 外側)
|
||
- ptr/int 混在禁止。必要箇所で ptrtoint/inttoptr を生成し、PHI では等型を保証
|
||
- 計測と検証
|
||
- `seal(bb)` 時に incomplete_phis が残れば panic(場所特定)
|
||
- `[PHI] add incoming var=.. pred=.. ty=..` をデバッグ出力
|
||
- verify は関数降下完了後に 1 回
|
||
- フォールバックのゲート
|
||
- by-name invoke は環境変数で明示ON(デフォルトOFF)にする方針に切替(ノイズ低減)
|
||
|
||
Refactor Policy
|
||
- 慌てず小さな箱(モジュール)を積む。必要なら随時リファクタリングOK。
|
||
- 代替案(必要時のみ): llvmlite の薄層で最低限の命令面を実装し、dep_tree_min_string を先に通す。
|
||
|
||
Done (today)
|
||
- BoxCall legacy block removed in LLVM codegen; delegation only.
|
||
- BinOp concat safety: minimal fallback for i8*+i64/i64+i8* when both sides are annotated String/Box → from_i8_string + concat_hh; otherwise keep concat_ss/si/is.
|
||
- String fast‑path: length/len lowered to nyash.string.len_h (handle), with ptr→handle bridge when needed.
|
||
- Map core‑first: NewBox(MapBox) routes via nyash.env.box.new("MapBox") → NyRT特例でコアMapを生成。LLVM BoxCall(Map.size/get/set/has) は NyRT の nyash.map.* を呼ぶ。
|
||
- Plugin強制スイッチ: NYASH_LLVM_FORCE_PLUGIN_MAP=1 で MapBox のプラグイン経路を明示切替(デフォルトはコア)。
|
||
- Docs: ARCHITECTURE/LOWERING_LLVM/EXTERNCALL/PLUGIN_ABI を追加・整備。
|
||
- Smokes: plugin‑ret green, map smoke green(core‑first)。
|
||
- ExternCall micro‑split 完了: `externcall.rs` を `externcall/` ディレクトリ配下に分割し、
|
||
`console.rs`(console/debug)と `env.rs`(future/local/box)に切り出し。
|
||
ディスパッチは `externcall/mod.rs` に集約(挙動差分なし・0‑diff)。
|
||
- String Fast‑Path 追加(LLVM/NYRT): `substring(start,end)` と `lastIndexOf(needle)` を実装。
|
||
- Compare: String/StringBox 注釈のときは内容比較(`nyash.string.eq_hh`)にブリッジ。
|
||
- LLVM 多関数 Lower の骨格を実装: 全関数を事前宣言→順次Lower→`ny_main` ラッパで呼び出し正規化。
|
||
- Call Lowering 追加(MIR14の `MirInstruction::Call`): callee 文字列定数を解決し、対応するLLVM関数を呼び出し(引数束縛・戻り値格納)。
|
||
|
||
Refactor — LLVM codegen instructions modularized (done)
|
||
- Goal achieved: `instructions.rs` を段階分割し、責務ごとに再配置(0‑diff)。
|
||
- New layout under `src/backend/llvm/compiler/codegen/instructions/`:
|
||
- Core: `blocks.rs`(BB生成/PHI事前作成), `flow.rs`(Return/Jump/Branch), `consts.rs`, `mem.rs`, `arith.rs`(Compare)
|
||
- BoxCall front: `boxcall.rs`(ディスパッチ本体)
|
||
- Strings/Arrays/Maps fast‑paths: `strings.rs`, `arrays.rs`, `maps.rs`
|
||
- Fields: `boxcall/fields.rs`(getField/setField)
|
||
- Tagged invoke: `boxcall/invoke.rs`(method_idありの固定長/可変長)
|
||
- Marshal: `boxcall/marshal.rs`(ptr→i64, f64→box→i64, tag分類)
|
||
- Arith ops: `arith_ops.rs`(Unary/Binary、文字列連結の特例含む)
|
||
- Extern: `externcall.rs`(console/debug/env.local/env.box.*)
|
||
- NewBox: `newbox.rs`(`codegen/mod.rs` から委譲に一本化)
|
||
- Wiring: `instructions/mod.rs` が `pub(super) use ...` で再エクスポート。可視性は `pub(in super::super)`/`pub(super)` を維持。
|
||
- Build: `cargo build --features llvm` グリーン、挙動差分なし。
|
||
|
||
Next (short, focused)
|
||
- Call Lowering の分離(完了): `instructions/call.rs` に分割し、`mod.rs` から委譲。
|
||
- 多関数 Lower 検証: selfhost minimal(dep_tree_min_string)を LLVM で通す(必要なら型注釈の微調整)。
|
||
- Flow lowering hardening (in progress next):
|
||
- Ensure every lowered block has a terminator; use builder.get_insert_block().get_terminator() guard before fallback
|
||
- Instrument per‑block lowering (bid, has terminator?, emitted kind) to isolate misses
|
||
- Keep fallback minimal and only when MIR.block.terminator is None and LLVM has no terminator
|
||
- Detection strengthened (LoopForm Step 2.5): while-pattern detection allows 2-step Jump chains and selects body/after deterministically; logs include loop_id and chosen blocks.
|
||
|
||
LoopForm IR — Experimental Plan (gated)
|
||
- Goal: Centralize PHIs and simplify terminator management by normalizing loops to a fixed block shape with a dispatch join point.
|
||
- Gate: `NYASH_ENABLE_LOOPFORM=1` enables experimental lowering in LLVM path (MIR unchanged in Phase 1).
|
||
- Representation: Signal-like pair `{ i8 tag, i64 payload }` (0=Next,1=Break initially). Payload carries loop value (Everything is Box handle or scalar).
|
||
- Pattern (blocks): header → body → branch(on tag) → dispatch(phi here only) → switch(tag){ Next→latch, Break→exit } → latch→header.
|
||
- Phase 1 scope: while/loop only; Return/Yield signalization deferred.
|
||
- Success criteria: PHIs appear only in dispatch; no post-terminator insertions; Sealed ON/OFF equivalence; zero-synth minimized.
|
||
- Files:
|
||
- New: `src/backend/llvm/compiler/codegen/instructions/loopform.rs` scaffolding + helpers
|
||
- Wire: `instructions/mod.rs` to expose helpers (not yet used by default lowering)
|
||
- MIR readable debug tools:
|
||
- Add --dump-mir-readable to print Nyash‑like pseudo code per function/block
|
||
- Optional DOT output (follow‑up)
|
||
- Debug hints in MIR (debug builds only):
|
||
- Add #[cfg(debug_assertions)] fields like MirInstruction::debug_hint and MirMetadata::block_sources
|
||
- Gate emission by env (NYASH_MIR_DEBUG=1)
|
||
- Map コア専用エントリ化(env.box.new 特例整理)と代表スモークの常時化(CI)
|
||
- types.rs の将来分割(任意):
|
||
- `types/convert.rs`(i64<->ptr, f64→box), `types/classify.rs`, `types/map_types.rs`
|
||
- 機能拡張(任意・別タスク):
|
||
- String AOT fast‑paths拡充(substring/indexOf/replace/trim/toUpper/toLower)
|
||
- MapBox 生成のNyRT専用エントリ化(env.box.new特例の解消)
|
||
- Map.get の戻り型注釈の厳密化
|
||
- 代表スモークの追加とCI常時チェック
|
||
|
||
Risks/Guards
|
||
- Avoid broad implicit conversions; keep concat fallback gated by annotations only.
|
||
- Ensure nyash.map.* との一致(core Map); plugin経路は環境変数で明示切替。
|
||
- Keep LLVM smokes green continuously; do not gate on VM/JIT.
|
||
|
||
## 🎉 LLVMプラグイン戻り値表示問題修正進行中(2025-09-10)
|
||
|
||
### ✅ **完了した主要成果**:
|
||
1. **プラグイン実装** ✅ - `nyash.plugin.invoke_*`関数はnyrtライブラリに正常実装済み
|
||
2. **プラグイン呼び出し** ✅ - 環境変数なしでメソッド呼び出し成功
|
||
3. **戻り値型推論修正** ✅ - MIR builder にプラグインメソッド型推論追加
|
||
4. **by-id統一完了** ✅ - by-name方式削除、method_id方式に完全統一
|
||
5. **環境変数削減達成** ✅ - `NYASH_LLVM_ALLOW_BY_NAME=1`削除完了
|
||
6. **シンプル実行実現** ✅ - `./target/release/nyash --backend llvm program.nyash`
|
||
7. **codex TLV修正マージ完了** ✅ - プラグイン戻り値TLVタグ2/6/7対応(2000行修正)
|
||
8. **console.log ハンドル対応** ✅ - 不正なi64→i8*変換を修正、ハンドル対応関数に変更
|
||
9. **型変換エラー解消** ✅ - bool(i1)→i64拡張処理追加でLLVM検証エラー修正
|
||
|
||
### 🔬 **現在の動作状況**(2025-09-11 最新):
|
||
- **プラグイン実行** ✅ - CounterBox、FileBox正常実行(副作用OK)
|
||
- **型エラー解消** ✅ - LLVM関数検証エラー修正済み
|
||
- **コンパイル成功** ✅ - 環境変数なしでLLVMバックエンド動作
|
||
- **条件分岐動作** ✅ - `if f.exists("file")` → "TRUE"/"FALSE"表示OK
|
||
- **LLVMコード生成の分割** ✅ - `codegen/` 下にモジュール化(types/instructions)
|
||
- **BoxCall Lower 移譲** ✅ - 実行経路は `instructions::lower_boxcall` に一本化(旧実装は到達不能)
|
||
- **スモーク整理** ✅ - `tools/llvm_smoke.sh` を環境変数整理。プラグイン戻り値スモーク追加
|
||
|
||
### 🔍 **根本原因判明**:
|
||
**Task先生の詳細技術調査により特定**:
|
||
- **不正なハンドル→ポインタ変換**: `build_int_to_ptr(iv, i8p, "arg_i2p")` でハンドル値(3)を直接メモリアドレス(0x3)として扱う不正変換
|
||
- **修正完了**: console.log を `nyash.console.log_handle(i64) -> i64` に変更、ハンドルレジストリ活用
|
||
|
||
### 🔍 **残存課題(新)**:
|
||
|
||
#### 1. **プラグイン戻り値表示問題** 🔶 **←現在調査中**
|
||
**症状(修正後も継続)**:
|
||
- `CounterBox.get()` → 数値戻り値がprint()で空白
|
||
- `FileBox.read(path)` → 文字列戻り値がprint()で空白
|
||
- `FileBox.exists(path)` → if条件では動作、変数格納で失敗
|
||
- `local x = 42; print(x)` → 正常(問題はプラグイン戻り値のみ)
|
||
|
||
**残る問題の推定**:
|
||
- print()以外のExternCall処理にも同様の問題がある可能性
|
||
- MIR変数代入処理での型情報不整合
|
||
- プラグイン戻り値のハンドル→実値変換が不完全
|
||
|
||
#### 2. **LLVM BinOp 文字列連結まわり(新規スモークで再現)** 🔶
|
||
現象:
|
||
- 追加スモーク `ny-plugin-ret-llvm-smoke` で LLVM AOT オブジェクト生成中に `binop type mismatch` が発生
|
||
- ケース: `print("S=" + t)`(`t` は `StringBox.concat("CD")` の戻り値)
|
||
|
||
暫定分析:
|
||
- `+` 連結の BinOp Lower は (ptr+ptr / ptr+int / int+ptr) を NyRT シム経由で処理する設計
|
||
- `t` のLowerが i64 handleのままになっている/もしくは型注釈不足で ptr へ昇格できていない可能性
|
||
- `instructions::lower_boxcall` 内の `concat` 特例(f64 fast-path)は撤去済み。以降は tagged invoke → dst 型注釈に応じて i64→ptr へ変換する想定
|
||
|
||
対応方針:
|
||
1) MIR の `value_types` に BoxCall 戻り値(StringBox)の型注釈が入っているか確認(不足時は MIR 側で注入)
|
||
2) BinOp 連結経路は fallback として (ptr + 非ptr) / (非ptr + ptr) に対して handle想定の i64→ptr 昇格を再確認
|
||
3) 上記fixの後、スモーク `NYASH_LLVM_PLUGIN_RET_SMOKE=1` を通し、VM/LLVM 一致を確認
|
||
|
||
メモ:
|
||
- 現状でも BoxCall は新経路に完全委譲済み。旧実装は到達不能(削除準備OK)。
|
||
|
||
### 📊 **修正済みファイル**:
|
||
- **src/mir/builder.rs** - プラグインメソッド戻り値型推論追加
|
||
- **src/backend/llvm/compiler.rs** - by-name方式削除、method_id統一
|
||
- **src/backend/llvm/compiler/codegen/mod.rs** - 分割に伴う委譲(Const/Compare/Return/Jump/Branch/Extern/NewBox/Load/Store/BoxCall)
|
||
- **src/backend/llvm/compiler/codegen/types.rs** - 型変換/分類/型マップ(新)
|
||
- **src/backend/llvm/compiler/codegen/instructions.rs** - Lower群を実装(新)
|
||
- **tools/llvm_smoke.sh** - LLVM18 prefix整理・プラグイン戻り値スモーク追加
|
||
- **apps/tests/ny-plugin-ret-llvm-smoke/main.nyash** - プラグイン戻り値スモーク(新)
|
||
- **CLAUDE.md** - 環境変数セクション更新、コマンド簡素化
|
||
- **README.md / README.ja.md** - 環境変数説明削除
|
||
- **tools/llvm_smoke.sh** - テストスクリプト環境変数削除
|
||
|
||
### 🎯 **次期深堀り調査対象**:
|
||
1. **プラグインランタイム戻り値パス詳細調査** - `crates/nyrt/src/lib.rs`
|
||
2. **LLVM BoxCall戻り値処理詳細分析** - `src/backend/llvm/compiler/real.rs` 戻り値変換
|
||
3. **MIR変数代入メカニズム調査** - BoxCall→変数の代入処理
|
||
4. **print()関数とプラグイン値の相性調査** - 型認識処理
|
||
5. **BinOp 連結の保険見直し** - 片方が i64 (handle) の場合に ptr に昇格する安全弾性
|
||
6. **BoxCall 旧実装の物理削除** - スモークグリーン後に `mod.rs` の死コードを除去
|
||
|
||
### ✅ **リファクタリング完了(2025-09-11)**:
|
||
**PR #136マージ済み** - LLVMコンパイラモジュール化:
|
||
- `compiler.rs` → 4モジュールに分割(mod.rs, real.rs, mock.rs, mock_impl.in.rs)
|
||
- プラグインシグネチャ読み込みを `plugin_sigs.rs` に移動
|
||
- BoxタイプID読み込みを `box_types.rs` に移動
|
||
- PR #134の型情報処理を完全保持
|
||
|
||
## 🎯 Restart Notes — Ny Syntax Alignment (2025‑09‑07)
|
||
|
||
### 目的
|
||
- Self‑Hosting 方針(Nyのみで工具を回す前段)に合わせて、Ny 構文とコーディング規約を明示化し、最小版ツールの完走性を優先。
|
||
|
||
### Ny 構文(実装時の基準)
|
||
- 1行1文/セミコロン非使用。
|
||
- break / continue を使わない(関数早期 return、番兵条件、if 包みで置換)。
|
||
- else は直前の閉じ波括弧と同一行(`} else {`})。
|
||
- 文字列の `"` と `\` は確実にエスケープ。
|
||
- 反復は `loop(条件) { …; インクリメント }` を基本とし、必要に応じて「関数早期 return」型で早期脱出。
|
||
|
||
### 短期タスク(Syntax 合意前提で最小ゴール)
|
||
1) include のみ依存木(Nyのみ・配列/マップ未使用)を完走化
|
||
- `apps/selfhost/tools/dep_tree_min_string.nyash`
|
||
- FileBox/PathBox + 文字走査のみで JSON 構築(配列/マップに頼らない)
|
||
- `make dep-tree` で `tmp/deps.json` を出力
|
||
2) using/module 対応は次段(構文・優先順位をユーザーと再すり合わせ後)
|
||
- 優先: `module > 相対 > using-path`、曖昧=エラー、STRICT ゲート(要相談)
|
||
3) ブリッジ Stage 1 は保留
|
||
- `NYASH_DEPS_JSON=<path>` 読み込み(ログ出力のみ)を最小パッチで用意(MIR/JIT/AOT は不変)
|