diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java index 2fc3181f..76ce75fe 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java @@ -68,17 +68,17 @@ public class MethodDefinition { if (encodedMethod.codeItem != null) { methodAnalyzer = new MethodAnalyzer(encodedMethod, baksmali.deodex); - AnalyzedInstruction[] instructions = methodAnalyzer.makeInstructionArray(); + List instructions = methodAnalyzer.getInstructions(); packedSwitchMap = new SparseIntArray(1); sparseSwitchMap = new SparseIntArray(1); - instructionMap = new SparseIntArray(instructions.length); + instructionMap = new SparseIntArray(instructions.size()); registerCount = encodedMethod.codeItem.getRegisterCount(); int currentCodeAddress = 0; - for (int i=0; i instructions = methodAnalyzer.getInstructions(); AnalyzedInstruction lastInstruction = null; - for (int i=instructions.length-1; i>=0; i--) { - AnalyzedInstruction instruction = instructions[i]; + for (int i=instructions.size()-1; i>=0; i--) { + AnalyzedInstruction instruction = instructions.get(i); if (!instruction.isDead()) { lastInstruction = instruction; @@ -277,8 +275,8 @@ public class MethodDefinition { BitSet printPostRegister = new BitSet(registerCount); int currentCodeAddress = 0; - for (int i=0; i methodItems, MethodAnalyzer methodAnalyzer, - int instructionNum, int currentCodeAddress) { - if (instructionNum == 0) { - return; - } - - //MethodAnalyzer cached the analyzedInstructions, so we're not actually re-analyzing, just getting the - //instructions that have already been analyzed - AnalyzedInstruction[] instructions = methodAnalyzer.analyze(); - AnalyzedInstruction instruction = instructions[instructionNum]; - + AnalyzedInstruction instruction, int currentCodeAddress) { if (instruction.getPredecessorCount() <= 1) { return; } @@ -482,33 +471,25 @@ public class MethodDefinition { } } - private void addMergeRegs(BitSet printPreRegister, AnalyzedInstruction instructions[], int instructionNum) { - //MethodAnalyzer cached the analyzedInstructions, so we're not actually re-analyzing, just getting the - //instructions that have already been analyzed - AnalyzedInstruction instruction = instructions[instructionNum]; - - if (instructionNum == 0) { + private void addMergeRegs(BitSet printPreRegister, AnalyzedInstruction instruction) { + if (instruction.isBeginningInstruction()) { addParamRegs(printPreRegister); - } else { - if (instruction.isBeginningInstruction()) { - addParamRegs(printPreRegister); - } + } - if (instruction.getPredecessorCount() <= 1) { - //in the common case of an instruction that only has a single predecessor which is the previous - //instruction, the pre-instruction registers will always match the previous instruction's - //post-instruction registers - return; - } + if (instruction.getPredecessorCount() <= 1) { + //in the common case of an instruction that only has a single predecessor which is the previous + //instruction, the pre-instruction registers will always match the previous instruction's + //post-instruction registers + return; + } - for (int registerNum=0; registerNum { * @return a boolean value indicating whether this instruction is a beginning instruction */ public boolean isBeginningInstruction() { + //if this instruction has no predecessors, it is either the fake "StartOfMethod" instruction or it is an + //unreachable instruction. if (predecessors.size() == 0) { return false; } diff --git a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java index d1315738..52762f1a 100644 --- a/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java +++ b/dexlib/src/main/java/org/jf/dexlib/Code/Analysis/MethodAnalyzer.java @@ -110,12 +110,13 @@ public class MethodAnalyzer { return analyzerState == VERIFIED; } - public AnalyzedInstruction[] analyze() { + public void analyze() { assert encodedMethod != null; assert encodedMethod.codeItem != null; if (analyzerState >= ANALYZED) { - return makeInstructionArray(); + //the instructions have already been analyzed, so there is nothing to do + return; } CodeItem codeItem = encodedMethod.codeItem; @@ -273,7 +274,6 @@ public class MethodAnalyzer { } analyzerState = ANALYZED; - return makeInstructionArray(); } private int getThisRegister() { @@ -309,12 +309,11 @@ public class MethodAnalyzer { return startOfMethod; } - public AnalyzedInstruction[] makeInstructionArray() { - AnalyzedInstruction[] instructionArray = new AnalyzedInstruction[instructions.size()]; - for (int i=0; i getInstructions() { + return instructions.getValues(); } public ValidationException getValidationException() { diff --git a/dexlib/src/main/java/org/jf/dexlib/Util/SparseArray.java b/dexlib/src/main/java/org/jf/dexlib/Util/SparseArray.java index f1ae8e97..3c92bc7e 100644 --- a/dexlib/src/main/java/org/jf/dexlib/Util/SparseArray.java +++ b/dexlib/src/main/java/org/jf/dexlib/Util/SparseArray.java @@ -16,6 +16,10 @@ package org.jf.dexlib.Util; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + /** * SparseArrays map integers to Objects. Unlike a normal array of Objects, * there can be gaps in the indices. It is intended to be more efficient @@ -340,6 +344,14 @@ public class SparseArray { return ~high; } + /** + * @return a read-only list of the values in this SparseArray which are in ascending order, based on their + * associated key + */ + public List getValues() { + return Collections.unmodifiableList(Arrays.asList((E[])mValues)); + } + private int[] mKeys; private Object[] mValues; private int mSize;