mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 12:20:11 +02:00
Various changes mostly relating to changing the getInterned* item methods to accept lists instead of arrays
git-svn-id: https://smali.googlecode.com/svn/trunk@412 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
eb21bb1783
commit
7eca83ddb6
@ -201,14 +201,10 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
protected int placeItem(int offset) {
|
||||
if (!dexFile.getInplace()) {
|
||||
ArrayUtils.sortTwoArrays(fieldAnnotationFields, fieldAnnotations);
|
||||
ArrayUtils.sortTwoArrays(methodAnnotationMethods, methodAnnotations);
|
||||
ArrayUtils.sortTwoArrays(parameterAnnotationMethods, parameterAnnotations);
|
||||
}
|
||||
|
||||
return offset + 16 + fieldAnnotations.length * 8 + methodAnnotations.length * 8 +
|
||||
parameterAnnotations.length * 8;
|
||||
return offset + 16 + (
|
||||
(fieldAnnotations==null?0:fieldAnnotations.length) +
|
||||
(methodAnnotations==null?0:methodAnnotations.length) +
|
||||
(parameterAnnotations==null?0:parameterAnnotations.length)) * 8;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@ -261,23 +257,29 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
||||
}
|
||||
|
||||
out.writeInt(classAnnotations==null?0:classAnnotations.getOffset());
|
||||
out.writeInt(fieldAnnotations.length);
|
||||
out.writeInt(methodAnnotations.length);
|
||||
out.writeInt(parameterAnnotations.length);
|
||||
out.writeInt(fieldAnnotations==null?0:fieldAnnotations.length);
|
||||
out.writeInt(methodAnnotations==null?0:methodAnnotations.length);
|
||||
out.writeInt(parameterAnnotations==null?0:parameterAnnotations.length);
|
||||
|
||||
for (int i=0; i<fieldAnnotations.length; i++) {
|
||||
out.writeInt(fieldAnnotationFields[i].getIndex());
|
||||
out.writeInt(fieldAnnotations[i].getOffset());
|
||||
if (fieldAnnotations != null) {
|
||||
for (int i=0; i<fieldAnnotations.length; i++) {
|
||||
out.writeInt(fieldAnnotationFields[i].getIndex());
|
||||
out.writeInt(fieldAnnotations[i].getOffset());
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<methodAnnotations.length; i++) {
|
||||
out.writeInt(methodAnnotationMethods[i].getIndex());
|
||||
out.writeInt(methodAnnotations[i].getOffset());
|
||||
if (methodAnnotations != null) {
|
||||
for (int i=0; i<methodAnnotations.length; i++) {
|
||||
out.writeInt(methodAnnotationMethods[i].getIndex());
|
||||
out.writeInt(methodAnnotations[i].getOffset());
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<parameterAnnotations.length; i++) {
|
||||
out.writeInt(parameterAnnotationMethods[i].getIndex());
|
||||
out.writeInt(parameterAnnotations[i].getOffset());
|
||||
if (parameterAnnotations != null) {
|
||||
for (int i=0; i<parameterAnnotations.length; i++) {
|
||||
out.writeInt(parameterAnnotationMethods[i].getIndex());
|
||||
out.writeInt(parameterAnnotations[i].getOffset());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,9 +363,9 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
||||
*/
|
||||
private boolean isInternable() {
|
||||
return classAnnotations != null &&
|
||||
fieldAnnotations.length == 0 &&
|
||||
methodAnnotations.length == 0 &&
|
||||
parameterAnnotations.length == 0;
|
||||
(fieldAnnotations == null || fieldAnnotations.length == 0) &&
|
||||
(methodAnnotations == null || methodAnnotations.length == 0) &&
|
||||
(parameterAnnotations == null || parameterAnnotations.length == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,6 +31,8 @@ package org.jf.dexlib;
|
||||
import org.jf.dexlib.Util.Input;
|
||||
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AnnotationSetItem extends Item<AnnotationSetItem> {
|
||||
private int hashCode = 0;
|
||||
|
||||
@ -61,8 +63,10 @@ public class AnnotationSetItem extends Item<AnnotationSetItem> {
|
||||
* @param annotations The annotations for this <code>AnnotationSetItem</code>
|
||||
* @return an <code>AnnotationSetItem</code> for the given annotations
|
||||
*/
|
||||
public static AnnotationSetItem getInternedAnnotationSetItem(DexFile dexFile, AnnotationItem[] annotations) {
|
||||
AnnotationSetItem annotationSetItem = new AnnotationSetItem(dexFile, annotations);
|
||||
public static AnnotationSetItem getInternedAnnotationSetItem(DexFile dexFile, List<AnnotationItem> annotations) {
|
||||
AnnotationItem[] annotationsArray = new AnnotationItem[annotations.size()];
|
||||
annotations.toArray(annotationsArray);
|
||||
AnnotationSetItem annotationSetItem = new AnnotationSetItem(dexFile, annotationsArray);
|
||||
return dexFile.AnnotationSetsSection.intern(annotationSetItem);
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,8 @@ package org.jf.dexlib;
|
||||
import org.jf.dexlib.Util.Input;
|
||||
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AnnotationSetRefList extends Item<AnnotationSetRefList> {
|
||||
private int hashCode = 0;
|
||||
|
||||
@ -62,8 +64,10 @@ public class AnnotationSetRefList extends Item<AnnotationSetRefList> {
|
||||
* @return an <code>AnnotationSetItem</code> for the given annotations
|
||||
*/
|
||||
public static AnnotationSetRefList getInternedAnnotationSetRefList(DexFile dexFile,
|
||||
AnnotationSetItem[] annotationSets) {
|
||||
AnnotationSetRefList annotationSetRefList = new AnnotationSetRefList(dexFile, annotationSets);
|
||||
List<AnnotationSetItem> annotationSets) {
|
||||
AnnotationSetItem[] annotationSetsArray = new AnnotationSetItem[annotationSets.size()];
|
||||
annotationSets.toArray(annotationSetsArray);
|
||||
AnnotationSetRefList annotationSetRefList = new AnnotationSetRefList(dexFile, annotationSetsArray);
|
||||
return dexFile.AnnotationSetRefListsSection.intern(annotationSetRefList);
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,8 @@ package org.jf.dexlib;
|
||||
|
||||
import org.jf.dexlib.Util.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
public class ClassDataItem extends Item<ClassDataItem> {
|
||||
private EncodedField[] staticFields;
|
||||
@ -75,18 +75,41 @@ public class ClassDataItem extends Item<ClassDataItem> {
|
||||
* @param virtualMethods The virtual methods for this class
|
||||
* @return a new <code>ClassDataItem</code> with the given values
|
||||
*/
|
||||
public static ClassDataItem getInternedClassDataItem(DexFile dexFile, EncodedField[] staticFields,
|
||||
EncodedField[] instanceFields, EncodedMethod[] directMethods,
|
||||
EncodedMethod[] virtualMethods) {
|
||||
if (!dexFile.getInplace()) {
|
||||
Arrays.sort(staticFields);
|
||||
Arrays.sort(instanceFields);
|
||||
Arrays.sort(directMethods);
|
||||
Arrays.sort(virtualMethods);
|
||||
public static ClassDataItem getInternedClassDataItem(DexFile dexFile, List<EncodedField> staticFields,
|
||||
List<EncodedField> instanceFields,
|
||||
List<EncodedMethod> directMethods,
|
||||
List<EncodedMethod> virtualMethods) {
|
||||
EncodedField[] staticFieldsArray = null;
|
||||
EncodedField[] instanceFieldsArray = null;
|
||||
EncodedMethod[] directMethodsArray = null;
|
||||
EncodedMethod[] virtualMethodsArray = null;
|
||||
|
||||
if (staticFields != null && staticFields.size() > 0) {
|
||||
Collections.sort(staticFields);
|
||||
staticFieldsArray = new EncodedField[staticFields.size()];
|
||||
staticFields.toArray(staticFieldsArray);
|
||||
}
|
||||
|
||||
ClassDataItem classDataItem = new ClassDataItem(dexFile, staticFields, instanceFields, directMethods,
|
||||
virtualMethods);
|
||||
if (instanceFields != null && instanceFields.size() > 0) {
|
||||
Collections.sort(instanceFields);
|
||||
instanceFieldsArray = new EncodedField[instanceFields.size()];
|
||||
instanceFields.toArray(instanceFieldsArray);
|
||||
}
|
||||
|
||||
if (directMethods != null && directMethods.size() > 0) {
|
||||
Collections.sort(directMethods);
|
||||
directMethodsArray = new EncodedMethod[directMethods.size()];
|
||||
directMethods.toArray(directMethodsArray);
|
||||
}
|
||||
|
||||
if (virtualMethods != null && virtualMethods.size() > 0) {
|
||||
Collections.sort(virtualMethods);
|
||||
virtualMethodsArray = new EncodedMethod[virtualMethods.size()];
|
||||
virtualMethods.toArray(virtualMethodsArray);
|
||||
}
|
||||
|
||||
ClassDataItem classDataItem = new ClassDataItem(dexFile, staticFieldsArray, instanceFieldsArray,
|
||||
directMethodsArray, virtualMethodsArray);
|
||||
return dexFile.ClassDataSection.intern(classDataItem);
|
||||
}
|
||||
|
||||
@ -301,7 +324,7 @@ public class ClassDataItem extends Item<ClassDataItem> {
|
||||
return virtualMethods;
|
||||
}
|
||||
|
||||
public static class EncodedField {
|
||||
public static class EncodedField implements Comparable<EncodedField> {
|
||||
/**
|
||||
* The <code>FieldIdItem</code> that this <code>EncodedField</code> is associated with
|
||||
*/
|
||||
@ -390,7 +413,7 @@ public class ClassDataItem extends Item<ClassDataItem> {
|
||||
}
|
||||
}
|
||||
|
||||
public static class EncodedMethod {
|
||||
public static class EncodedMethod implements Comparable<EncodedMethod> {
|
||||
/**
|
||||
* The <code>MethodIdItem</code> that this <code>EncodedMethod</code> is associated with
|
||||
*/
|
||||
|
@ -104,24 +104,22 @@ public class ClassDefItem extends Item<ClassDefItem> {
|
||||
* @param sourceFile The main source file that this class is defined in, or null if not available
|
||||
* @param annotations The annotations for this class and its fields, methods and method parameters, or null if none
|
||||
* @param classData The <code>ClassDataItem</code> containing the method and field definitions for this class
|
||||
* @param staticFieldInitializers The initial values for this class's static fields, or null if none. The initial
|
||||
* values should be in the same order as the fields in the <code>staticFields</code. parameter It can contain
|
||||
* fewer items than static fields, in which case the remaining static fields will be initialized with a default
|
||||
* value of null/0. The initial value for any fields that don't specifically have a value can be either the
|
||||
* type-appropriate null/0 encoded value, or null.
|
||||
* @param staticFields The static fields that correspond to the initial values in
|
||||
* <code>staticFieldInitializers</code>. The static fields are needed in order to sort the initial values correctly
|
||||
* @param staticFieldInitializers The initial values for this class's static fields, or null if none. If it is not
|
||||
* null, it must contain the same number of items as the number of static fields in this class. The value in the
|
||||
* <code>StaticFieldInitializer</code> for any field that doesn't have an explicit initial value can either be null
|
||||
* or be the type-appropriate null/0 value.
|
||||
* @return a <code>ClassDefItem</code> for the given values, and that has been interned into the given
|
||||
* <code>DexFile</code>
|
||||
*/
|
||||
public static ClassDefItem getInternedClassDefItem(DexFile dexFile, TypeIdItem classType, int accessFlags,
|
||||
TypeIdItem superType, TypeListItem implementedInterfaces, StringIdItem sourceFile,
|
||||
AnnotationDirectoryItem annotations, ClassDataItem classData,
|
||||
EncodedValue[] staticFieldInitializers, ClassDataItem.EncodedField[] staticFields) {
|
||||
List<StaticFieldInitializer> staticFieldInitializers) {
|
||||
EncodedArrayItem encodedArrayItem = null;
|
||||
if(!dexFile.getInplace() && staticFieldInitializers != null) {
|
||||
encodedArrayItem = makeStaticFieldInitializersItem(dexFile, staticFieldInitializers,
|
||||
staticFields);
|
||||
if(!dexFile.getInplace() && staticFieldInitializers != null && staticFieldInitializers.size() > 0) {
|
||||
assert classData != null;
|
||||
assert staticFieldInitializers.size() == classData.getStaticFields().length;
|
||||
encodedArrayItem = makeStaticFieldInitializersItem(dexFile, staticFieldInitializers);
|
||||
}
|
||||
|
||||
ClassDefItem classDefItem = new ClassDefItem(dexFile, classType, accessFlags, superType, implementedInterfaces,
|
||||
@ -301,63 +299,51 @@ public class ClassDefItem extends Item<ClassDefItem> {
|
||||
}
|
||||
}
|
||||
|
||||
currentOffset = classDefItem.placeAt(currentIndex++, currentOffset);
|
||||
currentOffset = classDefItem.placeAt(currentOffset, currentIndex++);
|
||||
unplacedClassDefsByType.remove(classDefItem.classType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class StaticFieldInitializer implements Comparable<StaticFieldInitializer> {
|
||||
public final EncodedValue value;
|
||||
public final ClassDataItem.EncodedField field;
|
||||
public StaticFieldInitializer(EncodedValue value, ClassDataItem.EncodedField field) {
|
||||
this.value = value;
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public int compareTo(StaticFieldInitializer other) {
|
||||
return field.compareTo(other.field);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A helper method to sort the static field initializers and populate the default values as needed
|
||||
* @param dexFile the <code>DexFile</code>
|
||||
* @param staticFieldInitializers the initial values
|
||||
* @param fields the fields that correspond to each initial value in <code>staticFieldInitializers</code>
|
||||
* @return an interned EncodedArrayItem containing the static field initializers
|
||||
*/
|
||||
private static EncodedArrayItem makeStaticFieldInitializersItem(DexFile dexFile,
|
||||
EncodedValue[] staticFieldInitializers,
|
||||
ClassDataItem.EncodedField[] fields) {
|
||||
class FieldAndValue {
|
||||
public final EncodedValue value;
|
||||
public final ClassDataItem.EncodedField field;
|
||||
public FieldAndValue(ClassDataItem.EncodedField field, EncodedValue value) {
|
||||
this.field = field;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (staticFieldInitializers == null || staticFieldInitializers.length == 0) {
|
||||
List<StaticFieldInitializer> staticFieldInitializers) {
|
||||
if (staticFieldInitializers == null || staticFieldInitializers.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int len = fields.length;
|
||||
int len = staticFieldInitializers.size();
|
||||
|
||||
FieldAndValue[] fieldAndValues = new FieldAndValue[len];
|
||||
|
||||
for (int i=0; i<len; i++) {
|
||||
EncodedValue encodedValue = null;
|
||||
if (i < staticFieldInitializers.length) {
|
||||
encodedValue = staticFieldInitializers[i];
|
||||
}
|
||||
ClassDataItem.EncodedField encodedField = fields[i];
|
||||
|
||||
fieldAndValues[i] = new FieldAndValue(encodedField, encodedValue);
|
||||
}
|
||||
|
||||
Arrays.sort(fieldAndValues, new Comparator<FieldAndValue>() {
|
||||
public int compare(FieldAndValue a, FieldAndValue b) {
|
||||
return a.field.compareTo(b.field);
|
||||
}
|
||||
});
|
||||
Collections.sort(staticFieldInitializers);
|
||||
|
||||
int lastIndex = -1;
|
||||
for (int i=0; i<len; i++) {
|
||||
FieldAndValue fav = fieldAndValues[i];
|
||||
for (int i=len-1; i>=0; i--) {
|
||||
StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i);
|
||||
|
||||
if (fav.value != null &&
|
||||
(fav.value.compareTo(TypeUtils.makeDefaultValueForType(dexFile,
|
||||
fav.field.field.getFieldType().getTypeDescriptor())) != 0)) {
|
||||
if (staticFieldInitializer.value != null &&
|
||||
(staticFieldInitializer.value.compareTo(TypeUtils.makeDefaultValueForType(dexFile,
|
||||
staticFieldInitializer.field.field.getFieldType().getTypeDescriptor())) != 0)) {
|
||||
lastIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,11 +355,11 @@ public class ClassDefItem extends Item<ClassDefItem> {
|
||||
EncodedValue[] values = new EncodedValue[lastIndex+1];
|
||||
|
||||
for (int i=0; i<=lastIndex; i++) {
|
||||
FieldAndValue fav = fieldAndValues[i];
|
||||
EncodedValue encodedValue = fav.value;
|
||||
StaticFieldInitializer staticFieldInitializer = staticFieldInitializers.get(i);
|
||||
EncodedValue encodedValue = staticFieldInitializer.value;
|
||||
if (encodedValue == null) {
|
||||
encodedValue = TypeUtils.makeDefaultValueForType(dexFile,
|
||||
fav.field.field.getFieldType().getTypeDescriptor());
|
||||
staticFieldInitializer.field.field.getFieldType().getTypeDescriptor());
|
||||
}
|
||||
|
||||
values[i] = encodedValue;
|
||||
|
@ -37,6 +37,8 @@ import org.jf.dexlib.Util.Input;
|
||||
import org.jf.dexlib.Util.SparseArray;
|
||||
import org.jf.dexlib.Util.Leb128Utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CodeItem extends Item<CodeItem> {
|
||||
private int registerCount;
|
||||
private int inWords;
|
||||
@ -101,9 +103,10 @@ public class CodeItem extends Item<CodeItem> {
|
||||
* @param outWords the maximum number of 2-byte words for the arguments of any method call in this code
|
||||
* @param debugInfo the debug information for this code/method
|
||||
* @param encodedInstructions the instructions, encoded as a byte array
|
||||
* @param referencedItems an array of the items referenced by instructions, in order of occurance in the code
|
||||
* @param tries an array of the tries defined for this code/method
|
||||
* @param encodedCatchHandlers an array of the exception handlers defined for this code/method
|
||||
* @param referencedItems a list of the items referenced by instructions, in order of occurance in the code,
|
||||
* or null if none
|
||||
* @param tries a list of the tries defined for this code/method or null if none
|
||||
* @param encodedCatchHandlers a list of the exception handlers defined for this code/method or null if none
|
||||
* @return a new <code>CodeItem</code> with the given values.
|
||||
*/
|
||||
public static CodeItem getInternedCodeItem(DexFile dexFile,
|
||||
@ -112,11 +115,30 @@ public class CodeItem extends Item<CodeItem> {
|
||||
int outWords,
|
||||
DebugInfoItem debugInfo,
|
||||
byte[] encodedInstructions,
|
||||
Item[] referencedItems,
|
||||
TryItem[] tries,
|
||||
EncodedCatchHandler[] encodedCatchHandlers) {
|
||||
List<Item> referencedItems,
|
||||
List<TryItem> tries,
|
||||
List<EncodedCatchHandler> encodedCatchHandlers) {
|
||||
Item[] referencedItemsArray = null;
|
||||
TryItem[] triesArray = null;
|
||||
EncodedCatchHandler[] encodedCatchHandlersArray = null;
|
||||
|
||||
if (referencedItems != null && referencedItems.size() > 0) {
|
||||
referencedItemsArray = new Item[referencedItems.size()];
|
||||
referencedItems.toArray(referencedItemsArray);
|
||||
}
|
||||
|
||||
if (tries != null && tries.size() > 0) {
|
||||
triesArray = new TryItem[tries.size()];
|
||||
tries.toArray(triesArray);
|
||||
}
|
||||
|
||||
if (encodedCatchHandlers != null && encodedCatchHandlers.size() > 0) {
|
||||
encodedCatchHandlersArray = new EncodedCatchHandler[encodedCatchHandlers.size()];
|
||||
encodedCatchHandlers.toArray(encodedCatchHandlersArray);
|
||||
}
|
||||
|
||||
CodeItem codeItem = new CodeItem(dexFile, registerCount, inWords, outWords, debugInfo, encodedInstructions,
|
||||
referencedItems, tries, encodedCatchHandlers);
|
||||
referencedItemsArray, triesArray, encodedCatchHandlersArray);
|
||||
return dexFile.CodeItemsSection.intern(codeItem);
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,10 @@ public class TypeListItem extends Item<TypeListItem> {
|
||||
* @return a <code>TypeListItem</code> for the given values, and that has been interned into
|
||||
* the given <code>DexFile</code>
|
||||
*/
|
||||
public static TypeListItem getInternedTypeListItem(DexFile dexFile, TypeIdItem[] typeList) {
|
||||
TypeListItem typeListItem = new TypeListItem(dexFile, typeList);
|
||||
public static TypeListItem getInternedTypeListItem(DexFile dexFile, List<TypeIdItem> typeList) {
|
||||
TypeIdItem[] typeArray = new TypeIdItem[typeList.size()];
|
||||
typeList.toArray(typeArray);
|
||||
TypeListItem typeListItem = new TypeListItem(dexFile, typeArray);
|
||||
return dexFile.TypeListsSection.intern(typeListItem);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user