1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use address::Address;

/// When is this edge taken? Conditionally or unconditionally?
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum EdgeType {
    /// This edge is when a conditional is taken.
    ConditionalTaken,
    /// This edge is when a conditional falls through to the next instruction.
    ConditionalFallthrough,
    /// This is edge is always taken.
    Unconditional,
}

/// A [basic block] is a sequence of instructions with no inward-bound
/// branches except to the entry point and no outward-bound branches
/// except at the exit.
///
/// [basic block]: https://en.wikipedia.org/wiki/Basic_block
#[derive(Debug)]
pub struct BasicBlock {
    /// The name of the basic block. Not all blocks have meaningful names.
    pub name: Option<String>,
    /// The address of the first instruction in the basic block.
    pub address: Address,
    /// The indices instructions within this basic block.
    pub instruction_indices: Vec<usize>,
}

impl BasicBlock {
    /// Construct a new `BasicBlock`.
    pub fn new(address: Address) -> Self {
        BasicBlock {
            name: None,
            address: address,
            instruction_indices: vec![],
        }
    }
}

/// Information about an edge between 2 [basic blocks].
///
/// This represents a branch, jump or other form of control flow
/// transfer within the control flow graph.
///
/// [basic blocks]: struct.BasicBlock.html
#[derive(Debug)]
pub struct BasicBlockEdge {
    /// Is this edge taken [conditionally or unconditionally]?
    ///
    /// [conditionally or unconditionally]: enum.EdgeType.html
    pub edge_type: EdgeType,
}