From 7c9f453fc632b418d0e6bfc1e031f7636f723ff9 Mon Sep 17 00:00:00 2001 From: tomoaki Date: Sun, 21 Dec 2025 08:32:04 +0900 Subject: [PATCH] refactor(mir): phase261 p0 enforce edge-args writer ssot (verify + sync) --- docs/development/current/main/10-Now.md | 19 +++++++++++ src/mir/basic_block.rs | 8 ++++- src/mir/verification/cfg.rs | 21 +++++++------ src/runtime/runtime_profile.rs | 42 ++++++++++++++++--------- 4 files changed, 65 insertions(+), 25 deletions(-) diff --git a/docs/development/current/main/10-Now.md b/docs/development/current/main/10-Now.md index 2a4a72ea..4493259d 100644 --- a/docs/development/current/main/10-Now.md +++ b/docs/development/current/main/10-Now.md @@ -16,6 +16,25 @@ - P2: `BasicBlock.jump_args` を削除(terminator operand を SSOT 化) - P3: spans を `Vec>` に収束(段階導入) +## Phase 261 P0 チェックリスト(legacy-only 経路の棚卸し) + +- `src/mir/basic_block.rs:119` — reason: legacy layout の初期値が None(空メタ); expected: OK(legacy 未設定時の既定) +- `src/mir/basic_block.rs:239` — reason: out_edges が legacy fallback を持つ; expected: Jump/Branch で edge-args を書く経路を増やし、verify で legacy-only を検出 +- `src/mir/basic_block.rs:254` — reason: legacy setter API; expected: writer 側は edge-args を併記する経路に統一 +- `src/mir/basic_block.rs:281` — reason: legacy edge-args 生成 API; expected: read-side の移行完了後に削除(P2) +- `src/mir/basic_block.rs:337` — reason: legacy edge-args fallback; expected: verify で legacy-only を検出し、P2で撤去 +- `src/mir/join_ir_vm_bridge/handlers/call.rs:193` — reason: tail-call Return の legacy 付与(exit wiring); expected: edge-args SSOT 化のための設計判断が必要(Return には edge-args を持てない) +- `src/mir/join_ir_vm_bridge/handlers/jump.rs:213` — reason: cond jump の exit block Return に legacy 付与; expected: 同上(Return 経由のため) +- `src/mir/join_ir_vm_bridge/handlers/jump.rs:249` — reason: tail-call Return の legacy 付与; expected: 同上 +- `src/mir/join_ir_vm_bridge/joinir_block_converter.rs:438` — reason: tail-call Return の legacy 付与; expected: 同上 +- `src/mir/join_ir_vm_bridge/joinir_block_converter.rs:508` — reason: cond jump の exit block Return に legacy 付与; expected: 同上 +- `src/mir/join_ir_vm_bridge/joinir_block_converter.rs:551` — reason: tail-call Return の legacy 付与; expected: 同上 +- `src/mir/join_ir_vm_bridge/normalized_bridge/direct.rs:425` — reason: exit Return の legacy 付与; expected: 同上 +- `src/mir/join_ir_vm_bridge/normalized_bridge/direct.rs:471` — reason: finalize_block の legacy 付与; expected: 同上 +- `src/mir/builder/control_flow/joinir/merge/rewriter/exit_collection.rs:64` — reason: legacy edge-args を read; expected: edge-args SSOT 経路に寄せて置換(P1〜P2) +- `src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs:415` — reason: legacy edge-args read; expected: 同上 +- `src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs:930` — reason: legacy edge-args read; expected: 同上 + ## Current First FAIL (SSOT) - **After Phase 260 P0.3**: `core_direct_array_oob_set_rc_vm / Stage-B compile / JoinIR Pattern2 LoopBodyLocal(seg)` diff --git a/src/mir/basic_block.rs b/src/mir/basic_block.rs index 7f04ea09..ebc3c679 100644 --- a/src/mir/basic_block.rs +++ b/src/mir/basic_block.rs @@ -252,8 +252,14 @@ impl BasicBlock { /// Set legacy jump args metadata (migration helper) pub fn set_legacy_jump_args(&mut self, values: Vec, layout: Option) { - self.jump_args = Some(values); + self.jump_args = Some(values.clone()); self.jump_args_layout = layout; + if let (Some(layout), Some(MirInstruction::Jump { target, edge_args: None })) = + (layout, self.terminator.clone()) + { + let edge_args = EdgeArgs { layout, values }; + self.set_jump_with_edge_args(target, Some(edge_args)); + } } /// Clear legacy jump args metadata (migration helper) diff --git a/src/mir/verification/cfg.rs b/src/mir/verification/cfg.rs index cfe5804b..62e1445b 100644 --- a/src/mir/verification/cfg.rs +++ b/src/mir/verification/cfg.rs @@ -70,18 +70,19 @@ pub fn check_control_flow(function: &MirFunction) -> Result<(), Vec { - if block.has_legacy_jump_args() - && (then_edge_args.is_some() || else_edge_args.is_some()) - { + MirInstruction::Jump { edge_args: None, .. } => { + if block.has_legacy_jump_args() { errors.push(VerificationError::ControlFlowError { block: *block_id, - reason: "Legacy jump_args present on multi-edge terminator with edge-args" - .to_string(), + reason: "Legacy jump_args present but Jump edge-args missing".to_string(), + }); + } + } + MirInstruction::Branch { .. } => { + if block.has_legacy_jump_args() { + errors.push(VerificationError::ControlFlowError { + block: *block_id, + reason: "Legacy jump_args present on Branch terminator".to_string(), }); } } diff --git a/src/runtime/runtime_profile.rs b/src/runtime/runtime_profile.rs index f5652a4d..879f5b2f 100644 --- a/src/runtime/runtime_profile.rs +++ b/src/runtime/runtime_profile.rs @@ -83,25 +83,37 @@ impl RuntimeProfile { #[cfg(test)] mod tests { use super::*; + use std::sync::Mutex; + + static ENV_LOCK: Mutex<()> = Mutex::new(()); + + fn with_env_lock(f: F) { + let _guard = ENV_LOCK.lock().expect("env lock poisoned"); + f(); + } #[test] fn test_runtime_profile_from_env_default() { - // Without setting env, should return Default - std::env::remove_var("NYASH_RUNTIME_PROFILE"); - assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::Default); + with_env_lock(|| { + // Without setting env, should return Default + std::env::remove_var("NYASH_RUNTIME_PROFILE"); + assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::Default); + }); } #[test] fn test_runtime_profile_from_env_nofs() { - // Test "no-fs" variant - std::env::set_var("NYASH_RUNTIME_PROFILE", "no-fs"); - assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::NoFs); + with_env_lock(|| { + // Test "no-fs" variant + std::env::set_var("NYASH_RUNTIME_PROFILE", "no-fs"); + assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::NoFs); - // Test "nofs" variant - std::env::set_var("NYASH_RUNTIME_PROFILE", "nofs"); - assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::NoFs); + // Test "nofs" variant + std::env::set_var("NYASH_RUNTIME_PROFILE", "nofs"); + assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::NoFs); - std::env::remove_var("NYASH_RUNTIME_PROFILE"); + std::env::remove_var("NYASH_RUNTIME_PROFILE"); + }); } #[test] @@ -112,9 +124,11 @@ mod tests { #[test] fn test_runtime_profile_from_env_unknown_defaults_to_default() { - // Unknown profile env var → Default に fallback - std::env::set_var("NYASH_RUNTIME_PROFILE", "unknown-profile"); - assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::Default); - std::env::remove_var("NYASH_RUNTIME_PROFILE"); + with_env_lock(|| { + // Unknown profile env var → Default に fallback + std::env::set_var("NYASH_RUNTIME_PROFILE", "unknown-profile"); + assert_eq!(RuntimeProfile::from_env(), RuntimeProfile::Default); + std::env::remove_var("NYASH_RUNTIME_PROFILE"); + }); } }