WIP
This commit is contained in:
parent
cb80922d38
commit
d479fbba6d
1 changed files with 113 additions and 105 deletions
|
|
@ -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)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::Goto(instr));
|
||||
}
|
||||
Instruction::IfEq(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfEq(instr));
|
||||
}
|
||||
Instruction::IfNe(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfNe(instr));
|
||||
}
|
||||
Instruction::IfLt(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfLt(instr));
|
||||
}
|
||||
Instruction::IfGe(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfGe(instr));
|
||||
}
|
||||
Instruction::IfGt(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfGt(instr));
|
||||
}
|
||||
Instruction::IfLe(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfLe(instr));
|
||||
}
|
||||
Instruction::IfEqZ(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfEqZ(instr));
|
||||
}
|
||||
Instruction::IfNeZ(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfNeZ(instr));
|
||||
}
|
||||
Instruction::IfLtZ(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfLtZ(instr));
|
||||
}
|
||||
Instruction::IfGeZ(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfGeZ(instr));
|
||||
}
|
||||
Instruction::IfGtZ(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfGtZ(instr));
|
||||
}
|
||||
Instruction::IfLeZ(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.label = new_labels
|
||||
.get(&instr.label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfLeZ(instr));
|
||||
}
|
||||
Instruction::Try(mut instr) => {
|
||||
last_ins_was_a_label = false;
|
||||
instr.end_label = new_labels
|
||||
.get(&instr.end_label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.end_label
|
||||
))?
|
||||
.clone();
|
||||
for i in 0..instr.handlers.len() {
|
||||
instr.handlers[i].1 = new_labels
|
||||
.get(&instr.handlers[i].1)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
instr.handlers[i].1
|
||||
))?
|
||||
.clone();
|
||||
}
|
||||
if let Some(label) = instr.default_handler {
|
||||
instr.default_handler = Some(
|
||||
new_labels
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone(),
|
||||
);
|
||||
.clone();
|
||||
new_insns.push(Instruction::Goto { label });
|
||||
}
|
||||
new_insns.push(Instruction::Try(instr));
|
||||
}
|
||||
Instruction::Switch(mut instr) => {
|
||||
Instruction::IfEq { label, a, b } => {
|
||||
last_ins_was_a_label = false;
|
||||
for label in instr.branches.values_mut() {
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfEq { label, a, b });
|
||||
}
|
||||
Instruction::IfNe { label, a, b } => {
|
||||
last_ins_was_a_label = false;
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfNe { label, a, b });
|
||||
}
|
||||
Instruction::IfLt { label, a, b } => {
|
||||
last_ins_was_a_label = false;
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfLt { label, a, b });
|
||||
}
|
||||
Instruction::IfGe { label, a, b } => {
|
||||
last_ins_was_a_label = false;
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfGe { label, a, b });
|
||||
}
|
||||
Instruction::IfGt { label, a, b } => {
|
||||
last_ins_was_a_label = false;
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfGt { label, a, b });
|
||||
}
|
||||
Instruction::IfLe { label, a, b } => {
|
||||
last_ins_was_a_label = false;
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfLe { label, a, b });
|
||||
}
|
||||
Instruction::IfEqZ { label, a } => {
|
||||
last_ins_was_a_label = false;
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfEqZ { label, a });
|
||||
}
|
||||
Instruction::IfNeZ { label, a } => {
|
||||
last_ins_was_a_label = false;
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfNeZ { label, a });
|
||||
}
|
||||
Instruction::IfLtZ { label, a } => {
|
||||
last_ins_was_a_label = false;
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfLtZ { label, a });
|
||||
}
|
||||
Instruction::IfGeZ { label, a } => {
|
||||
last_ins_was_a_label = false;
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfGeZ { label, a });
|
||||
}
|
||||
Instruction::IfGtZ { label, a } => {
|
||||
last_ins_was_a_label = false;
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfGtZ { label, a });
|
||||
}
|
||||
Instruction::IfLeZ { label, a } => {
|
||||
last_ins_was_a_label = false;
|
||||
let label = new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))?
|
||||
.clone();
|
||||
new_insns.push(Instruction::IfLeZ { label, a });
|
||||
}
|
||||
Instruction::Try {
|
||||
end_label,
|
||||
mut handlers,
|
||||
default_handler,
|
||||
} => {
|
||||
last_ins_was_a_label = false;
|
||||
let end_label = new_labels
|
||||
.get(&end_label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
end_label
|
||||
))?
|
||||
.clone();
|
||||
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",
|
||||
handlers[i].1
|
||||
))?
|
||||
.clone();
|
||||
}
|
||||
let default_handler = default_handler
|
||||
.map(|label| {
|
||||
new_labels
|
||||
.get(&label)
|
||||
.ok_or(anyhow!(
|
||||
"Internal error: {} not found in renamed label",
|
||||
label
|
||||
))
|
||||
.cloned()
|
||||
})
|
||||
.transpose()?;
|
||||
new_insns.push(Instruction::Try {
|
||||
end_label,
|
||||
handlers,
|
||||
default_handler,
|
||||
});
|
||||
}
|
||||
Instruction::Switch { mut branches, reg } => {
|
||||
last_ins_was_a_label = false;
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue