1use fuel_asm::Instruction;
2use fuel_types::{
3 ContractId,
4 Word,
5};
6
7use crate::consts::VM_MAX_RAM;
8
9#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct Breakpoint {
18 contract: ContractId,
19 pc: Word,
20}
21
22impl Breakpoint {
23 pub(crate) const fn raw(contract: ContractId, pc: Word) -> Self {
24 Self { contract, pc }
25 }
26
27 pub const fn new(contract: ContractId, pc: Word) -> Self {
35 let pc = pc.saturating_mul(Instruction::SIZE as Word);
36 assert!(pc <= VM_MAX_RAM, "Breakpoint cannot fit into vm memory");
37 Self::raw(contract, pc)
38 }
39
40 pub fn script(pc: Word) -> Self {
45 let contract = Default::default();
46
47 Self::new(contract, pc)
48 }
49
50 pub const fn contract(&self) -> &ContractId {
52 &self.contract
53 }
54
55 pub const fn pc(&self) -> Word {
57 self.pc
58 }
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
62#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
63pub enum DebugEval {
66 Breakpoint(Breakpoint),
69 Continue,
71}
72
73impl Default for DebugEval {
74 fn default() -> Self {
75 Self::Continue
76 }
77}
78
79impl From<Breakpoint> for DebugEval {
80 fn from(b: Breakpoint) -> Self {
81 Self::Breakpoint(b)
82 }
83}
84
85impl DebugEval {
86 pub const fn should_continue(&self) -> bool {
88 matches!(self, Self::Continue)
89 }
90
91 pub const fn breakpoint(&self) -> Option<&Breakpoint> {
94 match self {
95 Self::Breakpoint(b) => Some(b),
96 _ => None,
97 }
98 }
99}