diff --git a/docs/development/current/main/phase131-3-llvm-lowering-inventory.md b/docs/development/current/main/phase131-3-llvm-lowering-inventory.md index baf30116..4c7820fe 100644 --- a/docs/development/current/main/phase131-3-llvm-lowering-inventory.md +++ b/docs/development/current/main/phase131-3-llvm-lowering-inventory.md @@ -27,6 +27,16 @@ - Investigation: [phase132-llvm-exit-phi-wrong-result.md](investigations/phase132-llvm-exit-phi-wrong-result.md) - Phase summary: [phases/phase-132/README.md](phases/phase-132/README.md) +## Phase 132-P1 Update (2025-12-15) + +✅ **STRUCTURAL FIX**: Function-local state isolation in LLVM Python backend + +- **Issue**: block id / value id が “関数をまたいで” 衝突し得る(snapshot / cache / PHI state の漏洩) +- **Fix**: `FunctionLowerContext` Box で function-scoped state を隔離し、tuple-key workaround を不要化 +- **Code**: + - `src/llvm_py/context/function_lower_context.py` + - `src/llvm_py/builders/function_lower.py` + ## Root Causes Identified ### 1. TAG-EMIT: Loop PHI → Invalid LLVM IR (Case B) ✅ FIXED (Phase 131-10) diff --git a/docs/development/current/main/phases/phase-132/README.md b/docs/development/current/main/phases/phase-132/README.md index 514412e5..50d978ac 100644 --- a/docs/development/current/main/phases/phase-132/README.md +++ b/docs/development/current/main/phases/phase-132/README.md @@ -110,3 +110,24 @@ JoinIR merge の契約検証(debug build)で **早期に Fail-Fast** する 期待される振る舞い: - debug build では compile/run 中に panic で即停止(原因と修正案が出る) - release build の既定挙動は変えない(検証は `debug_assertions` のみ) + +--- + +## 追加: Phase 132-P1(LLVM Python)FunctionLowerContext Box + +Phase 131–132 で顕在化した「関数間の状態漏洩(block id / value id の衝突)」を、 +tuple-key の小手先ではなく **構造で根治**するために、関数ローカル状態を 1 箱に隔離した。 + +- 実装: `src/llvm_py/context/function_lower_context.py` +- 統合: `src/llvm_py/builders/function_lower.py` + +箱の責務(SSOT): +- `block_end_values`(snapshot) +- `def_blocks` +- `jump_only_blocks` +- `phi_manager` +- resolver caches(i64/ptr/f64/end_i64 など) + +狙い: +- 関数単位で state を自動破棄し、cross-function collision を “起こせない構造” にする +- 追加の手動クリアや tuple-key を不要にする diff --git a/src/llvm_py/builders/function_lower.py b/src/llvm_py/builders/function_lower.py index 16c33b3e..c7bb6fb3 100644 --- a/src/llvm_py/builders/function_lower.py +++ b/src/llvm_py/builders/function_lower.py @@ -51,6 +51,14 @@ def lower_function(builder, func_data: Dict[str, Any]): builder.bb_map.clear() except Exception: builder.bb_map = {} + # Phase 132-P1: Clear per-function predeclared PHI placeholders (avoid cross-function leakage) + try: + builder.predeclared_ret_phis.clear() + except Exception: + try: + builder.predeclared_ret_phis = {} + except Exception: + pass # Phase 132-P1: Create function-local context Box # This automatically isolates all function-scoped state @@ -63,6 +71,7 @@ def lower_function(builder, func_data: Dict[str, Any]): builder.phi_manager = context.phi_manager builder.block_phi_incomings = context.block_phi_incomings builder.def_blocks = context.def_blocks + builder.block_end_values = context.block_end_values # Bind resolver to context (redirects caches to context storage) builder.resolver.bind_context(context) @@ -311,7 +320,7 @@ def lower_function(builder, func_data: Dict[str, Any]): vmap=builder.vmap, bb_map=builder.bb_map, preds=builder.preds, - block_end_values=builder.block_end_values, + block_end_values=context.block_end_values, resolver=builder.resolver, trace_phi=os.environ.get('NYASH_LLVM_TRACE_PHI') == '1', verbose=os.environ.get('NYASH_CLI_VERBOSE') == '1',