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