diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java index e04f0bfc..55759419 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java @@ -31,12 +31,8 @@ package org.jf.dexlib2.analysis; -import com.google.common.base.Predicate; import com.google.common.base.Predicates; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; +import com.google.common.collect.*; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.analysis.util.TypeProtoUtils; import org.jf.dexlib2.iface.ClassDef; @@ -44,13 +40,15 @@ import org.jf.dexlib2.iface.Field; import org.jf.dexlib2.iface.Method; import org.jf.dexlib2.iface.reference.FieldReference; import org.jf.dexlib2.iface.reference.MethodReference; -import org.jf.dexlib2.util.FieldUtil; import org.jf.util.ExceptionWithContext; import org.jf.util.SparseArray; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; /** * A class "prototype". This contains things like the interfaces, the superclass, the vtable and the instance fields @@ -342,20 +340,19 @@ public class ClassProto implements TypeProto { final byte WIDE = 1; final byte OTHER = 2; - ArrayList loadedFields = getInstanceFields(getClassDef()); - Field[] fields = new Field[loadedFields.size()]; + ArrayList fields = getSortedInstanceFields(getClassDef()); + final int fieldCount = fields.size(); //the "type" for each field in fields. 0=reference,1=wide,2=other - byte[] fieldTypes = new byte[fields.length]; - for (int i=0;i front) { if (fieldTypes[back] == REFERENCE) { @@ -392,10 +389,10 @@ public class ClassProto implements TypeProto { //8-byte aligned. If we're on an odd field index, we need to insert a 32-bit field. If the next field //is already a 32-bit field, use that. Otherwise, find the first 32-bit field from the end and swap it in. //If there are no 32-bit fields, do nothing for now. We'll add padding when calculating the field offsets - if (front < fields.length && (front % 2) != fieldIndexMod) { + if (front < fieldCount && (front % 2) != fieldIndexMod) { if (fieldTypes[front] == WIDE) { //we need to swap in a 32-bit field, so the wide fields will be correctly aligned - back = fields.length - 1; + back = fieldCount - 1; while (back > front) { if (fieldTypes[back] == OTHER) { swap(fieldTypes, fields, front++, back); @@ -410,8 +407,8 @@ public class ClassProto implements TypeProto { } //do the swap thing for wide fields - back = fields.length - 1; - for (; front front) { if (fieldTypes[back] == WIDE) { @@ -433,7 +430,7 @@ public class ClassProto implements TypeProto { } //now the fields are in the correct order. Add them to the SparseArray and lookup, and calculate the offsets - int totalFieldCount = superFieldCount + fields.length; + int totalFieldCount = superFieldCount + fieldCount; SparseArray instanceFields = new SparseArray(totalFieldCount); int fieldOffset; @@ -458,8 +455,8 @@ public class ClassProto implements TypeProto { } boolean gotDouble = false; - for (int i=0; i getInstanceFields(@Nonnull ClassDef classDef) { - ArrayList instanceFields = Lists.newArrayList(); - for (Field field: classDef.getInstanceFields()) { - instanceFields.add(field); - } - return instanceFields; + private static ArrayList getSortedInstanceFields(@Nonnull ClassDef classDef) { + ArrayList fields = Lists.newArrayList(classDef.getInstanceFields()); + Collections.sort(fields); + return fields; } - private byte getFieldType(String fieldType) { - switch (fieldType.charAt(0)) { + private byte getFieldType(@Nonnull FieldReference field) { + switch (field.getType().charAt(0)) { case '[': case 'L': return 0; //REFERENCE @@ -505,14 +500,13 @@ public class ClassProto implements TypeProto { } } - private void swap(byte[] fieldTypes, FieldReference[] fields, int position1, int position2) { + private void swap(byte[] fieldTypes, List fields, int position1, int position2) { byte tempType = fieldTypes[position1]; fieldTypes[position1] = fieldTypes[position2]; fieldTypes[position2] = tempType; - FieldReference tempField = fields[position1]; - fields[position1] = fields[position2]; - fields[position2] = tempField; + Field tempField = fields.set(position1, fields.get(position2)); + fields.set(position2, tempField); } private int getNextFieldOffset() {