use crate::ast::AstTargetDialect;
use crate::timing::{TimingCollector, TimingReport};
use super::error::DecompileError;
use super::options::DecompileOptions;
use super::stages::run_decompile_stages;
use super::state::{DecompileContext, DecompileState, StageDebugOutput};
#[derive(Debug, Clone, PartialEq)]
pub struct DecompileResult {
pub state: DecompileState,
pub debug_output: Vec<StageDebugOutput>,
pub timing_report: Option<TimingReport>,
}
pub fn decompile(
bytes: &[u8],
options: DecompileOptions,
) -> Result<DecompileResult, DecompileError> {
DecompilerPipeline.run(bytes, options)
}
struct DecompilerPipeline;
impl DecompilerPipeline {
fn run(
self,
bytes: &[u8],
options: DecompileOptions,
) -> Result<DecompileResult, DecompileError> {
let options = options.normalized();
let mut debug_output = Vec::new();
let timings = TimingCollector::new(options.debug.enable && options.debug.timing);
let requested_target = AstTargetDialect::new(options.dialect);
let context = DecompileContext {
bytes,
options: &options,
timings: &timings,
requested_target,
};
let mut state = DecompileState::new(options.dialect, options.target_stage);
run_decompile_stages(&mut state, &context, &mut debug_output)?;
Ok(DecompileResult {
state,
debug_output,
timing_report: context.timings.finish(),
})
}
}