Update to smali 2.0.2

This commit is contained in:
Connor Tumbleson 2013-11-15 12:14:35 -06:00
parent 8d0801e6db
commit f89b51c74e
18 changed files with 126 additions and 88 deletions

View File

@ -31,7 +31,7 @@
apply plugin: 'idea' apply plugin: 'idea'
version = '2.0' version = '2.0.2'
def jarVersion = version def jarVersion = version

View File

@ -32,19 +32,29 @@
package org.jf.dexlib2.builder; package org.jf.dexlib2.builder;
import org.jf.dexlib2.base.BaseExceptionHandler; import org.jf.dexlib2.base.BaseExceptionHandler;
import org.jf.dexlib2.iface.ExceptionHandler;
import org.jf.dexlib2.iface.reference.TypeReference; import org.jf.dexlib2.iface.reference.TypeReference;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
class BuilderExceptionHandler { public abstract class BuilderExceptionHandler extends BaseExceptionHandler {
static ExceptionHandler newExceptionHandler(@Nullable final TypeReference exceptionType, @Nonnull protected final Label handler;
@Nonnull final Label handler) {
private BuilderExceptionHandler(@Nonnull Label handler) {
this.handler = handler;
}
@Nonnull
public Label getHandler() {
return handler;
}
static BuilderExceptionHandler newExceptionHandler(@Nullable final TypeReference exceptionType,
@Nonnull Label handler) {
if (exceptionType == null) { if (exceptionType == null) {
return newExceptionHandler(handler); return newExceptionHandler(handler);
} }
return new BaseExceptionHandler() { return new BuilderExceptionHandler(handler) {
@Nullable @Override public String getExceptionType() { @Nullable @Override public String getExceptionType() {
return exceptionType.getType(); return exceptionType.getType();
} }
@ -59,8 +69,8 @@ class BuilderExceptionHandler {
}; };
} }
static ExceptionHandler newExceptionHandler(@Nonnull final Label handler) { static BuilderExceptionHandler newExceptionHandler(@Nonnull Label handler) {
return new BaseExceptionHandler() { return new BuilderExceptionHandler(handler) {
@Nullable @Override public String getExceptionType() { @Nullable @Override public String getExceptionType() {
return null; return null;
} }
@ -71,12 +81,12 @@ class BuilderExceptionHandler {
}; };
} }
static ExceptionHandler newExceptionHandler(@Nullable final String exceptionType, static BuilderExceptionHandler newExceptionHandler(@Nullable final String exceptionType,
@Nonnull final Label handler) { @Nonnull Label handler) {
if (exceptionType == null) { if (exceptionType == null) {
return newExceptionHandler(handler); return newExceptionHandler(handler);
} }
return new BaseExceptionHandler() { return new BuilderExceptionHandler(handler) {
@Nullable @Override public String getExceptionType() { @Nullable @Override public String getExceptionType() {
return exceptionType; return exceptionType;
} }

View File

@ -32,10 +32,12 @@
package org.jf.dexlib2.builder; package org.jf.dexlib2.builder;
import org.jf.dexlib2.Opcode; import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.builder.instruction.BuilderSwitchElement;
import org.jf.dexlib2.iface.instruction.SwitchPayload; import org.jf.dexlib2.iface.instruction.SwitchPayload;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List;
public abstract class BuilderSwitchPayload extends BuilderInstruction implements SwitchPayload { public abstract class BuilderSwitchPayload extends BuilderInstruction implements SwitchPayload {
@Nullable @Nullable
@ -52,4 +54,6 @@ public abstract class BuilderSwitchPayload extends BuilderInstruction implements
} }
return referrer; return referrer;
} }
@Nonnull @Override public abstract List<? extends BuilderSwitchElement> getSwitchElements();
} }

View File

@ -33,16 +33,15 @@ package org.jf.dexlib2.builder;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.jf.dexlib2.base.BaseTryBlock; import org.jf.dexlib2.base.BaseTryBlock;
import org.jf.dexlib2.iface.ExceptionHandler;
import org.jf.dexlib2.iface.reference.TypeReference; import org.jf.dexlib2.iface.reference.TypeReference;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List; import java.util.List;
class BuilderTryBlock extends BaseTryBlock<ExceptionHandler> { public class BuilderTryBlock extends BaseTryBlock<BuilderExceptionHandler> {
// We only ever have one exception handler per try block. They are later merged as needed in TryListBuilder // We only ever have one exception handler per try block. They are later merged as needed in TryListBuilder
@Nonnull public final ExceptionHandler exceptionHandler; @Nonnull public final BuilderExceptionHandler exceptionHandler;
@Nonnull public final Label start; @Nonnull public final Label start;
// The end location is exclusive, it should point to the codeAddress of the instruction immediately after the last // The end location is exclusive, it should point to the codeAddress of the instruction immediately after the last
// covered instruction. // covered instruction.
@ -76,7 +75,7 @@ class BuilderTryBlock extends BaseTryBlock<ExceptionHandler> {
return end.getCodeAddress() - start.getCodeAddress(); return end.getCodeAddress() - start.getCodeAddress();
} }
@Nonnull @Override public List<? extends ExceptionHandler> getExceptionHandlers() { @Nonnull @Override public List<? extends BuilderExceptionHandler> getExceptionHandlers() {
return ImmutableList.of(exceptionHandler); return ImmutableList.of(exceptionHandler);
} }
} }

View File

@ -34,7 +34,6 @@ package org.jf.dexlib2.builder;
import org.jf.dexlib2.iface.MethodImplementation; import org.jf.dexlib2.iface.MethodImplementation;
import org.jf.dexlib2.iface.reference.StringReference; import org.jf.dexlib2.iface.reference.StringReference;
import org.jf.dexlib2.iface.reference.TypeReference; import org.jf.dexlib2.iface.reference.TypeReference;
import org.jf.dexlib2.writer.builder.BuilderStringReference;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -143,7 +142,7 @@ public class MethodImplementationBuilder {
currentLocation.addEpilogue(); currentLocation.addEpilogue();
} }
public void addSetSourceFile(@Nullable BuilderStringReference sourceFile) { public void addSetSourceFile(@Nullable StringReference sourceFile) {
currentLocation.addSetSourceFile(sourceFile); currentLocation.addSetSourceFile(sourceFile);
} }

View File

@ -36,7 +36,6 @@ import org.jf.dexlib2.builder.debug.*;
import org.jf.dexlib2.iface.instruction.Instruction; import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.reference.StringReference; import org.jf.dexlib2.iface.reference.StringReference;
import org.jf.dexlib2.iface.reference.TypeReference; import org.jf.dexlib2.iface.reference.TypeReference;
import org.jf.dexlib2.writer.builder.BuilderStringReference;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -207,7 +206,7 @@ public class MethodLocation {
getDebugItems().add(new BuilderEpilogueBegin()); getDebugItems().add(new BuilderEpilogueBegin());
} }
public void addSetSourceFile(@Nullable BuilderStringReference sourceFile) { public void addSetSourceFile(@Nullable StringReference sourceFile) {
getDebugItems().add(new BuilderSetSourceFile(sourceFile)); getDebugItems().add(new BuilderSetSourceFile(sourceFile));
} }
} }

