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 println!("Output: {:?}", state.execution_trace.outputs().stack_truncated(num_outputs));
64
65 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 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}