zingen/jump/
pc.rs

1//! Program counter handlers.
2//!
3//! This module provides functionality to shift the program counter for various jump types
4//! and manage the relationships between labels and their corresponding program counters.
5
6use crate::{jump::JumpTable, Error, Result, BUFFER_LIMIT};
7
8impl JumpTable {
9    /// Shifts the program counter for all jump items.
10    ///
11    /// This function updates the program counters based on a starting point and an offset.
12    pub fn shift_pc(&mut self, start: u16, offset: u16) -> Result<()> {
13        tracing::trace!("shift pc from 0x{start:x} with offset={offset}");
14        self.shift_label_pc(start, offset)?;
15        self.shift_label_target(start, offset)?;
16        self.shift_func_target(start, offset)
17    }
18
19    /// Shifts the program counter for labels.
20    ///
21    /// This function updates the program counters of labels based on the specified start
22    /// point and offset.
23    pub fn shift_label_pc(&mut self, start: u16, offset: u16) -> Result<()> {
24        let mut new_jump = Vec::new();
25        for (label, jump) in self.jump.iter() {
26            let mut label = *label;
27            let next_label = label + offset;
28            if label > start {
29                tracing::trace!(
30                    "shift {jump} pc with offset={offset}: 0x{label:x}(0x{start:x}) -> 0x{:x}",
31                    next_label
32                );
33                label = next_label;
34
35                if label > BUFFER_LIMIT as u16 {
36                    return Err(Error::InvalidPC(label as usize));
37                }
38            }
39
40            new_jump.push((label, jump.clone()));
41        }
42
43        self.jump = new_jump.into_iter().collect();
44        Ok(())
45    }
46}