View File

@ -136,13 +136,13 @@ public class MutableMethodImplementation implements MethodImplementation {
} }
@Nonnull @Nonnull
public List<Instruction> getInstructions() { public List<BuilderInstruction> getInstructions() {
if (fixInstructions) { if (fixInstructions) {
fixInstructions(); fixInstructions();
} }
return new AbstractList<Instruction>() { return new AbstractList<BuilderInstruction>() {
@Override public Instruction get(int i) { @Override public BuilderInstruction get(int i) {
if (i >= size()) { if (i >= size()) {
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
} }
@ -162,7 +162,7 @@ public class MutableMethodImplementation implements MethodImplementation {
}; };
} }
@Nonnull @Override public List<? extends TryBlock<? extends ExceptionHandler>> getTryBlocks() { @Nonnull @Override public List<BuilderTryBlock> getTryBlocks() {
if (fixInstructions) { if (fixInstructions) {
fixInstructions(); fixInstructions();
} }
@ -483,9 +483,11 @@ public class MutableMethodImplementation implements MethodImplementation {
} }
@Nonnull @Nonnull
public Label newSwitchPayloadReferenceLabel(@Nonnull int[] codeAddressToIndex, int codeAddress) { public Label newSwitchPayloadReferenceLabel(@Nonnull MethodLocation switchLocation,
@Nonnull int[] codeAddressToIndex, int codeAddress) {
MethodLocation referent = instructionList.get(mapCodeAddressToIndex(codeAddressToIndex, codeAddress)); MethodLocation referent = instructionList.get(mapCodeAddressToIndex(codeAddressToIndex, codeAddress));
Label label = new SwitchPayloadReferenceLabel(); SwitchPayloadReferenceLabel label = new SwitchPayloadReferenceLabel();
label.switchLocation = switchLocation;
referent.getLabels().add(label); referent.getLabels().add(label);
return label; return label;
} }
@ -528,7 +530,7 @@ public class MutableMethodImplementation implements MethodImplementation {
setInstruction(location, newBuilderInstruction21ih((Instruction21ih)instruction)); setInstruction(location, newBuilderInstruction21ih((Instruction21ih)instruction));
return; return;
case Format21lh: case Format21lh:
setInstruction(location, newBuilderInstruction10x((Instruction10x)instruction)); setInstruction(location, newBuilderInstruction21lh((Instruction21lh)instruction));
return; return;
case Format21s: case Format21s:
setInstruction(location, newBuilderInstruction21s((Instruction21s)instruction)); setInstruction(location, newBuilderInstruction21s((Instruction21s)instruction));
@ -567,7 +569,7 @@ public class MutableMethodImplementation implements MethodImplementation {
setInstruction(location, newBuilderInstruction31i((Instruction31i)instruction)); setInstruction(location, newBuilderInstruction31i((Instruction31i)instruction));
return; return;
case Format31t: case Format31t:
setInstruction(location, newBuilderInstruction31t(location.codeAddress, codeAddressToIndex, setInstruction(location, newBuilderInstruction31t(location, codeAddressToIndex,
(Instruction31t)instruction)); (Instruction31t)instruction));
return; return;
case Format32x: case Format32x:
@ -589,8 +591,10 @@ public class MutableMethodImplementation implements MethodImplementation {
case SparseSwitchPayload: case SparseSwitchPayload:
setInstruction(location, setInstruction(location,
newBuilderSparseSwitchPayload(location, codeAddressToIndex, (SparseSwitchPayload)instruction)); newBuilderSparseSwitchPayload(location, codeAddressToIndex, (SparseSwitchPayload)instruction));
return;
case ArrayPayload: case ArrayPayload:
setInstruction(location, newBuilderArrayPayload((ArrayPayload)instruction)); setInstruction(location, newBuilderArrayPayload((ArrayPayload)instruction));
return;
default: default:
throw new ExceptionWithContext("Instruction format %s not supported", instruction.getOpcode().format); throw new ExceptionWithContext("Instruction format %s not supported", instruction.getOpcode().format);
} }
@ -662,7 +666,7 @@ public class MutableMethodImplementation implements MethodImplementation {
return new BuilderInstruction21ih( return new BuilderInstruction21ih(
instruction.getOpcode(), instruction.getOpcode(),
instruction.getRegisterA(), instruction.getRegisterA(),
instruction.getHatLiteral()); instruction.getNarrowLiteral());
} }
@Nonnull @Nonnull
@ -670,7 +674,7 @@ public class MutableMethodImplementation implements MethodImplementation {
return new BuilderInstruction21lh( return new BuilderInstruction21lh(
instruction.getOpcode(), instruction.getOpcode(),
instruction.getRegisterA(), instruction.getRegisterA(),
instruction.getHatLiteral()); instruction.getWideLiteral());
} }
@Nonnull @Nonnull
@ -769,12 +773,13 @@ public class MutableMethodImplementation implements MethodImplementation {
} }
@Nonnull @Nonnull
private BuilderInstruction31t newBuilderInstruction31t(int codeAddress, int[] codeAddressToIndex, private BuilderInstruction31t newBuilderInstruction31t(@Nonnull MethodLocation location , int[] codeAddressToIndex,
@Nonnull Instruction31t instruction) { @Nonnull Instruction31t instruction) {
int codeAddress = location.getCodeAddress();
Label newLabel; Label newLabel;
if (instruction.getOpcode() != Opcode.FILL_ARRAY_DATA) { if (instruction.getOpcode() != Opcode.FILL_ARRAY_DATA) {
// if it's a sparse switch or packed switch // if it's a sparse switch or packed switch
newLabel = newSwitchPayloadReferenceLabel(codeAddressToIndex, codeAddress + instruction.getCodeOffset()); newLabel = newSwitchPayloadReferenceLabel(location, codeAddressToIndex, codeAddress + instruction.getCodeOffset());
} else { } else {
newLabel = newLabel(codeAddressToIndex, codeAddress + instruction.getCodeOffset()); newLabel = newLabel(codeAddressToIndex, codeAddress + instruction.getCodeOffset());
} }
@ -871,7 +876,7 @@ public class MutableMethodImplementation implements MethodImplementation {
List<Label> labels = Lists.newArrayList(); List<Label> labels = Lists.newArrayList();
for (SwitchElement element: switchElements) { for (SwitchElement element: switchElements) {
labels.add(newLabel(codeAddressToIndex, element.getOffset() - baseAddress)); labels.add(newLabel(codeAddressToIndex, element.getOffset() + baseAddress));
} }
return new BuilderPackedSwitchPayload(switchElements.get(0).getKey(), labels); return new BuilderPackedSwitchPayload(switchElements.get(0).getKey(), labels);
@ -897,7 +902,7 @@ public class MutableMethodImplementation implements MethodImplementation {
List<SwitchLabelElement> labelElements = Lists.newArrayList(); List<SwitchLabelElement> labelElements = Lists.newArrayList();
for (SwitchElement element: switchElements) { for (SwitchElement element: switchElements) {
labelElements.add(new SwitchLabelElement(element.getKey(), labelElements.add(new SwitchLabelElement(element.getKey(),
newLabel(codeAddressToIndex, element.getOffset() - baseAddress))); newLabel(codeAddressToIndex, element.getOffset() + baseAddress)));
} }
return new BuilderSparseSwitchPayload(labelElements); return new BuilderSparseSwitchPayload(labelElements);

View File

@ -31,15 +31,12 @@
package org.jf.dexlib2.builder.instruction; package org.jf.dexlib2.builder.instruction;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.jf.dexlib2.Format; import org.jf.dexlib2.Format;
import org.jf.dexlib2.Opcode; import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.builder.BuilderSwitchPayload; import org.jf.dexlib2.builder.BuilderSwitchPayload;
import org.jf.dexlib2.builder.Label; import org.jf.dexlib2.builder.Label;
import org.jf.dexlib2.builder.MethodLocation;
import org.jf.dexlib2.iface.instruction.SwitchElement;
import org.jf.dexlib2.iface.instruction.formats.PackedSwitchPayload; import org.jf.dexlib2.iface.instruction.formats.PackedSwitchPayload;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -49,7 +46,7 @@ import java.util.List;
public class BuilderPackedSwitchPayload extends BuilderSwitchPayload implements PackedSwitchPayload { public class BuilderPackedSwitchPayload extends BuilderSwitchPayload implements PackedSwitchPayload {
public static final Opcode OPCODE = Opcode.PACKED_SWITCH_PAYLOAD; public static final Opcode OPCODE = Opcode.PACKED_SWITCH_PAYLOAD;
@Nonnull protected final List<? extends BuilderSwitchElement> switchElements; @Nonnull protected final List<BuilderSwitchElement> switchElements;
public BuilderPackedSwitchPayload(final int startKey, public BuilderPackedSwitchPayload(final int startKey,
@Nullable List<? extends Label> switchElements) { @Nullable List<? extends Label> switchElements) {
@ -57,17 +54,15 @@ public class BuilderPackedSwitchPayload extends BuilderSwitchPayload implements
if (switchElements == null) { if (switchElements == null) {
this.switchElements = ImmutableList.of(); this.switchElements = ImmutableList.of();
} else { } else {
this.switchElements = Lists.transform(switchElements, new Function<Label, BuilderSwitchElement>() { this.switchElements = Lists.newArrayList();
int key = startKey; int key = startKey;
@Nullable @Override public BuilderSwitchElement apply(@Nullable Label target) { for (Label target: switchElements) {
assert target != null; this.switchElements.add(new BuilderSwitchElement(this, key++, target));
return new BuilderSwitchElement(BuilderPackedSwitchPayload.this, key++, target); }
}
});
} }
} }
@Nonnull @Override public List<? extends SwitchElement> getSwitchElements() { return switchElements; } @Nonnull @Override public List<BuilderSwitchElement> getSwitchElements() { return switchElements; }
@Override public int getCodeUnits() { return 4 + switchElements.size() * 2; } @Override public int getCodeUnits() { return 4 + switchElements.size() * 2; }
@Override public Format getFormat() { return OPCODE.format; } @Override public Format getFormat() { return OPCODE.format; }

View File

@ -38,7 +38,6 @@ import org.jf.dexlib2.Format;
import org.jf.dexlib2.Opcode; import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.builder.BuilderSwitchPayload; import org.jf.dexlib2.builder.BuilderSwitchPayload;
import org.jf.dexlib2.builder.SwitchLabelElement; import org.jf.dexlib2.builder.SwitchLabelElement;
import org.jf.dexlib2.iface.instruction.SwitchElement;
import org.jf.dexlib2.iface.instruction.formats.SparseSwitchPayload; import org.jf.dexlib2.iface.instruction.formats.SparseSwitchPayload;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -48,7 +47,7 @@ import java.util.List;
public class BuilderSparseSwitchPayload extends BuilderSwitchPayload implements SparseSwitchPayload { public class BuilderSparseSwitchPayload extends BuilderSwitchPayload implements SparseSwitchPayload {
public static final Opcode OPCODE = Opcode.SPARSE_SWITCH_PAYLOAD; public static final Opcode OPCODE = Opcode.SPARSE_SWITCH_PAYLOAD;
@Nonnull protected final List<? extends BuilderSwitchElement> switchElements; @Nonnull protected final List<BuilderSwitchElement> switchElements;
public BuilderSparseSwitchPayload(@Nullable List<? extends SwitchLabelElement> switchElements) { public BuilderSparseSwitchPayload(@Nullable List<? extends SwitchLabelElement> switchElements) {
super(OPCODE); super(OPCODE);
@ -64,7 +63,7 @@ public class BuilderSparseSwitchPayload extends BuilderSwitchPayload implements
} }
} }
@Nonnull @Override public List<? extends SwitchElement> getSwitchElements() { return switchElements; } @Nonnull @Override public List<BuilderSwitchElement> getSwitchElements() { return switchElements; }
@Override public int getCodeUnits() { return 2 + switchElements.size() * 4; } @Override public int getCodeUnits() { return 2 + switchElements.size() * 4; }
@Override public Format getFormat() { return OPCODE.format; } @Override public Format getFormat() { return OPCODE.format; }

View File

@ -26,4 +26,9 @@ public class BuilderSwitchElement implements SwitchElement {
@Override public int getOffset() { @Override public int getOffset() {
return target.getCodeAddress() - parent.getReferrer().getCodeAddress(); return target.getCodeAddress() - parent.getReferrer().getCodeAddress();
} }
@Nonnull
public Label getTarget() {
return target;
}
} }

View File

@ -152,16 +152,16 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
final int staticInitialValuesOffset = final int staticInitialValuesOffset =
dexFile.readSmallUint(classDefOffset + ClassDefItem.STATIC_VALUES_OFFSET); dexFile.readSmallUint(classDefOffset + ClassDefItem.STATIC_VALUES_OFFSET);
final int fieldsStartOffset = reader.getOffset(); final int fieldsStartOffset = reader.getOffset();
final AnnotationsDirectory.AnnotationIterator annotationIterator =
annotationsDirectory.getFieldAnnotationIterator();
final StaticInitialValueIterator staticInitialValueIterator =
StaticInitialValueIterator.newOrEmpty(dexFile, staticInitialValuesOffset);
return new Iterable<DexBackedField>() { return new Iterable<DexBackedField>() {
@Nonnull @Nonnull
@Override @Override
public Iterator<DexBackedField> iterator() { public Iterator<DexBackedField> iterator() {
final AnnotationsDirectory.AnnotationIterator annotationIterator =
annotationsDirectory.getFieldAnnotationIterator();
final StaticInitialValueIterator staticInitialValueIterator =
StaticInitialValueIterator.newOrEmpty(dexFile, staticInitialValuesOffset);
return new VariableSizeLookaheadIterator<DexBackedField>(dexFile, fieldsStartOffset) { return new VariableSizeLookaheadIterator<DexBackedField>(dexFile, fieldsStartOffset) {
private int count; private int count;
@Nullable private FieldReference previousField; @Nullable private FieldReference previousField;
@ -212,14 +212,15 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
DexReader reader = dexFile.readerAt(getInstanceFieldsOffset()); DexReader reader = dexFile.readerAt(getInstanceFieldsOffset());
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory(); final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
final AnnotationsDirectory.AnnotationIterator annotationIterator =
annotationsDirectory.getFieldAnnotationIterator();
final int fieldsStartOffset = reader.getOffset(); final int fieldsStartOffset = reader.getOffset();
return new Iterable<DexBackedField>() { return new Iterable<DexBackedField>() {
@Nonnull @Nonnull
@Override @Override
public Iterator<DexBackedField> iterator() { public Iterator<DexBackedField> iterator() {
final AnnotationsDirectory.AnnotationIterator annotationIterator =
annotationsDirectory.getFieldAnnotationIterator();
return new VariableSizeLookaheadIterator<DexBackedField>(dexFile, fieldsStartOffset) { return new VariableSizeLookaheadIterator<DexBackedField>(dexFile, fieldsStartOffset) {
private int count; private int count;
@Nullable private FieldReference previousField; @Nullable private FieldReference previousField;
@ -278,16 +279,17 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
DexReader reader = dexFile.readerAt(getDirectMethodsOffset()); DexReader reader = dexFile.readerAt(getDirectMethodsOffset());
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory(); final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
final AnnotationsDirectory.AnnotationIterator methodAnnotationIterator =
annotationsDirectory.getMethodAnnotationIterator();
final AnnotationsDirectory.AnnotationIterator parameterAnnotationIterator =
annotationsDirectory.getParameterAnnotationIterator();
final int methodsStartOffset = reader.getOffset(); final int methodsStartOffset = reader.getOffset();
return new Iterable<DexBackedMethod>() { return new Iterable<DexBackedMethod>() {
@Nonnull @Nonnull
@Override @Override
public Iterator<DexBackedMethod> iterator() { public Iterator<DexBackedMethod> iterator() {
final AnnotationsDirectory.AnnotationIterator methodAnnotationIterator =
annotationsDirectory.getMethodAnnotationIterator();
final AnnotationsDirectory.AnnotationIterator parameterAnnotationIterator =
annotationsDirectory.getParameterAnnotationIterator();
return new VariableSizeLookaheadIterator<DexBackedMethod>(dexFile, methodsStartOffset) { return new VariableSizeLookaheadIterator<DexBackedMethod>(dexFile, methodsStartOffset) {
private int count; private int count;
@Nullable private MethodReference previousMethod; @Nullable private MethodReference previousMethod;
@ -334,13 +336,14 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
DexReader reader = dexFile.readerAt(getVirtualMethodsOffset()); DexReader reader = dexFile.readerAt(getVirtualMethodsOffset());
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory(); final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
final AnnotationsDirectory.AnnotationIterator methodAnnotationIterator =
annotationsDirectory.getMethodAnnotationIterator();
final AnnotationsDirectory.AnnotationIterator parameterAnnotationIterator =
annotationsDirectory.getParameterAnnotationIterator();
final int methodsStartOffset = reader.getOffset(); final int methodsStartOffset = reader.getOffset();
return new Iterable<DexBackedMethod>() { return new Iterable<DexBackedMethod>() {
final AnnotationsDirectory.AnnotationIterator methodAnnotationIterator =
annotationsDirectory.getMethodAnnotationIterator();
final AnnotationsDirectory.AnnotationIterator parameterAnnotationIterator =
annotationsDirectory.getParameterAnnotationIterator();
@Nonnull @Nonnull
@Override @Override
public Iterator<DexBackedMethod> iterator() { public Iterator<DexBackedMethod> iterator() {

View File

@ -51,9 +51,15 @@ public class HeaderItem {
public static final int CHECKSUM_OFFSET = 8; public static final int CHECKSUM_OFFSET = 8;
// this is the start of the checksumed data
public static final int CHECKSUM_DATA_START_OFFSET = 12;
public static final int SIGNATURE_OFFSET = 12; public static final int SIGNATURE_OFFSET = 12;
public static final int SIGNATURE_SIZE = 20; public static final int SIGNATURE_SIZE = 20;
// this is the start of the sha-1 hashed data
public static final int SIGNATURE_DATA_START_OFFSET = 32;
public static final int FILE_SIZE_OFFSET = 32;
public static final int HEADER_SIZE_OFFSET = 36; public static final int HEADER_SIZE_OFFSET = 36;
public static final int ENDIAN_TAG_OFFSET = 40; public static final int ENDIAN_TAG_OFFSET = 40;

View File

@ -67,8 +67,8 @@ public class ImmutableStartLocal extends ImmutableDebugItem implements StartLoca
return new ImmutableStartLocal( return new ImmutableStartLocal(
startLocal.getCodeAddress(), startLocal.getCodeAddress(),
startLocal.getRegister(), startLocal.getRegister(),
startLocal.getType(),
startLocal.getName(), startLocal.getName(),
startLocal.getType(),
startLocal.getSignature()); startLocal.getSignature());
} }

View File

@ -236,7 +236,7 @@ public abstract class DexWriter<
} }
byte[] buffer = new byte[4 * 1024]; byte[] buffer = new byte[4 * 1024];
InputStream input = dataStore.readAt(HeaderItem.HEADER_SIZE_OFFSET); InputStream input = dataStore.readAt(HeaderItem.SIGNATURE_DATA_START_OFFSET);
int bytesRead = input.read(buffer); int bytesRead = input.read(buffer);
while (bytesRead >= 0) { while (bytesRead >= 0) {
md.update(buffer, 0, bytesRead); md.update(buffer, 0, bytesRead);
@ -258,7 +258,7 @@ public abstract class DexWriter<
Adler32 a32 = new Adler32(); Adler32 a32 = new Adler32();
byte[] buffer = new byte[4 * 1024]; byte[] buffer = new byte[4 * 1024];
InputStream input = dataStore.readAt(HeaderItem.SIGNATURE_OFFSET); InputStream input = dataStore.readAt(HeaderItem.CHECKSUM_DATA_START_OFFSET);
int bytesRead = input.read(buffer); int bytesRead = input.read(buffer);
while (bytesRead >= 0) { while (bytesRead >= 0) {
a32.update(buffer, 0, bytesRead); a32.update(buffer, 0, bytesRead);
@ -777,7 +777,7 @@ public abstract class DexWriter<
} }
private void fixInstructions(@Nonnull MutableMethodImplementation methodImplementation) { private void fixInstructions(@Nonnull MutableMethodImplementation methodImplementation) {
List<Instruction> instructions = methodImplementation.getInstructions(); List<? extends Instruction> instructions = methodImplementation.getInstructions();
for (int i=0; i<instructions.size(); i++) { for (int i=0; i<instructions.size(); i++) {
Instruction instruction = instructions.get(i); Instruction instruction = instructions.get(i);
@ -798,18 +798,20 @@ public abstract class DexWriter<
@Nullable Iterable<? extends StringKey> parameterNames, @Nullable Iterable<? extends StringKey> parameterNames,
@Nullable Iterable<? extends DebugItem> debugItems) throws IOException { @Nullable Iterable<? extends DebugItem> debugItems) throws IOException {
int parameterCount = 0; int parameterCount = 0;
int lastNamedParameterIndex = -1;
if (parameterNames != null) { if (parameterNames != null) {
parameterCount = Iterables.size(parameterNames);
int index = 0; int index = 0;
for (StringKey parameterName: parameterNames) { for (StringKey parameterName: parameterNames) {
index++;
if (parameterName != null) { if (parameterName != null) {
parameterCount = index; lastNamedParameterIndex = index;
} }
index++;
} }
} }
if (parameterCount == 0 && (debugItems == null || Iterables.isEmpty(debugItems))) { if (lastNamedParameterIndex == -1 && (debugItems == null || Iterables.isEmpty(debugItems))) {
return NO_OFFSET; return NO_OFFSET;
} }

View File

@ -248,18 +248,18 @@ public class BuilderClassPool implements ClassSection<BuilderStringReference, Bu
@Nullable @Override public List<? extends BuilderAnnotationSet> getParameterAnnotations( @Nullable @Override public List<? extends BuilderAnnotationSet> getParameterAnnotations(
@Nonnull final BuilderMethod method) { @Nonnull final BuilderMethod method) {
final int lastIndex = CollectionUtils.lastIndexOf(method.getParameters(), HAS_PARAMETER_ANNOTATIONS); final List<? extends BuilderMethodParameter> parameters = method.getParameters();
boolean hasParameterAnnotations = Iterables.any(parameters, HAS_PARAMETER_ANNOTATIONS);
if (lastIndex > -1) { if (hasParameterAnnotations) {
return new AbstractForwardSequentialList<BuilderAnnotationSet>() { return new AbstractForwardSequentialList<BuilderAnnotationSet>() {
@Nonnull @Override public Iterator<BuilderAnnotationSet> iterator() { @Nonnull @Override public Iterator<BuilderAnnotationSet> iterator() {
return FluentIterable.from(method.getParameters()) return FluentIterable.from(parameters)
.limit(lastIndex+1)
.transform(PARAMETER_ANNOTATIONS).iterator(); .transform(PARAMETER_ANNOTATIONS).iterator();
} }
@Override public int size() { @Override public int size() {
return lastIndex+1; return parameters.size();
} }
}; };
} }

View File

@ -55,7 +55,7 @@ class BuilderTypeListPool implements TypeListSection<BuilderTypeReference, Build
} }
@Nonnull public BuilderTypeList internTypeList(@Nullable List<? extends CharSequence> types) { @Nonnull public BuilderTypeList internTypeList(@Nullable List<? extends CharSequence> types) {
if (types == null) { if (types == null || types.size() == 0) {
return BuilderTypeList.EMPTY; return BuilderTypeList.EMPTY;
} }
@ -76,7 +76,7 @@ class BuilderTypeListPool implements TypeListSection<BuilderTypeReference, Build
} }
@Override public int getNullableItemOffset(@Nullable BuilderTypeList key) { @Override public int getNullableItemOffset(@Nullable BuilderTypeList key) {
return key==null?DexWriter.NO_OFFSET:key.offset; return (key==null||key.size()==0)?DexWriter.NO_OFFSET:key.offset;
} }
@Nonnull @Override @Nonnull @Override

View File

@ -371,18 +371,18 @@ public class ClassPool implements ClassSection<CharSequence, CharSequence,
@Nullable @Override public List<? extends Set<? extends Annotation>> getParameterAnnotations( @Nullable @Override public List<? extends Set<? extends Annotation>> getParameterAnnotations(
@Nonnull final PoolMethod method) { @Nonnull final PoolMethod method) {
final int lastIndex = CollectionUtils.lastIndexOf(method.getParameters(), HAS_PARAMETER_ANNOTATIONS); final List<? extends MethodParameter> parameters = method.getParameters();
boolean hasParameterAnnotations = Iterables.any(parameters, HAS_PARAMETER_ANNOTATIONS);
if (lastIndex > -1) { if (hasParameterAnnotations) {
return new AbstractForwardSequentialList<Set<? extends Annotation>>() { return new AbstractForwardSequentialList<Set<? extends Annotation>>() {
@Nonnull @Override public Iterator<Set<? extends Annotation>> iterator() { @Nonnull @Override public Iterator<Set<? extends Annotation>> iterator() {
return FluentIterable.from(method.getParameters()) return FluentIterable.from(parameters)
.limit(lastIndex+1)
.transform(PARAMETER_ANNOTATIONS).iterator(); .transform(PARAMETER_ANNOTATIONS).iterator();
} }
@Override public int size() { @Override public int size() {
return lastIndex+1; return parameters.size();
} }
}; };
} }

View File

@ -32,10 +32,12 @@
package org.jf.dexlib2.writer.pool; package org.jf.dexlib2.writer.pool;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.jf.dexlib2.writer.pool.TypeListPool.Key; import org.jf.dexlib2.writer.DexWriter;
import org.jf.dexlib2.writer.TypeListSection; import org.jf.dexlib2.writer.TypeListSection;
import org.jf.dexlib2.writer.pool.TypeListPool.Key;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
@ -48,11 +50,13 @@ public class TypeListPool extends BaseNullableOffsetPool<Key<? extends Collectio
} }
public void intern(@Nonnull Collection<? extends CharSequence> types) { public void intern(@Nonnull Collection<? extends CharSequence> types) {
Key<? extends Collection<? extends CharSequence>> key = new Key<Collection<? extends CharSequence>>(types); if (types.size() > 0) {
Integer prev = internedItems.put(key, 0); Key<? extends Collection<? extends CharSequence>> key = new Key<Collection<? extends CharSequence>>(types);
if (prev == null) { Integer prev = internedItems.put(key, 0);
for (CharSequence type: types) { if (prev == null) {
typePool.intern(type); for (CharSequence type: types) {
typePool.intern(type);
}
} }
} }
} }
@ -65,6 +69,14 @@ public class TypeListPool extends BaseNullableOffsetPool<Key<? extends Collectio
return typesKey.types; return typesKey.types;
} }
@Override public int getNullableItemOffset(@Nullable Key<? extends Collection<? extends CharSequence>> key) {
if (key == null || key.types.size() == 0) {
return DexWriter.NO_OFFSET;
} else {
return super.getNullableItemOffset(key);
}
}
public static class Key<TypeCollection extends Collection<? extends CharSequence>> public static class Key<TypeCollection extends Collection<? extends CharSequence>>
implements Comparable<Key<? extends Collection<? extends CharSequence>>> { implements Comparable<Key<? extends Collection<? extends CharSequence>>> {
@Nonnull TypeCollection types; @Nonnull TypeCollection types;