use crate::Program;
use crate::bytecode::{Instruction, InstructionStream};
use super::error::VerifierError;
use super::phase::Phase;
use super::scan::stream_err;
pub struct JumpTargetPhase;
impl Phase for JumpTargetPhase {
type Error = VerifierError;
fn run(&self, program: &Program) -> Result<(), VerifierError> {
let target_count = program.jump_table().len();
let mut stream = InstructionStream::new(program.code());
while let Some(item) = stream.next_instruction() {
let (pos, _label, instr) = item.map_err(|e| stream_err(&e))?;
match instr {
Instruction::Jump1 { label } | Instruction::JumpI1 { label }
if usize::from(label) >= target_count =>
{
return Err(VerifierError::UndefinedJumpTarget {
offset: pos,
label: u16::from(label),
target_count,
});
}
Instruction::Jump2 { label } | Instruction::JumpI2 { label }
if usize::from(label) >= target_count =>
{
return Err(VerifierError::UndefinedJumpTarget {
offset: pos,
label,
target_count,
});
}
_ => {}
}
}
Ok(())
}
}