use crate::{CustomSection, Encode, Section, SectionId};
use alloc::borrow::Cow;
use alloc::vec::Vec;
#[derive(Default, Debug)]
pub struct BranchHints {
bytes: Vec<u8>,
num_hints: u32,
}
#[derive(Debug, Clone, Copy)]
pub struct BranchHint {
pub branch_func_offset: u32,
pub branch_hint_value: u32,
}
impl BranchHints {
pub fn new() -> Self {
Self::default()
}
pub fn function_hints<I>(&mut self, func: u32, hints: I)
where
I: IntoIterator<Item = BranchHint>,
I::IntoIter: ExactSizeIterator,
{
self.num_hints += 1;
func.encode(&mut self.bytes);
let hints = hints.into_iter();
hints.len().encode(&mut self.bytes);
for hint in hints {
hint.branch_func_offset.encode(&mut self.bytes);
1u32.encode(&mut self.bytes);
hint.branch_hint_value.encode(&mut self.bytes);
}
}
pub fn is_empty(&self) -> bool {
self.num_hints == 0
}
pub fn len(&self) -> u32 {
self.num_hints
}
}
impl Encode for BranchHints {
fn encode(&self, sink: &mut Vec<u8>) {
let mut data = Vec::new();
self.num_hints.encode(&mut data);
data.extend(&self.bytes);
CustomSection {
name: "metadata.code.branch_hint".into(),
data: Cow::Borrowed(&data),
}
.encode(sink);
}
}
impl Section for BranchHints {
fn id(&self) -> u8 {
SectionId::Custom.into()
}
}