use jstd::registry::Registry;
use qcode::{
context::{Context, Shared},
value::{
BodyView, FunctionBody, FunctionId, function::FunctionInterface, util::body_mut::BodyMut,
},
};
pub mod cfg;
pub mod dce;
pub mod symbolize;
mod terminator;
pub use cfg::absorb_straight_line;
pub use dce::{dead_insns, remove_dead_insns, remove_dead_insns_body};
pub use symbolize::{resolve_addresses, resolve_strings};
pub use terminator::replace_terminator_with_branch;
#[derive(Clone, Copy)]
pub struct PassCtx<'ctx, 'str> {
shared: &'ctx Shared<'str>,
interfaces: &'ctx Registry<FunctionId, FunctionInterface<'str>>,
}
impl<'ctx, 'str> PassCtx<'ctx, 'str> {
pub fn new(ctx: &'ctx Context<'str>) -> Self {
Self {
shared: &ctx.shared,
interfaces: &ctx.interfaces,
}
}
pub fn from_parts(
shared: &'ctx Shared<'str>,
interfaces: &'ctx Registry<FunctionId, FunctionInterface<'str>>,
) -> Self {
Self { shared, interfaces }
}
pub fn shr(&self) -> &'ctx Shared<'str> {
self.shared
}
pub fn interface(&self, f: FunctionId) -> &'ctx FunctionInterface<'str> {
&self.interfaces[f]
}
pub fn interfaces(&self) -> &'ctx Registry<FunctionId, FunctionInterface<'str>> {
self.interfaces
}
pub fn body_view<'body>(self, body: &'body FunctionBody<'str>) -> BodyView<'body, 'str>
where
'ctx: 'body,
{
BodyView::new(body, self.shared, self.interfaces)
}
pub fn host<'body>(self, body: &'body mut FunctionBody<'str>) -> BodyMut<'body, 'str>
where
'ctx: 'body,
{
BodyMut::new(body, self.shared, self.interfaces)
}
}
pub fn split<'a, 'str>(
ctx: &'a mut Context<'str>,
) -> (
&'a mut Registry<FunctionId, FunctionBody<'str>>,
PassCtx<'a, 'str>,
) {
(
&mut ctx.bodies,
PassCtx {
shared: &ctx.shared,
interfaces: &ctx.interfaces,
},
)
}
pub fn with_body_mut<'str, R>(
ctx: &mut Context<'str>,
fid: FunctionId,
f: impl FnOnce(&mut FunctionBody<'str>, PassCtx<'_, 'str>) -> R,
) -> R {
let (bodies, view) = split(ctx);
f(&mut bodies[fid], view)
}