feat(phase71-ssa): SSA undef 完全解消達成!(4件→0件)
## Phase 71-SSA SSA undef 削減 完全達成! ### 🎉 成果 - **SSA undef**: 4件 → **0件** (100%解消!) - **所要時間**: 約2時間 (Task先生調査 + 実装 + 検証) - **修正ファイル**: 3ファイル (.hako実装のみ、MIR/SSAビルダー不変) ### 🔍 根本原因 (Task先生による徹底分析) **ValueId(272) = StringHelpers.starts_with_kw/3 の戻り値** - static boxの委譲でValueIdマッピング失敗 - 引数パラメータ設定ログが一切出力されず - 別関数の戻り値ValueIdが誤って引数として参照される ### 🛠️ 修正内容 **修正1: ParserStringUtilsBox.trim (Quick Win)** - L76: `StringHelpers.skip_ws` → `ParserStringUtilsBox.skip_ws` - 効果: SSA undef 4件 → 2件 - 副次効果: Main._parse_number/ParserBox.parse_block2 消滅 **修正2: ParserCommonUtilsBox.trim (修正案A)** - L50-69: 委譲を廃止、直接実装に変更 - FuncScannerBox.trimの成功パターンを適用 **修正3: ParserBox.trim (修正案A)** - L81-98: 委譲を廃止、直接実装に変更 - 効果: 残り2件のSSA undef完全解消 ### ✅ 検証結果 ```bash grep -c 'ssa-undef-debug' logs/selfhost/stageb_20251202_111409_2674670.log # 出力: 0 ← 🎉 完全解消! ``` ### 📊 SSA undef 推移 | フェーズ | 件数 | 詳細 | |---------|------|------| | Phase 71初回 | 4件 | trim×2, _parse_number, parse_block2 | | Quick Win後 | 2件 | trim×2 (予想外: 他2件消滅) | | 修正案A後 | **0件** | 🎉 **完全解消!** | ### 🎯 残存課題 (次フェーズ) 1. dev verify警告: 1件 (StageBDriverBox birth) 2. Program JSON未出力: extract_ok=0 (rc=0だが行なし) ### 💡 重要な教訓 - static boxの委譲は危険 (ValueIdマッピング失敗) - 静的呼び出し (BoxName.method) が SSA-friendly - 成功パターン (FuncScannerBox.trim) の積極活用 ### 📝 ドキュメント - 詳細レポート: phase71-ssa-trim-fix-20251202.md - Task先生分析: ValueId(272)特定、修正案A-C提案 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -78,7 +78,24 @@ box ParserBox {
|
||||
|
||||
index_of(src, i, pat) { return ParserStringUtilsBox.index_of(src, i, pat) }
|
||||
|
||||
trim(s) { return ParserStringUtilsBox.trim(s) }
|
||||
trim(s) {
|
||||
// Phase 71-SSA: Direct implementation to avoid ValueId mapping issue in static box delegation
|
||||
if s == null { return "" }
|
||||
local str = "" + s
|
||||
local n = str.length()
|
||||
|
||||
local b = ParserStringUtilsBox.skip_ws(str, 0)
|
||||
if b >= n { return "" }
|
||||
|
||||
local e = n
|
||||
loop(e > b) {
|
||||
local ch = str.substring(e - 1, e)
|
||||
if ch == " " || ch == "\t" || ch == "\n" || ch == "\r" || ch == ";" { e = e - 1 } else { break }
|
||||
}
|
||||
|
||||
if e > b { return str.substring(b, e) }
|
||||
return ""
|
||||
}
|
||||
|
||||
starts_with_kw(src, i, kw) { return ParserStringUtilsBox.starts_with_kw(src, i, kw) }
|
||||
|
||||
|
||||
@ -48,8 +48,24 @@ static box ParserCommonUtilsBox {
|
||||
}
|
||||
|
||||
trim(s) {
|
||||
// Delegate to string_utils to keep SSA/semantic consistency.
|
||||
return ParserStringUtilsBox.trim(s)
|
||||
// Phase 71-SSA: Direct implementation to avoid ValueId mapping issue in static box delegation
|
||||
if s == null { return "" }
|
||||
local str = "" + s
|
||||
local n = str.length()
|
||||
|
||||
// Leading whitespace: use static method to avoid SSA undef
|
||||
local b = ParserStringUtilsBox.skip_ws(str, 0)
|
||||
if b >= n { return "" }
|
||||
|
||||
// Trailing whitespace: walk backwards until a non-space is found.
|
||||
local e = n
|
||||
loop(e > b) {
|
||||
local ch = str.substring(e - 1, e)
|
||||
if ch == " " || ch == "\t" || ch == "\n" || ch == "\r" || ch == ";" { e = e - 1 } else { break }
|
||||
}
|
||||
|
||||
if e > b { return str.substring(b, e) }
|
||||
return ""
|
||||
}
|
||||
|
||||
esc_json(s) {
|
||||
|
||||
@ -72,8 +72,8 @@ static box ParserStringUtilsBox {
|
||||
local str = "" + s
|
||||
local n = str.length()
|
||||
|
||||
// Leading whitespace: reuse shared skip_ws to keep semantics aligned with Stage‑B.
|
||||
local b = StringHelpers.skip_ws(str, 0)
|
||||
// Leading whitespace: use static method to avoid SSA undef (Phase 71-SSA Quick Win)
|
||||
local b = ParserStringUtilsBox.skip_ws(str, 0)
|
||||
if b >= n { return "" }
|
||||
|
||||
// Trailing whitespace: walk backwards until a non-space is found.
|
||||
|
||||
Reference in New Issue
Block a user