feat(joinir): Phase 27.8-4/5 — skip_ws CFG sanity checks + fallback design
- MirQuery API を使用した軽量 CFG チェック実装
- Entry block successors >= 1
- Const(0) 存在確認
- String.length() 存在確認
- 予期しない MIR 構造時の手書き版 fallback 設計
- A/B テスト完了: 手書き版・MIR-based 版両方 PASS ✅
- ドキュメント更新: joinir_coverage.md + IMPLEMENTATION_LOG.md
Phase 27.9 modular refactoring: commit 3d5979c7
Phase 27.8-4/5 verification: CFG checks + docs updates
This commit is contained in:
@ -229,6 +229,9 @@ fn lower_skip_ws_handwritten(module: &crate::mir::MirModule) -> Option<JoinModul
|
||||
/// ## 実装状況:
|
||||
/// - Phase 27.8: 基本実装(MirQuery を使用した MIR 解析)
|
||||
fn lower_skip_ws_from_mir(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
||||
use crate::mir::query::{MirQuery, MirQueryBox};
|
||||
use crate::mir::MirInstruction;
|
||||
|
||||
// Step 1: "Main.skip/1" を探す
|
||||
let target_func = module.functions.get("Main.skip/1")?;
|
||||
|
||||
@ -246,6 +249,34 @@ fn lower_skip_ws_from_mir(module: &crate::mir::MirModule) -> Option<JoinModule>
|
||||
return lower_skip_ws_handwritten(module);
|
||||
}
|
||||
|
||||
// Phase 27.8-4: Lightweight CFG sanity checks
|
||||
// MirQueryBox を使ってパターンマッチング
|
||||
let query = MirQueryBox::new(target_func);
|
||||
let entry_id = target_func.entry_block;
|
||||
|
||||
// Check 1: Entry block has at least 1 successor
|
||||
let entry_succs = query.succs(entry_id);
|
||||
if entry_succs.is_empty() {
|
||||
eprintln!("[joinir/skip_ws/mir] unexpected MIR shape: entry has no successors, falling back to handwritten");
|
||||
return lower_skip_ws_handwritten(module);
|
||||
}
|
||||
|
||||
// Check 2: First block contains Const(0) and BoxCall(String.length)
|
||||
let entry_insts = query.insts_in_block(entry_id);
|
||||
let has_const_0 = entry_insts.iter().any(|inst| {
|
||||
matches!(inst, MirInstruction::Const { value: crate::mir::ConstValue::Integer(0), .. })
|
||||
});
|
||||
let has_string_length = entry_insts.iter().any(|inst| {
|
||||
matches!(inst, MirInstruction::BoxCall { method, .. } if method == "length")
|
||||
});
|
||||
|
||||
if !has_const_0 || !has_string_length {
|
||||
eprintln!("[joinir/skip_ws/mir] unexpected MIR shape: entry block missing Const(0) or String.length, falling back to handwritten");
|
||||
return lower_skip_ws_handwritten(module);
|
||||
}
|
||||
|
||||
eprintln!("[joinir/skip_ws/mir] CFG sanity checks passed ✅");
|
||||
|
||||
// JoinIR の ValueId は手書き版と同じレンジを使い、既存テストと互換にする
|
||||
let skip_id = JoinFuncId::new(0);
|
||||
let loop_step_id = JoinFuncId::new(1);
|
||||
|
||||
Reference in New Issue
Block a user