From 93f51e40ae00e202cdae316540b21a27060522a2 Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Tue, 2 Dec 2025 14:01:44 +0900 Subject: [PATCH] =?UTF-8?q?refactor(joinir):=20Phase=2082=20SSOT=E7=B5=B1?= =?UTF-8?q?=E4=B8=80=E5=8C=96=20-=20=E3=83=86=E3=83=BC=E3=83=96=E3=83=AB?= =?UTF-8?q?=E5=8C=96=E3=81=A8=E3=83=98=E3=83=AB=E3=83=91=E3=83=BC=E6=8A=BD?= =?UTF-8?q?=E8=B1=A1=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 82: JoinIR関数リストとExecルートの SSOT 統一化 ## 変更内容 ### 1. JOINIR_TARGETS テーブル統一化 **targets.rs**: vm_bridge_dispatch テーブルが唯一のSSO - FuncScannerBox.append_defs/2 を Exec に追加 - is_loop_lowered_function() はここから参照 - コメントに Phase 82 SSOT マーク **mod.rs**: is_loop_lowered_function() 簡素化 - JOINIR_TARGETS テーブルから参照に統一 - Exec/LowerOnly 両方を Loop lowered対象とする - ハードコード関数リストを削除 ✅ ### 2. Exec routes 統一ヘルパー **exec_routes.rs**: run_generic_joinir_route() 追加 - try_run_skip_ws() / try_run_trim() の共通パターンを抽象化 - 入出力値フォーマッタ、終了コードエキスプレッサをコールバック化 - 後方互換性のため既存関数は保持 - 将来フェーズで統合可能 (#[allow(dead_code)]) ## テスト結果 ✅ test_is_loop_lowered_function PASS ✅ cargo build --release SUCCESS ## 重複排除の効果 - テーブル重複: ハードコード関数リスト完全排除 - ロジック重複: 統一ヘルパーで28行削減可能(将来) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/mir/join_ir/lowering/mod.rs | 19 +++-- .../join_ir_vm_bridge_dispatch/exec_routes.rs | 81 +++++++++++++++++++ src/mir/join_ir_vm_bridge_dispatch/targets.rs | 11 ++- 3 files changed, 100 insertions(+), 11 deletions(-) diff --git a/src/mir/join_ir/lowering/mod.rs b/src/mir/join_ir/lowering/mod.rs index 1ad5528a..25d46bf1 100644 --- a/src/mir/join_ir/lowering/mod.rs +++ b/src/mir/join_ir/lowering/mod.rs @@ -59,6 +59,9 @@ use crate::mir::{BasicBlockId, MirFunction}; /// これらの関数は Phase 32/33 で LoopToJoinLowerer によって処理されます。 /// If lowering (Select/IfMerge) の対象から除外することで、Loop/If の責務を明確に分離します。 /// +/// Phase 82 SSOT: JOINIR_TARGETS テーブルから Exec 対象を参照 +/// (テーブルは vm_bridge_dispatch/targets.rs で一元管理) +/// /// ## 対象関数(6本) /// - Main.skip/1: 空白スキップループ /// - FuncScannerBox.trim/1: 前後空白削除ループ @@ -70,16 +73,12 @@ use crate::mir::{BasicBlockId, MirFunction}; /// ## 将来の拡張 /// NYASH_JOINIR_LOWER_GENERIC=1 で汎用 Case-A ループにも拡張可能 pub(crate) fn is_loop_lowered_function(name: &str) -> bool { - const LOOP_LOWERED_FUNCTIONS: &[&str] = &[ - "Main.skip/1", - "FuncScannerBox.trim/1", - "FuncScannerBox.append_defs/2", - "Stage1UsingResolverBox.resolve_for_source/5", - "StageBBodyExtractorBox.build_body_src/2", - "StageBFuncScannerBox.scan_all_boxes/1", - ]; - - LOOP_LOWERED_FUNCTIONS.contains(&name) + // Phase 82 SSOT: vm_bridge_dispatch テーブルから Loop 関数を抽出 + // Phase 33-9.1: If lowering の除外対象は、JOINIR_TARGETS に登録されたすべての関数 + // (Exec/LowerOnly 問わず、ループ専任関数として Loop lowering で処理) + crate::mir::join_ir_vm_bridge_dispatch::JOINIR_TARGETS + .iter() + .any(|t| t.func_name == name) } // ============================================================================ diff --git a/src/mir/join_ir_vm_bridge_dispatch/exec_routes.rs b/src/mir/join_ir_vm_bridge_dispatch/exec_routes.rs index bdb62c11..5d03ec1c 100644 --- a/src/mir/join_ir_vm_bridge_dispatch/exec_routes.rs +++ b/src/mir/join_ir_vm_bridge_dispatch/exec_routes.rs @@ -122,3 +122,84 @@ pub(crate) fn try_run_trim(module: &MirModule, quiet_pipe: bool) -> bool { } } } + +// ============================================================================ +// Phase 82: Exec routes 統一ヘルパー(重複ロジック排除) +// ============================================================================ + +/// JoinIR 実行ルートの統一ヘルパー +/// +/// `try_run_skip_ws()` と `try_run_trim()` の共通パターンを吸収。 +/// +/// # Phase 82 SSOT 統一 +/// 現在は後方互換性のため既存関数を保持。 +/// 将来のフェーズで try_run_skip_ws/try_run_trim を このヘルパーで統合可能。 +/// +/// # Arguments +/// - `lowerer`: JoinIR に lowering する関数(返り値 Option) +/// - `input_val`: 入力値(JoinValue形式) +/// - `output_formatter`: 出力値を文字列に変換する関数 +/// - `exit_code_extractor`: 出力値から終了コードを抽出する関数 +/// - `route_name`: ログ出力用の名前(例: "Main.skip", "FuncScannerBox.trim") +#[allow(dead_code)] +fn run_generic_joinir_route( + lowerer: F, + input_val: JoinValue, + output_formatter: G, + exit_code_extractor: H, + route_name: &str, + quiet_pipe: bool, +) -> bool +where + F: FnOnce() -> Option, + G: Fn(&JoinValue) -> String, + H: Fn(&JoinValue) -> i32, +{ + eprintln!("[joinir/vm_bridge] Attempting JoinIR path for {}", route_name); + + let Some(join_module) = lowerer() else { + eprintln!( + "[joinir/vm_bridge] lower_{} returned None", + route_name.replace(".", "_").to_lowercase() + ); + eprintln!("[joinir/vm_bridge] Falling back to normal VM path"); + return false; + }; + + let dev_bridge = joinir_dev_enabled() + || std::env::var("NYASH_EMIT_MIR_TRACE").ok().as_deref() == Some("1"); + let strict = joinir_strict_enabled(); + + match run_joinir_via_vm(&join_module, JoinFuncId::new(0), &[input_val]) { + Ok(result) => { + eprintln!("[joinir/vm_bridge] ✅ JoinIR result: {:?}", result); + let output = output_formatter(&result); + let exit_code = exit_code_extractor(&result); + + if dev_bridge { + if !quiet_pipe { + println!("{}", output); + } + return true; + } else if strict { + if !quiet_pipe { + println!("{}", output); + } + process::exit(exit_code); + } else { + if !quiet_pipe { + println!("{}", output); + } + process::exit(exit_code); + } + } + Err(e) => { + eprintln!( + "[joinir/vm_bridge] ❌ JoinIR {} failed: {:?}", + route_name, e + ); + eprintln!("[joinir/vm_bridge] Falling back to normal VM path"); + false + } + } +} diff --git a/src/mir/join_ir_vm_bridge_dispatch/targets.rs b/src/mir/join_ir_vm_bridge_dispatch/targets.rs index eef1acdb..e913d5d4 100644 --- a/src/mir/join_ir_vm_bridge_dispatch/targets.rs +++ b/src/mir/join_ir_vm_bridge_dispatch/targets.rs @@ -25,18 +25,21 @@ pub struct JoinIrTargetDesc { pub default_enabled: bool, } -/// JoinIR ブリッジ対象テーブル +/// JoinIR ブリッジ対象テーブル(SSOT) /// /// Phase 32 L-4: 全対象関数を一覧化し、Exec/LowerOnly の区分を明示する。 +/// Phase 82: このテーブルが唯一の SSOT。is_loop_lowered_function() はここから参照。 /// /// | 関数 | Kind | デフォルト有効 | 備考 | /// |-----|------|---------------|------| /// | Main.skip/1 | Exec | No | PHI canary のため env 必須 | /// | FuncScannerBox.trim/1 | Exec | Yes | A/B 実証済み、事実上本線 | +/// | FuncScannerBox.append_defs/2 | Exec | No | Phase 82 SSOT統一で追加 | /// | Stage1UsingResolverBox.resolve_for_source/5 | LowerOnly | No | 構造検証のみ | /// | StageBBodyExtractorBox.build_body_src/2 | LowerOnly | No | 構造検証のみ | /// | StageBFuncScannerBox.scan_all_boxes/1 | LowerOnly | No | 構造検証のみ | pub const JOINIR_TARGETS: &[JoinIrTargetDesc] = &[ + // Loop Exec(実行対応) JoinIrTargetDesc { func_name: "Main.skip/1", kind: JoinIrBridgeKind::Exec, @@ -47,6 +50,12 @@ pub const JOINIR_TARGETS: &[JoinIrTargetDesc] = &[ kind: JoinIrBridgeKind::Exec, default_enabled: true, // A/B 実証済み、事実上本線 }, + JoinIrTargetDesc { + func_name: "FuncScannerBox.append_defs/2", + kind: JoinIrBridgeKind::Exec, + default_enabled: false, + }, + // Loop LowerOnly(構造検証のみ) JoinIrTargetDesc { func_name: "Stage1UsingResolverBox.resolve_for_source/5", kind: JoinIrBridgeKind::LowerOnly,