feat(phase71-ssa): ParserBox委譲SSA undef完全解消達成!(9件→0件)

**Phase 71-SSA: 全SSA undef完全解消達成!**
- 修正前: trim系 4件 + ParserBox委譲 9件 = 計13件
- 修正後: **0件** (100%解消!)

**修正内容**:
1. ParserBox委譲メソッド削除 (L71-106)
   - 削除: is_digit, is_space, is_alpha, starts_with, index_of
   - 削除: starts_with_kw, i2s, to_int, skip_ws
   - 理由: static box delegation による ValueId mapping 失敗

2. ParserBox内部呼び出し修正 (5箇所)
   - `me.to_int()` → `ParserStringUtilsBox.to_int()`
   - `me.starts_with()` → `ParserStringUtilsBox.starts_with()`
   - L112, L129, L157, L160, L353 を修正

3. compiler_stageb.hako トレース追加 (L1477-1495)
   - Program JSON emit 直前にトレースポイント追加
   - HAKO_STAGEB_TRACE=1 で詳細トレース出力

**根本原因** (Rust MIRビルダーのバグ):
- static box の委譲時に ValueId マッピングが失敗
- 引数の ValueId が undef (未定義) になる
- 例: Copy { dst: ValueId(4), src: ValueId(132) }
  で ValueId(132) が存在しない

**Phase 71-SSA戦略**:
- .hako 層で委譲を廃止 (回避策)
- 直接実装または直接呼び出しに統一
- 根本解決は将来タスク (Rust MIRビルダー修正)

**検証結果**:
```bash
grep -c 'ssa-undef-debug' logs/selfhost/stageb_*.log
# 出力: 0  ← 完全成功!
```

**残存課題**:
- dev verify警告: 1件 (StageBDriverBox birth)
- Program JSON emit: extract_ok=0 (次フェーズで調査)

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-02 11:22:53 +09:00
parent 4b3eb6b3a9
commit 29e09c1491
2 changed files with 28 additions and 22 deletions

View File

