refactor(joinir): Phase 27.10 - CFG sanity checks + dispatcher pattern 共通化
- common.rs 新規作成(162行): - CFG sanity check helpers: ensure_entry_has_succs, has_const_int, has_const_string, has_string_method, has_binop - Logging helper: log_fallback - Dispatcher: dispatch_lowering - skip_ws.rs: CFG checks (-25行) + dispatcher (-2行) = -27行削減 - funcscanner_trim.rs: CFG checks (-25行) + dispatcher (-4行) = -29行削減 - mod.rs: pub mod common 追加 設計原則: - 軽量パターンマッチング(命令の存在確認のみ) - Graceful degradation(予期しない構造で即座にfallback) - DRY原則(重複コード1箇所に集約) 🎉 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -50,7 +50,20 @@ use crate::mir::join_ir::{
|
||||
LoopExitShape, LoopHeaderShape, MirLikeInst,
|
||||
};
|
||||
|
||||
/// Phase 27.9: Toggle dispatcher for trim lowering
|
||||
/// - Default: handwritten lowering
|
||||
/// - NYASH_JOINIR_LOWER_FROM_MIR=1: MIR-based lowering
|
||||
pub fn lower_funcscanner_trim_to_joinir(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
||||
super::common::dispatch_lowering(
|
||||
"trim",
|
||||
module,
|
||||
lower_trim_from_mir,
|
||||
lower_trim_handwritten,
|
||||
)
|
||||
}
|
||||
|
||||
/// Phase 27.1-27.7: Handwritten JoinIR lowering for FuncScannerBox.trim/1
|
||||
fn lower_trim_handwritten(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
||||
// Step 1: "FuncScannerBox.trim/1" を探す
|
||||
let target_func = module.functions.get("FuncScannerBox.trim/1")?;
|
||||
|
||||
@ -495,3 +508,47 @@ pub fn lower_funcscanner_trim_to_joinir(module: &crate::mir::MirModule) -> Optio
|
||||
|
||||
Some(join_module)
|
||||
}
|
||||
|
||||
/// Phase 27.9: MIR-based lowering for FuncScannerBox.trim/1
|
||||
/// - Lightweight CFG sanity checks
|
||||
/// - Fallback to handwritten if MIR structure is unexpected
|
||||
fn lower_trim_from_mir(module: &crate::mir::MirModule) -> Option<JoinModule> {
|
||||
use crate::mir::query::MirQueryBox;
|
||||
use crate::mir::BinaryOp;
|
||||
use super::common::{ensure_entry_has_succs, has_const_string, has_string_method, has_binop, log_fallback};
|
||||
|
||||
// Step 1: "FuncScannerBox.trim/1" を探す
|
||||
let target_func = module.functions.get("FuncScannerBox.trim/1")?;
|
||||
|
||||
eprintln!("[joinir/trim/mir] Found FuncScannerBox.trim/1 (MIR-based lowering)");
|
||||
eprintln!("[joinir/trim/mir] MIR blocks: {}", target_func.blocks.len());
|
||||
|
||||
// Phase 27.10: Lightweight CFG sanity checks using common utilities
|
||||
let query = MirQueryBox::new(target_func);
|
||||
let entry_id = target_func.entry_block;
|
||||
|
||||
// Check 1: Entry block has at least 1 successor
|
||||
if !ensure_entry_has_succs(&query, entry_id) {
|
||||
log_fallback("trim", "entry has no successors");
|
||||
return lower_trim_handwritten(module);
|
||||
}
|
||||
|
||||
// Check 2: Entry block contains expected patterns
|
||||
// - Const("") for string coercion
|
||||
// - BoxCall(String.length)
|
||||
// - BinOp(Add) for "" + s
|
||||
if !has_const_string(&query, entry_id, "") ||
|
||||
!has_string_method(&query, entry_id, "length") ||
|
||||
!has_binop(&query, entry_id, BinaryOp::Add)
|
||||
{
|
||||
log_fallback("trim", "entry block missing expected patterns (Const(\"\"), String.length, or BinOp(Add))");
|
||||
return lower_trim_handwritten(module);
|
||||
}
|
||||
|
||||
eprintln!("[joinir/trim/mir] CFG sanity checks passed ✅");
|
||||
|
||||
// Phase 27.9: Generate JoinIR (equivalent to handwritten version)
|
||||
// For now, use the same structure as handwritten version
|
||||
// TODO: Full MIR-based construction in future phases
|
||||
lower_trim_handwritten(module)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user