use crate::instruction::OpCode;
use super::super::super::HighLevelEmitter;
impl HighLevelEmitter {
pub(super) fn is_conditional_branch(opcode: OpCode) -> bool {
matches!(
opcode,
OpCode::Jmpif
| OpCode::Jmpif_L
| OpCode::Jmpifnot
| OpCode::Jmpifnot_L
| OpCode::JmpEq
| OpCode::JmpEq_L
| OpCode::JmpNe
| OpCode::JmpNe_L
| OpCode::JmpGt
| OpCode::JmpGt_L
| OpCode::JmpGe
| OpCode::JmpGe_L
| OpCode::JmpLt
| OpCode::JmpLt_L
| OpCode::JmpLe
| OpCode::JmpLe_L
)
}
pub(super) fn has_internal_crossing_branch(
&self,
branch_offset: usize,
false_target: usize,
) -> bool {
let start_index = self
.index_by_offset
.range((branch_offset + 1)..false_target)
.next()
.map(|(_, index)| *index);
let Some(start_index) = start_index else {
return false;
};
let end_index = self
.index_by_offset
.range(false_target..)
.next()
.map(|(_, index)| *index)
.unwrap_or(self.program.len());
self.program[start_index..end_index].iter().any(|inner| {
Self::is_conditional_branch(inner.opcode)
&& self
.forward_jump_target(inner)
.map(|target| target > false_target)
.unwrap_or(false)
})
}
pub(super) fn has_crossing_closer(&self, target: usize) -> bool {
self.pending_closers
.keys()
.next()
.map(|next_close| target > *next_close)
.unwrap_or(false)
}
}