This commit is contained in:
Jean-Marie Mineau 2024-07-18 11:50:53 +02:00
parent cb80922d38
commit d479fbba6d
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2

View file

@ -7,7 +7,7 @@ use std::collections::{HashMap, HashSet};
use pyo3::prelude::*;
use crate::{
ins, ins::Instruction, DexString, IdField, IdMethod, IdMethodType, IdType, MethodHandle, Result,
ins::Instruction, DexString, IdField, IdMethod, IdMethodType, IdType, MethodHandle, Result,
};
// TODO: make this easy to edit/manipulate, maybe move to Method
@ -163,50 +163,50 @@ impl Code {
let mut used_labels = HashSet::new();
for ins in &self.insns {
match ins {
Instruction::Goto(ins::Goto { label }) => {
Instruction::Goto { label } => {
used_labels.insert(label.clone());
}
Instruction::IfEq(ins::IfEq { label, .. }) => {
Instruction::IfEq { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::IfNe(ins::IfNe { label, .. }) => {
Instruction::IfNe { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::IfLt(ins::IfLt { label, .. }) => {
Instruction::IfLt { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::IfGe(ins::IfGe { label, .. }) => {
Instruction::IfGe { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::IfGt(ins::IfGt { label, .. }) => {
Instruction::IfGt { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::IfLe(ins::IfLe { label, .. }) => {
Instruction::IfLe { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::IfEqZ(ins::IfEqZ { label, .. }) => {
Instruction::IfEqZ { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::IfNeZ(ins::IfNeZ { label, .. }) => {
Instruction::IfNeZ { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::IfLtZ(ins::IfLtZ { label, .. }) => {
Instruction::IfLtZ { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::IfGeZ(ins::IfGeZ { label, .. }) => {
Instruction::IfGeZ { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::IfGtZ(ins::IfGtZ { label, .. }) => {
Instruction::IfGtZ { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::IfLeZ(ins::IfLeZ { label, .. }) => {
Instruction::IfLeZ { label, .. } => {
used_labels.insert(label.clone());
}
Instruction::Try(ins::Try {
Instruction::Try {
end_label,
handlers,
default_handler,
}) => {
} => {
used_labels.insert(end_label.clone());
for (_, label) in handlers {
used_labels.insert(label.clone());
@ -215,7 +215,7 @@ impl Code {
used_labels.insert(label.clone());
}
}
Instruction::Switch(ins::Switch { branches, .. }) => {
Instruction::Switch { branches, .. } => {
for label in branches.values() {
used_labels.insert(label.clone());
}
@ -239,7 +239,7 @@ impl Code {
for ins in &self.insns {
match ins {
Instruction::Label(ins::Label { name }) => {
Instruction::Label { name } => {
if used_labels.get(name).is_none() {
continue;
}
@ -265,185 +265,193 @@ impl Code {
let mut new_insns = vec![];
last_ins_was_a_label = false;
for ins in self.insns.iter().cloned() {
for ins in self.insns.into_iter() {
match ins {
Instruction::Goto(mut instr) => {
Instruction::Goto { label } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::Goto(instr));
new_insns.push(Instruction::Goto { label });
}
Instruction::IfEq(mut instr) => {
Instruction::IfEq { label, a, b } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfEq(instr));
new_insns.push(Instruction::IfEq { label, a, b });
}
Instruction::IfNe(mut instr) => {
Instruction::IfNe { label, a, b } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfNe(instr));
new_insns.push(Instruction::IfNe { label, a, b });
}
Instruction::IfLt(mut instr) => {
Instruction::IfLt { label, a, b } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfLt(instr));
new_insns.push(Instruction::IfLt { label, a, b });
}
Instruction::IfGe(mut instr) => {
Instruction::IfGe { label, a, b } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfGe(instr));
new_insns.push(Instruction::IfGe { label, a, b });
}
Instruction::IfGt(mut instr) => {
Instruction::IfGt { label, a, b } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfGt(instr));
new_insns.push(Instruction::IfGt { label, a, b });
}
Instruction::IfLe(mut instr) => {
Instruction::IfLe { label, a, b } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfLe(instr));
new_insns.push(Instruction::IfLe { label, a, b });
}
Instruction::IfEqZ(mut instr) => {
Instruction::IfEqZ { label, a } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfEqZ(instr));
new_insns.push(Instruction::IfEqZ { label, a });
}
Instruction::IfNeZ(mut instr) => {
Instruction::IfNeZ { label, a } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfNeZ(instr));
new_insns.push(Instruction::IfNeZ { label, a });
}
Instruction::IfLtZ(mut instr) => {
Instruction::IfLtZ { label, a } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfLtZ(instr));
new_insns.push(Instruction::IfLtZ { label, a });
}
Instruction::IfGeZ(mut instr) => {
Instruction::IfGeZ { label, a } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfGeZ(instr));
new_insns.push(Instruction::IfGeZ { label, a });
}
Instruction::IfGtZ(mut instr) => {
Instruction::IfGtZ { label, a } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfGtZ(instr));
new_insns.push(Instruction::IfGtZ { label, a });
}
Instruction::IfLeZ(mut instr) => {
Instruction::IfLeZ { label, a } => {
last_ins_was_a_label = false;
instr.label = new_labels
.get(&instr.label)
let label = new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.label
label
))?
.clone();
new_insns.push(Instruction::IfLeZ(instr));
new_insns.push(Instruction::IfLeZ { label, a });
}
Instruction::Try(mut instr) => {
Instruction::Try {
end_label,
mut handlers,
default_handler,
} => {
last_ins_was_a_label = false;
instr.end_label = new_labels
.get(&instr.end_label)
let end_label = new_labels
.get(&end_label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.end_label
end_label
))?
.clone();
for i in 0..instr.handlers.len() {
instr.handlers[i].1 = new_labels
.get(&instr.handlers[i].1)
for i in 0..handlers.len() {
handlers[i].1 = new_labels
.get(&handlers[i].1)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
instr.handlers[i].1
handlers[i].1
))?
.clone();
}
if let Some(label) = instr.default_handler {
instr.default_handler = Some(
let default_handler = default_handler
.map(|label| {
new_labels
.get(&label)
.ok_or(anyhow!(
"Internal error: {} not found in renamed label",
label
))?
.clone(),
);
}
new_insns.push(Instruction::Try(instr));
))
.cloned()
})
.transpose()?;
new_insns.push(Instruction::Try {
end_label,
handlers,
default_handler,
});
}
Instruction::Switch(mut instr) => {
Instruction::Switch { mut branches, reg } => {
last_ins_was_a_label = false;
for label in instr.branches.values_mut() {
for label in branches.values_mut() {
*label = new_labels
.get(label)
.ok_or(anyhow!(
@ -452,15 +460,15 @@ impl Code {
))?
.clone();
}
new_insns.push(Instruction::Switch(instr));
new_insns.push(Instruction::Switch { branches, reg });
}
Instruction::Label(ins::Label { name }) => {
Instruction::Label { name } => {
if used_labels.get(&name).is_none() {
//println!("{name} not used");
continue;
}
if !last_ins_was_a_label {
new_insns.push(Instruction::Label(ins::Label {
new_insns.push(Instruction::Label {
name: new_labels
.get(&name)
.ok_or(anyhow!(
@ -468,7 +476,7 @@ impl Code {
name
))?
.clone(),
}));
});
}
last_ins_was_a_label = true;
}