ZJIT: Don't stringify Function in ValidationError

That's not the validator's responsibility; the caller can choose to
later.
This commit is contained in:
Max Bernstein 2025-07-11 10:57:16 -04:00 committed by Max Bernstein
parent 12d44dbc49
commit e3456d6180

View file

@ -917,17 +917,16 @@ impl<T: Copy + Into<usize> + PartialEq> UnionFind<T> {
#[derive(Debug, PartialEq)]
pub enum ValidationError {
// All validation errors come with the function's representation as the first argument.
BlockHasNoTerminator(String, BlockId),
BlockHasNoTerminator(BlockId),
// The terminator and its actual position
TerminatorNotAtEnd(String, BlockId, InsnId, usize),
TerminatorNotAtEnd(BlockId, InsnId, usize),
/// Expected length, actual length
MismatchedBlockArity(String, BlockId, usize, usize),
JumpTargetNotInRPO(String, BlockId),
MismatchedBlockArity(BlockId, usize, usize),
JumpTargetNotInRPO(BlockId),
// The offending instruction, and the operand
OperandNotDefined(String, BlockId, InsnId, InsnId),
OperandNotDefined(BlockId, InsnId, InsnId),
/// The offending block and instruction
DuplicateInstruction(String, BlockId, InsnId),
DuplicateInstruction(BlockId, InsnId),
}
@ -2072,7 +2071,7 @@ impl Function {
let target_len = target_block.params.len();
let args_len = args.len();
if target_len != args_len {
return Err(ValidationError::MismatchedBlockArity(format!("{:?}", self), block_id, target_len, args_len))
return Err(ValidationError::MismatchedBlockArity(block_id, target_len, args_len))
}
}
_ => {}
@ -2082,11 +2081,11 @@ impl Function {
}
block_has_terminator = true;
if idx != insns.len() - 1 {
return Err(ValidationError::TerminatorNotAtEnd(format!("{:?}", self), block_id, *insn_id, idx));
return Err(ValidationError::TerminatorNotAtEnd(block_id, *insn_id, idx));
}
}
if !block_has_terminator {
return Err(ValidationError::BlockHasNoTerminator(format!("{:?}", self), block_id));
return Err(ValidationError::BlockHasNoTerminator(block_id));
}
}
Ok(())
@ -2122,8 +2121,7 @@ impl Function {
match self.find(insn_id) {
Insn::Jump(target) | Insn::IfTrue { target, .. } | Insn::IfFalse { target, .. } => {
let Some(block_in) = assigned_in[target.target.0].as_mut() else {
let fun_string = format!("{:?}", self);
return Err(ValidationError::JumpTargetNotInRPO(fun_string, target.target));
return Err(ValidationError::JumpTargetNotInRPO(target.target));
};
// jump target's block_in was modified, we need to queue the block for processing.
if block_in.intersect_with(&assigned) {
@ -2150,7 +2148,7 @@ impl Function {
self.worklist_traverse_single_insn(&insn, &mut operands);
for operand in operands {
if !assigned.get(operand) {
return Err(ValidationError::OperandNotDefined(format!("{:?}", self), block, insn_id, operand));
return Err(ValidationError::OperandNotDefined(block, insn_id, operand));
}
}
if insn.has_output() {
@ -2168,7 +2166,7 @@ impl Function {
for &insn_id in &self.blocks[block_id.0].insns {
let insn_id = self.union_find.borrow().find_const(insn_id);
if !seen.insert(insn_id) {
return Err(ValidationError::DuplicateInstruction(format!("{:?}", self), block_id, insn_id));
return Err(ValidationError::DuplicateInstruction(block_id, insn_id));
}
}
}
@ -3279,7 +3277,7 @@ mod validation_tests {
let mut function = Function::new(std::ptr::null());
let entry = function.entry_block;
function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) });
assert_matches_err(function.validate(), ValidationError::BlockHasNoTerminator(format!("{:?}", function), entry));
assert_matches_err(function.validate(), ValidationError::BlockHasNoTerminator(entry));
}
#[test]
@ -3289,7 +3287,7 @@ mod validation_tests {
let val = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) });
let insn_id = function.push_insn(entry, Insn::Return { val });
function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) });
assert_matches_err(function.validate(), ValidationError::TerminatorNotAtEnd(format!("{:?}", function), entry, insn_id, 1));
assert_matches_err(function.validate(), ValidationError::TerminatorNotAtEnd(entry, insn_id, 1));
}
#[test]
@ -3299,7 +3297,7 @@ mod validation_tests {
let side = function.new_block();
let val = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) });
function.push_insn(entry, Insn::IfTrue { val, target: BranchEdge { target: side, args: vec![val, val, val] } });
assert_matches_err(function.validate(), ValidationError::MismatchedBlockArity(format!("{:?}", function), entry, 0, 3));
assert_matches_err(function.validate(), ValidationError::MismatchedBlockArity(entry, 0, 3));
}
#[test]
@ -3309,7 +3307,7 @@ mod validation_tests {
let side = function.new_block();
let val = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) });
function.push_insn(entry, Insn::IfFalse { val, target: BranchEdge { target: side, args: vec![val, val, val] } });
assert_matches_err(function.validate(), ValidationError::MismatchedBlockArity(format!("{:?}", function), entry, 0, 3));
assert_matches_err(function.validate(), ValidationError::MismatchedBlockArity(entry, 0, 3));
}
#[test]
@ -3319,7 +3317,7 @@ mod validation_tests {
let side = function.new_block();
let val = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) });
function.push_insn(entry, Insn::Jump ( BranchEdge { target: side, args: vec![val, val, val] } ));
assert_matches_err(function.validate(), ValidationError::MismatchedBlockArity(format!("{:?}", function), entry, 0, 3));
assert_matches_err(function.validate(), ValidationError::MismatchedBlockArity(entry, 0, 3));
}
#[test]
@ -3329,8 +3327,7 @@ mod validation_tests {
// Create an instruction without making it belong to anything.
let dangling = function.new_insn(Insn::Const{val: Const::CBool(true)});
let val = function.push_insn(function.entry_block, Insn::ArrayDup { val: dangling, state: InsnId(0usize) });
let fun_string = format!("{:?}", function);
assert_matches_err(function.validate_definite_assignment(), ValidationError::OperandNotDefined(fun_string, entry, val, dangling));
assert_matches_err(function.validate_definite_assignment(), ValidationError::OperandNotDefined(entry, val, dangling));
}
#[test]
@ -3341,8 +3338,7 @@ mod validation_tests {
// Ret is a non-output instruction.
let ret = function.push_insn(function.entry_block, Insn::Return { val: const_ });
let val = function.push_insn(function.entry_block, Insn::ArrayDup { val: ret, state: InsnId(0usize) });
let fun_string = format!("{:?}", function);
assert_matches_err(function.validate_definite_assignment(), ValidationError::OperandNotDefined(fun_string, entry, val, ret));
assert_matches_err(function.validate_definite_assignment(), ValidationError::OperandNotDefined(entry, val, ret));
}
#[test]
@ -3360,8 +3356,7 @@ mod validation_tests {
let val2 = function.push_insn(exit, Insn::ArrayDup { val: v0, state: v0 });
crate::cruby::with_rubyvm(|| {
function.infer_types();
let fun_string = format!("{:?}", function);
assert_matches_err(function.validate_definite_assignment(), ValidationError::OperandNotDefined(fun_string, exit, val2, v0));
assert_matches_err(function.validate_definite_assignment(), ValidationError::OperandNotDefined(exit, val2, v0));
});
}
@ -3392,7 +3387,7 @@ mod validation_tests {
let val = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) });
function.push_insn_id(entry, val);
function.push_insn(entry, Insn::Return { val });
assert_matches_err(function.validate(), ValidationError::DuplicateInstruction(format!("{:?}", function), entry, val));
assert_matches_err(function.validate(), ValidationError::DuplicateInstruction(entry, val));
}
#[test]
@ -3403,7 +3398,7 @@ mod validation_tests {
let val1 = function.push_insn(entry, Insn::Const { val: Const::Value(Qnil) });
function.make_equal_to(val1, val0);
function.push_insn(entry, Insn::Return { val: val0 });
assert_matches_err(function.validate(), ValidationError::DuplicateInstruction(format!("{:?}", function), entry, val0));
assert_matches_err(function.validate(), ValidationError::DuplicateInstruction(entry, val0));
}
#[test]
@ -3415,7 +3410,7 @@ mod validation_tests {
function.push_insn(entry, Insn::Jump(BranchEdge { target: exit, args: vec![] }));
function.push_insn_id(exit, val);
function.push_insn(exit, Insn::Return { val });
assert_matches_err(function.validate(), ValidationError::DuplicateInstruction(format!("{:?}", function), exit, val));
assert_matches_err(function.validate(), ValidationError::DuplicateInstruction(exit, val));
}
}