Add finer grained control of what register information is printed out

git-svn-id: https://smali.googlecode.com/svn/trunk@625 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com
2010-02-14 20:04:59 +00:00
parent da69b22d6f
commit 1c56c7e750
6 changed files with 342 additions and 39 deletions

View File

@ -6,7 +6,9 @@ import org.jf.dexlib.ItemType;
import org.jf.dexlib.MethodIdItem;
import org.jf.dexlib.Util.ExceptionWithContext;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class AnalyzedInstruction {
/**
@ -63,7 +65,24 @@ public class AnalyzedInstruction {
return predecessors.size();
}
public List<AnalyzedInstruction> getPredecessors() {
return Collections.unmodifiableList(predecessors);
}
private boolean checkPredecessorSorted(AnalyzedInstruction predecessor) {
if (predecessors.size() == 0) {
return true;
}
if (predecessor.getInstructionIndex() <= predecessors.getLast().getInstructionIndex()) {
return false;
}
return true;
}
protected void addPredecessor(AnalyzedInstruction predecessor) {
assert checkPredecessorSorted(predecessor);
predecessors.add(predecessor);
}
@ -80,6 +99,34 @@ public class AnalyzedInstruction {
return true;
}
public int getSuccessorCount() {
return successors.size();
}
public List<AnalyzedInstruction> getSuccesors() {
return Collections.unmodifiableList(successors);
}
/**
* Is this instruction a "beginning instruction". A beginning instruction is defined to be an instruction
* that can be the first successfully executed instruction in the method. The first instruction is always a
* beginning instruction. If the first instruction can throw an exception, and is covered by a try block, then
* the first instruction of any exception handler for that try block is also a beginning instruction. And likewise,
* if any of those instructions can throw an exception and are covered by try blocks, the first instruction of the
* corresponding exception handler is a beginning instruction, etc.
* @return a boolean value indicating whether this instruction is a beginning instruction
*/
public boolean isBeginningInstruction() {
if (predecessors.size() == 0) {
return false;
}
if (predecessors.getFirst().instructionIndex == -1) {
return true;
}
return false;
}
/*
* Sets the "post-instruction" register type as indicated. This should only be used to set
* the method parameter types for the "start of method" instruction, or to set the register

View File

@ -94,7 +94,7 @@ public class ClassPath {
if (classType.charAt(0) == '[') {
return theClassPath.createArrayClassDef(classType);
} else {
//TODO: we should output a warning
//TODO: we should output a warning
return theClassPath.createUnresolvedClassDef(classType);
}
}
@ -571,12 +571,12 @@ public class ClassPath {
if (interfaces != null) {
for (TypeIdItem interfaceType: interfaces.getTypes()) {
ClassDef interfaceDef = ClassPath.getClassDef(interfaceType.getTypeDescriptor());
assert interfaceDef.isInterface;
assert interfaceDef.isInterface();
implementedInterfaceSet.add(interfaceDef);
interfaceDef = interfaceDef.getSuperclass();
while (!interfaceDef.getClassType().equals("Ljava/lang/Object;")) {
assert interfaceDef.isInterface;
assert interfaceDef.isInterface();
implementedInterfaceSet.add(interfaceDef);
interfaceDef = interfaceDef.getSuperclass();
}

View File

@ -183,6 +183,10 @@ public class MethodAnalyzer {
(encodedMethod.accessFlags & AccessFlags.CONSTRUCTOR.getValue()) != 0;
}
public AnalyzedInstruction getStartOfMethod() {
return startOfMethod;
}
public AnalyzedInstruction[] makeInstructionArray() {
AnalyzedInstruction[] instructionArray = new AnalyzedInstruction[instructions.size()];
for (int i=0; i<instructions.size(); i++) {
@ -214,7 +218,7 @@ public class MethodAnalyzer {
return registerTypes;
}
private int getInstructionAddress(AnalyzedInstruction instruction) {
public int getInstructionAddress(AnalyzedInstruction instruction) {
return instructions.keyAt(instruction.instructionIndex);
}