midenc_debug/
lib.rs

1#![feature(iter_array_chunks)]
2#![allow(unused)]
3
4mod cli;
5mod config;
6mod debug;
7mod exec;
8mod felt;
9mod logger;
10mod ui;
11
12use std::rc::Rc;
13
14use midenc_session::{
15    diagnostics::{IntoDiagnostic, Report},
16    HumanDuration, Session,
17};
18
19pub use self::{
20    cli::Debugger,
21    config::DebuggerConfig,
22    debug::*,
23    exec::*,
24    felt::{bytes_to_words, Felt, Felt as TestFelt, FromMidenRepr, ToMidenRepr},
25};
26
27pub type ExecutionResult<T> = Result<T, Report>;
28
29pub fn run(
30    inputs: Option<DebuggerConfig>,
31    args: Vec<miden_processor::Felt>,
32    session: Rc<Session>,
33    logger: Box<dyn log::Log>,
34) -> ExecutionResult<()> {
35    let mut builder = tokio::runtime::Builder::new_current_thread();
36    let rt = builder.enable_all().build().into_diagnostic()?;
37    rt.block_on(async move { start_ui(inputs, args, session, logger).await })
38}
39
40pub fn run_noninteractively(
41    inputs: Option<DebuggerConfig>,
42    args: Vec<miden_processor::Felt>,
43    num_outputs: usize,
44    session: Rc<Session>,
45) -> ExecutionResult<()> {
46    use std::time::Instant;
47
48    use midenc_hir::formatter::ToHex;
49
50    println!("===============================================================================");
51    println!("Run program: {}", session.inputs[0].file_name());
52    println!("-------------------------------------------------------------------------------");
53
54    let state = ui::State::from_inputs(inputs, args, session)?;
55
56    println!(
57        "Executed program with hash {} in {}",
58        state.package.digest().to_hex(),
59        HumanDuration::from(state.execution_duration),
60    );
61
62    // write the stack outputs to the screen.
63    println!("Output: {:?}", state.execution_trace.outputs().stack_truncated(num_outputs));
64
65    // calculate the percentage of padded rows
66    let trace_len_summary = state.execution_trace.trace_len_summary();
67    let padding_percentage = (trace_len_summary.padded_trace_len() - trace_len_summary.trace_len())
68        * 100
69        / trace_len_summary.padded_trace_len();
70
71    // print the required cycles for each component
72    println!(
73        "VM cycles: {} extended to {} steps ({}% padding).
74├── Stack rows: {}
75├── Range checker rows: {}
76└── Chiplets rows: {}
77├── Hash chiplet rows: {}
78├── Bitwise chiplet rows: {}
79├── Memory chiplet rows: {}
80└── Kernel ROM rows: {}",
81        trace_len_summary.trace_len(),
82        trace_len_summary.padded_trace_len(),
83        padding_percentage,
84        trace_len_summary.main_trace_len(),
85        trace_len_summary.range_trace_len(),
86        trace_len_summary.chiplets_trace_len().trace_len(),
87        trace_len_summary.chiplets_trace_len().hash_chiplet_len(),
88        trace_len_summary.chiplets_trace_len().bitwise_chiplet_len(),
89        trace_len_summary.chiplets_trace_len().memory_chiplet_len(),
90        trace_len_summary.chiplets_trace_len().kernel_rom_len(),
91    );
92
93    Ok(())
94}
95
96pub fn trace(
97    _options: Option<DebuggerConfig>,
98    _args: Vec<String>,
99    _session: Rc<Session>,
100) -> ExecutionResult<ExecutionTrace> {
101    todo!()
102}
103
104pub async fn start_ui(
105    inputs: Option<DebuggerConfig>,
106    args: Vec<miden_processor::Felt>,
107    session: Rc<Session>,
108    logger: Box<dyn log::Log>,
109) -> Result<(), Report> {
110    use ratatui::crossterm as term;
111
112    logger::DebugLogger::install(logger);
113
114    let original_hook = std::panic::take_hook();
115    std::panic::set_hook(Box::new(move |panic_info| {
116        let _ = term::terminal::disable_raw_mode();
117        let _ = term::execute!(std::io::stdout(), term::terminal::LeaveAlternateScreen);
118        original_hook(panic_info);
119    }));
120
121    let mut app = ui::App::new(inputs, args, session).await?;
122    app.run().await?;
123
124    Ok(())
125}