From 805487526181d93a6dadccd61f4649f32d6b7bd5 Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Wed, 19 Nov 2025 05:48:51 +0900 Subject: [PATCH] =?UTF-8?q?feat(parser):=20Phase=2025.1c=20dev-only=20prog?= =?UTF-8?q?ress=20guard=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task 8-4: ParserBox.parse_program2ハング調査のため、開発専用の進捗ガード実装 **実装内容**: - HAKO_PARSER_PROG_MAX環境変数で最大反復回数を設定可能 - デフォルト挙動は完全不変(max_prog=0=無制限) - 数値パースは安全実装(不正値→0扱い) - トレースモード時のみガード到達をログ出力 **Phase 25ポリシー準拠**: - 仕様変更なし(dev-onlyオプトイン) - 既存コード完全互換 - 無効値は静かに無視(デフォルト挙動維持) **調査状況**: - Hotfix 8適用後、Stage-Bトレースは after_build_body_src まで出力 - parse_program2に入っておらず、パーサートレース未出現 - trace_enabled()呼び出し前後のハング疑惑を調査中 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- lang/src/compiler/parser/parser_box.hako | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/lang/src/compiler/parser/parser_box.hako b/lang/src/compiler/parser/parser_box.hako index 2b12a4f6..02a0fdf9 100644 --- a/lang/src/compiler/parser/parser_box.hako +++ b/lang/src/compiler/parser/parser_box.hako @@ -270,7 +270,42 @@ box ParserBox { local first = 1 local cont_prog = 1 + // Dev-only program-level progress guard (Phase 25.1c): + // - Enabled when HAKO_PARSER_PROG_MAX > 0 + // - Protects Stage‑B/selfhost callers from infinite top-level loops on malformed input + local guard_prog = 0 + local max_prog = 0 + { + local m = env.get("HAKO_PARSER_PROG_MAX") + if m != null { + // Safely parse to int; invalid values are treated as 0 (disabled) + local mv = 0 + local ok = 0 + // Minimal numeric parse: allow decimal digits only + local ms = "" + m + local mi = 0 + local ml = ms.length() + loop(mi < ml) { + local chm = ms.substring(mi, mi + 1) + if chm < "0" || chm > "9" { ok = 0 break } + if ok == 0 { ok = 1 } + mv = mv * 10 + me.to_int(chm) + mi = mi + 1 + } + if ok == 1 && mv > 0 { max_prog = mv } + } + } + loop(cont_prog == 1) { + if max_prog > 0 { + guard_prog = guard_prog + 1 + if guard_prog > max_prog { + if trace == 1 { + print("[parser/program2:guard] max iteration reached at pos=" + ("" + i)) + } + cont_prog = 0 + } + } if trace == 1 { local kind = "Stmt" if i >= n {