@ -1474,9 +1474,25 @@ static box StageBDriverBox {
} }
} }
// Phase 71-SSA 71-11.1: Guaranteed trace before Program JSON emit
{
local marker_enabled = env.get("HAKO_STAGEB_TRACE")
if marker_enabled != null && ("" + marker_enabled) == "1" {
local ajson_len = 0
if ast_json != null { ajson_len = ("" + ast_json).length() }
print("[stageb/main] BEFORE_EMIT ast_json_len=" + ("" + ajson_len))
}
}
print("[stageb/main] before ast_json") print("[stageb/main] before ast_json")
print(ast_json) print(ast_json)
print("[stageb/main] after ast_json") print("[stageb/main] after ast_json")
// Phase 71-SSA 71-11.1: Guaranteed trace after Program JSON emit
{
local marker_enabled = env.get("HAKO_STAGEB_TRACE")
if marker_enabled != null && ("" + marker_enabled) == "1" {
print("[stageb/main] AFTER_EMIT success")
}
}
{ {
local tracer = new StageBTraceBox() local tracer = new StageBTraceBox()
tracer.log("StageBDriverBox.main:exit rc=0") tracer.log("StageBDriverBox.main:exit rc=0")

View File

@ -67,16 +67,10 @@ box ParserBox {
return out return out
} }
// === Delegation to ParserStringUtilsBox === // === Phase 71-SSA: Removed delegation methods to avoid SSA undef ===
is_digit(ch) { return ParserStringUtilsBox.is_digit(ch) } // Direct use of ParserStringUtilsBox methods recommended instead
// Removed: is_digit, is_space, is_alpha, starts_with, index_of
is_space(ch) { return ParserStringUtilsBox.is_space(ch) } // Use ParserStringUtilsBox.method() directly to avoid ValueId mapping issues
is_alpha(ch) { return ParserStringUtilsBox.is_alpha(ch) }
starts_with(src, i, pat) { return ParserStringUtilsBox.starts_with(src, i, pat) }
index_of(src, i, pat) { return ParserStringUtilsBox.index_of(src, i, pat) }
trim(s) { trim(s) {
// Phase 71-SSA: Direct implementation to avoid ValueId mapping issue in static box delegation // Phase 71-SSA: Direct implementation to avoid ValueId mapping issue in static box delegation
@ -97,13 +91,9 @@ box ParserBox {
return "" return ""
} }
starts_with_kw(src, i, kw) { return ParserStringUtilsBox.starts_with_kw(src, i, kw) } // Phase 71-SSA: Removed delegation methods to avoid SSA undef
// Removed: starts_with_kw, i2s, to_int, skip_ws
i2s(v) { return ParserStringUtilsBox.i2s(v) } // Use ParserStringUtilsBox.method() directly instead
to_int(s) { return ParserStringUtilsBox.to_int(s) }
skip_ws(src, i) { return ParserStringUtilsBox.skip_ws(src, i) }
// === Delegation to scanner boxes === // === Delegation to scanner boxes ===
read_ident2(src, i) { return ParserIdentScanBox.scan_ident(src, i) } read_ident2(src, i) { return ParserIdentScanBox.scan_ident(src, i) }
@ -119,7 +109,7 @@ box ParserBox {
local at = pair.lastIndexOf("@") local at = pair.lastIndexOf("@")
local content = pair.substring(0, at) local content = pair.substring(0, at)
local pos = 0 local pos = 0
if at >= 0 { pos = me.to_int(pair.substring(at+1, pair.length())) } if at >= 0 { pos = ParserStringUtilsBox.to_int(pair.substring(at+1, pair.length())) }
else { pos = i } else { pos = i }
me.gpos_set(pos) me.gpos_set(pos)
return content return content
@ -136,7 +126,7 @@ box ParserBox {
local at = pair.lastIndexOf("@") local at = pair.lastIndexOf("@")
local content = pair.substring(0, at) local content = pair.substring(0, at)
local pos = 0 local pos = 0
if at >= 0 { pos = me.to_int(pair.substring(at+1, pair.length())) } if at >= 0 { pos = ParserStringUtilsBox.to_int(pair.substring(at+1, pair.length())) }
else { pos = i } else { pos = i }
me.gpos_set(pos) me.gpos_set(pos)
return content return content
@ -164,10 +154,10 @@ box ParserBox {
} }
if idx >= 0 { p = p.substring(idx+1, p.length()) } if idx >= 0 { p = p.substring(idx+1, p.length()) }
if p.length() > 5 && me.starts_with(p, p.length()-5, ".hako") == 1 { if p.length() > 5 && ParserStringUtilsBox.starts_with(p, p.length()-5, ".hako") == 1 {
p = p.substring(0, p.length()-5) p = p.substring(0, p.length()-5)
} else { } else {
if p.length() > 6 && me.starts_with(p, p.length()-6, ".hako") == 1 { if p.length() > 6 && ParserStringUtilsBox.starts_with(p, p.length()-6, ".hako") == 1 {
p = p.substring(0, p.length()-6) p = p.substring(0, p.length()-6)
} }
} }
@ -360,7 +350,7 @@ box ParserBox {
local chm = ms.substring(mi, mi + 1) local chm = ms.substring(mi, mi + 1)
if chm < "0" || chm > "9" { ok = 0 break } if chm < "0" || chm > "9" { ok = 0 break }
if ok == 0 { ok = 1 } if ok == 0 { ok = 1 }
mv = mv * 10 + me.to_int(chm) mv = mv * 10 + ParserStringUtilsBox.to_int(chm)
mi = mi + 1 mi = mi + 1
} }
if ok == 1 && mv > 0 { max_prog = mv } if ok == 1 && mv > 0 { max_prog = mv }