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 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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue