Skip to main content

neo_decompiler/decompiler/cfg/basic_block/
block.rs

1use std::ops::Range;
2
3use super::block_id::BlockId;
4use super::terminator::Terminator;
5
6/// A basic block: a sequence of instructions with single entry and exit.
7#[derive(Debug, Clone)]
8pub struct BasicBlock {
9    /// Unique identifier for this block.
10    pub id: BlockId,
11    /// Starting bytecode offset of this block.
12    pub start_offset: usize,
13    /// Ending bytecode offset (exclusive) of this block.
14    pub end_offset: usize,
15    /// Instructions in this block (references by offset range).
16    pub instruction_range: Range<usize>,
17    /// How this block terminates.
18    pub terminator: Terminator,
19}
20
21impl BasicBlock {
22    /// Create a new basic block.
23    #[must_use]
24    pub fn new(
25        id: BlockId,
26        start_offset: usize,
27        end_offset: usize,
28        instruction_range: Range<usize>,
29        terminator: Terminator,
30    ) -> Self {
31        Self {
32            id,
33            start_offset,
34            end_offset,
35            instruction_range,
36            terminator,
37        }
38    }
39
40    /// Check if this block contains the given offset.
41    #[must_use]
42    pub fn contains_offset(&self, offset: usize) -> bool {
43        offset >= self.start_offset && offset < self.end_offset
44    }
45
46    /// Get the number of instructions in this block.
47    #[must_use]
48    pub fn instruction_count(&self) -> usize {
49        self.instruction_range.len()
50    }
51
52    /// Check if this is an empty block (no instructions).
53    #[must_use]
54    pub fn is_empty(&self) -> bool {
55        self.instruction_range.is_empty()
56    }
57}