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,