midenc_codegen_masm/emulator/
debug.rs

1use std::fmt;
2
3use midenc_hir::{Felt, FunctionIdent, OperandStack};
4
5use super::{Addr, InstructionPointer, InstructionWithOp};
6
7/// Represents basic information about a frame on the call stack
8pub struct CallFrame {
9    pub function: FunctionIdent,
10    pub fp: Addr,
11    pub ip: Option<InstructionPointer>,
12}
13
14/// Represents the current state of the program being executed for use in debugging/troubleshooting
15pub struct DebugInfo<'a> {
16    /// The current cycle count
17    pub cycle: usize,
18    /// The current function being executed
19    pub function: FunctionIdent,
20    /// The address at which locals for the current function begin
21    pub fp: Addr,
22    /// The current instruction pointer metadata, if one is pending
23    pub ip: Option<InstructionWithOp>,
24    /// The current state of the operand stack
25    pub stack: &'a OperandStack<Felt>,
26}
27impl DebugInfo<'_> {
28    pub fn to_owned(self) -> DebugInfoWithStack {
29        let stack = self.stack.clone();
30        DebugInfoWithStack {
31            cycle: self.cycle,
32            function: self.function,
33            fp: self.fp,
34            ip: self.ip,
35            stack,
36        }
37    }
38}
39impl<'a> fmt::Debug for DebugInfo<'a> {
40    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41        use midenc_hir::Stack;
42
43        f.debug_struct("DebugInfo")
44            .field("cycle", &self.cycle)
45            .field("function", &self.function)
46            .field("fp", &self.fp)
47            .field("ip", &self.ip)
48            .field("stack", &self.stack.debug())
49            .finish()
50    }
51}
52
53/// Same as [DebugInfo], but takes a clone of the operand stack, rather than a reference
54pub struct DebugInfoWithStack {
55    /// The current cycle count
56    pub cycle: usize,
57    /// The current function being executed
58    pub function: FunctionIdent,
59    /// The address at which locals for the current function begin
60    pub fp: Addr,
61    /// The current instruction pointer metadata, if one is pending
62    pub ip: Option<InstructionWithOp>,
63    /// The current state of the operand stack
64    pub stack: OperandStack<Felt>,
65}
66impl fmt::Debug for DebugInfoWithStack {
67    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68        use midenc_hir::Stack;
69
70        f.debug_struct("DebugInfo")
71            .field("cycle", &self.cycle)
72            .field("function", &self.function)
73            .field("fp", &self.fp)
74            .field("ip", &self.ip)
75            .field("stack", &self.stack.debug())
76            .finish()
77    }
78}