vm(compare): fix BoxRef(IntegerBox) comparisons by upstream casts and fallbacks; unify IntegerBox (re-export); as_bool truthiness; NewBox primitive fastpath; phi minimal fallback; add temp debug logs for route tracing
This commit is contained in:
@ -225,6 +225,15 @@ pub struct VM {
|
||||
}
|
||||
|
||||
impl VM {
|
||||
/// Helper: execute phi via loop executor (exposes private field safely)
|
||||
pub(super) fn loop_execute_phi(&mut self, _dst: ValueId, inputs: &[(BasicBlockId, ValueId)]) -> Result<VMValue, VMError> {
|
||||
// 80/20 minimal: select first input when we can't safely borrow executor + self simultaneously
|
||||
if let Some((_, val_id)) = inputs.first() {
|
||||
self.get_value(*val_id)
|
||||
} else {
|
||||
Err(VMError::InvalidInstruction("Phi node has no inputs".to_string()))
|
||||
}
|
||||
}
|
||||
/// Create a new VM instance
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
@ -429,6 +438,7 @@ impl VM {
|
||||
/// Execute a single instruction
|
||||
fn execute_instruction(&mut self, instruction: &MirInstruction) -> Result<ControlFlow, VMError> {
|
||||
// Record instruction for stats
|
||||
eprintln!("[VM] execute_instruction: {:?}", instruction);
|
||||
self.record_instruction(instruction);
|
||||
|
||||
match instruction {
|
||||
@ -447,12 +457,17 @@ impl VM {
|
||||
self.execute_unaryop(*dst, op, *operand),
|
||||
|
||||
MirInstruction::Compare { dst, op, lhs, rhs } => {
|
||||
// Fast path: compare IntegerBox values by unboxing to i64
|
||||
eprintln!("[VM] dispatch Compare op={:?} lhs={:?} rhs={:?}", op, lhs, rhs);
|
||||
// Fast path: if both BoxRef, try numeric parse and compare
|
||||
if let (Ok(lv), Ok(rv)) = (self.get_value(*lhs), self.get_value(*rhs)) {
|
||||
eprintln!("[VM] values before fastpath: left={:?} right={:?}", lv, rv);
|
||||
if let (VMValue::BoxRef(lb), VMValue::BoxRef(rb)) = (&lv, &rv) {
|
||||
if lb.type_name() == "IntegerBox" && rb.type_name() == "IntegerBox" {
|
||||
let li = if let Some(ib) = lb.as_any().downcast_ref::<crate::box_trait::IntegerBox>() { ib.value } else { lb.to_string_box().value.parse::<i64>().unwrap_or(0) };
|
||||
let ri = if let Some(ib) = rb.as_any().downcast_ref::<crate::box_trait::IntegerBox>() { ib.value } else { rb.to_string_box().value.parse::<i64>().unwrap_or(0) };
|
||||
eprintln!("[VM] BoxRef types: lty={} rty={} lstr={} rstr={}", lb.type_name(), rb.type_name(), lb.to_string_box().value, rb.to_string_box().value);
|
||||
let li = lb.as_any().downcast_ref::<crate::box_trait::IntegerBox>().map(|x| x.value)
|
||||
.or_else(|| lb.to_string_box().value.trim().parse::<i64>().ok());
|
||||
let ri = rb.as_any().downcast_ref::<crate::box_trait::IntegerBox>().map(|x| x.value)
|
||||
.or_else(|| rb.to_string_box().value.trim().parse::<i64>().ok());
|
||||
if let (Some(li), Some(ri)) = (li, ri) {
|
||||
let out = match op { crate::mir::CompareOp::Eq => li == ri, crate::mir::CompareOp::Ne => li != ri, crate::mir::CompareOp::Lt => li < ri, crate::mir::CompareOp::Le => li <= ri, crate::mir::CompareOp::Gt => li > ri, crate::mir::CompareOp::Ge => li >= ri };
|
||||
self.set_value(*dst, VMValue::Bool(out));
|
||||
return Ok(ControlFlow::Continue);
|
||||
|
||||
Reference in New Issue
Block a user