## 🎯 根本原因(Task先生特定) - `src/mir/loop_builder.rs` L203-215のGUARD checkが誤動作 - ValueId(0)を「常に未初期化」と判定していたが、実際には**最初のパラメータとして正当** - skip_whitespace(s, idx)のsがValueId(0)で弾かれ、ループが生成されない ## ✅ 修正内容 - GUARD check完全削除(L203-215) - 経緯説明コメント追加 ## ✅ 修正効果 - ループブロック生成: 33 blocks確認 - 既存テスト: 全PASS(mir_basic_loop, mir_loopform_exit_phi) - 回帰なし ## ❌ 別問題発見(次のタスク) - PHI node predecessor mismatch (別バグ) - これはExit PHI生成の問題 ## 📋 調査プロセス - Step 1-3: 最小再現ケース+Rustテスト作成 - Step 4: Task先生でMIR解析→根本原因特定 - Step 5-6: loop_builder.rs修正 - Step 7: 全確認(既存テスト全PASS) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
151 lines
4.4 KiB
Rust
151 lines
4.4 KiB
Rust
//! PoC tests for MIR unified ops and VM execution
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use crate::backend::VM;
|
||
use crate::mir::{BasicBlockId, ConstValue, Effect, EffectMask, MirInstruction, MirType};
|
||
use crate::mir::{FunctionSignature, MirFunction, MirModule};
|
||
|
||
fn make_main() -> MirFunction {
|
||
let sig = FunctionSignature {
|
||
name: "main".to_string(),
|
||
params: vec![],
|
||
return_type: MirType::Void,
|
||
effects: EffectMask::PURE,
|
||
};
|
||
MirFunction::new(sig, BasicBlockId::new(0))
|
||
}
|
||
|
||
// Legacy VM / typeop PoC(現行の VM 実装とは前提がズレるためアーカイブ扱い).
|
||
#[test]
|
||
#[ignore]
|
||
fn vm_exec_typeop_check_and_cast() {
|
||
let mut func = make_main();
|
||
let bb = func.entry_block;
|
||
|
||
let v0 = func.next_value_id();
|
||
func.get_block_mut(bb)
|
||
.unwrap()
|
||
.add_instruction(MirInstruction::Const {
|
||
dst: v0,
|
||
value: ConstValue::Integer(42),
|
||
});
|
||
|
||
let v1 = func.next_value_id();
|
||
func.get_block_mut(bb)
|
||
.unwrap()
|
||
.add_instruction(MirInstruction::TypeOp {
|
||
dst: v1,
|
||
op: crate::mir::TypeOpKind::Check,
|
||
value: v0,
|
||
ty: MirType::Integer,
|
||
});
|
||
|
||
// console.log(result) via ExternCall
|
||
func.get_block_mut(bb)
|
||
.unwrap()
|
||
.add_instruction(MirInstruction::ExternCall {
|
||
dst: None,
|
||
iface_name: "env.console".to_string(),
|
||
method_name: "log".to_string(),
|
||
args: vec![v1],
|
||
effects: EffectMask::IO,
|
||
});
|
||
|
||
// Cast (no-op for PoC semantics)
|
||
let v2 = func.next_value_id();
|
||
func.get_block_mut(bb)
|
||
.unwrap()
|
||
.add_instruction(MirInstruction::TypeOp {
|
||
dst: v2,
|
||
op: crate::mir::TypeOpKind::Cast,
|
||
value: v0,
|
||
ty: MirType::Integer,
|
||
});
|
||
|
||
// Return void
|
||
func.get_block_mut(bb)
|
||
.unwrap()
|
||
.add_instruction(MirInstruction::Return { value: None });
|
||
|
||
let mut module = MirModule::new("test".to_string());
|
||
module.add_function(func);
|
||
|
||
let mut vm = VM::new();
|
||
let _ = vm
|
||
.execute_module(&module)
|
||
.expect("VM should execute module");
|
||
}
|
||
|
||
#[test]
|
||
#[ignore]
|
||
fn vm_exec_typeop_cast_int_float() {
|
||
let mut func = make_main();
|
||
let bb = func.entry_block;
|
||
|
||
let v0 = func.next_value_id();
|
||
func.get_block_mut(bb)
|
||
.unwrap()
|
||
.add_instruction(MirInstruction::Const {
|
||
dst: v0,
|
||
value: ConstValue::Integer(3),
|
||
});
|
||
|
||
let v1 = func.next_value_id();
|
||
func.get_block_mut(bb)
|
||
.unwrap()
|
||
.add_instruction(MirInstruction::TypeOp {
|
||
dst: v1,
|
||
op: crate::mir::TypeOpKind::Cast,
|
||
value: v0,
|
||
ty: MirType::Float,
|
||
});
|
||
func.get_block_mut(bb)
|
||
.unwrap()
|
||
.add_instruction(MirInstruction::Return { value: None });
|
||
|
||
let mut module = MirModule::new("test".to_string());
|
||
module.add_function(func);
|
||
let mut vm = VM::new();
|
||
let _ = vm
|
||
.execute_module(&module)
|
||
.expect("int->float cast should succeed");
|
||
}
|
||
|
||
#[test]
|
||
#[ignore]
|
||
fn vm_exec_typeop_cast_float_int() {
|
||
let mut func = make_main();
|
||
let bb = func.entry_block;
|
||
|
||
let v0 = func.next_value_id();
|
||
func.get_block_mut(bb)
|
||
.unwrap()
|
||
.add_instruction(MirInstruction::Const {
|
||
dst: v0,
|
||
value: ConstValue::Float(3.7),
|
||
});
|
||
|
||
let v1 = func.next_value_id();
|
||
func.get_block_mut(bb)
|
||
.unwrap()
|
||
.add_instruction(MirInstruction::TypeOp {
|
||
dst: v1,
|
||
op: crate::mir::TypeOpKind::Cast,
|
||
value: v0,
|
||
ty: MirType::Integer,
|
||
});
|
||
func.get_block_mut(bb)
|
||
.unwrap()
|
||
.add_instruction(MirInstruction::Return { value: None });
|
||
|
||
let mut module = MirModule::new("test".to_string());
|
||
module.add_function(func);
|
||
let mut vm = VM::new();
|
||
let _ = vm
|
||
.execute_module(&module)
|
||
.expect("float->int cast should succeed");
|
||
}
|
||
}
|
||
|