Delete InstructionWriteUtil

This commit is contained in:
Ben Gruver 2013-08-25 11:07:43 -07:00
parent dff046e1b5
commit e94ee6fe80
7 changed files with 37 additions and 510 deletions

View File

@ -36,6 +36,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.base.BaseAnnotation;
import org.jf.dexlib2.dexbacked.raw.*;
import org.jf.dexlib2.iface.Annotation;
@ -44,10 +45,11 @@ import org.jf.dexlib2.iface.TryBlock;
import org.jf.dexlib2.iface.debug.DebugItem;
import org.jf.dexlib2.iface.debug.LineNumber;
import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.ReferenceInstruction;
import org.jf.dexlib2.iface.instruction.formats.*;
import org.jf.dexlib2.iface.reference.*;
import org.jf.dexlib2.util.InstructionUtil;
import org.jf.dexlib2.util.MethodUtil;
import org.jf.dexlib2.writer.util.InstructionWriteUtil;
import org.jf.dexlib2.writer.util.TryListBuilder;
import org.jf.util.CollectionUtils;
import org.jf.util.ExceptionWithContext;
@ -462,7 +464,7 @@ public abstract class DexWriter<
int prevIndex = 0;
for (FieldKey key: fields) {
int index = fieldSection.getFieldIndex(key);
writer.writeUleb128(index-prevIndex);
writer.writeUleb128(index - prevIndex);
writer.writeUleb128(classSection.getFieldAccessFlags(key));
prevIndex = index;
}
@ -812,10 +814,21 @@ public abstract class DexWriter<
if (instructions != null) {
tryBlocks = TryListBuilder.massageTryBlocks(tryBlocks);
InstructionWriteUtil<StringRef, BaseReference> instrWriteUtil =
new InstructionWriteUtil<StringRef, BaseReference>(
instructions, stringSection, instructionFactory);
writer.writeUshort(instrWriteUtil.getOutParamCount());
int outParamCount = 0;
int codeUnitCount = 0;
for (Instruction instruction: instructions) {
codeUnitCount += instruction.getCodeUnits();
if (instruction.getOpcode().referenceType == ReferenceType.METHOD) {
ReferenceInstruction refInsn = (ReferenceInstruction)instruction;
MethodReference methodRef = (MethodReference)refInsn.getReference();
int paramCount = MethodUtil.getParameterRegisterCount(methodRef, InstructionUtil.isInvokeStatic(instruction.getOpcode()));
if (paramCount > outParamCount) {
outParamCount = paramCount;
}
}
}
writer.writeUshort(outParamCount);
writer.writeUshort(tryBlocks.size());
writer.writeInt(debugItemOffset);
@ -823,8 +836,8 @@ public abstract class DexWriter<
InstructionWriter.makeInstructionWriter(writer, stringSection, typeSection, fieldSection,
methodSection);
writer.writeInt(instrWriteUtil.getCodeUnitCount());
for (Instruction instruction: instrWriteUtil.getInstructions()) {
writer.writeInt(codeUnitCount);
for (Instruction instruction: instructions) {
switch (instruction.getOpcode().format) {
case Format10t:
instructionWriter.write((Instruction10t)instruction);
@ -935,8 +948,6 @@ public abstract class DexWriter<
int startAddress = tryBlock.getStartCodeAddress();
int endAddress = startAddress + tryBlock.getCodeUnitCount();
startAddress += instrWriteUtil.codeOffsetShift(startAddress);
endAddress += instrWriteUtil.codeOffsetShift(endAddress);
int tbCodeUnitCount = endAddress - startAddress;
writer.writeInt(startAddress);
@ -969,7 +980,6 @@ public abstract class DexWriter<
TypeKey exceptionTypeKey = classSection.getExceptionType(eh);
int codeAddress = eh.getHandlerCodeAddress();
codeAddress += instrWriteUtil.codeOffsetShift(codeAddress);
if (exceptionTypeKey != null) {
//regular exception handling

View File

@ -32,8 +32,9 @@
package org.jf.dexlib2.writer;
import org.jf.dexlib2.iface.reference.StringReference;
import org.jf.dexlib2.writer.util.InstructionWriteUtil;
public interface StringSection<StringKey, StringRef extends StringReference> extends NullableIndexSection<StringKey>,
InstructionWriteUtil.StringIndexProvider<StringRef> {
import javax.annotation.Nonnull;
public interface StringSection<StringKey, StringRef extends StringReference> extends NullableIndexSection<StringKey> {
int getItemIndex(@Nonnull StringRef key);
}

View File

@ -33,6 +33,7 @@ package org.jf.dexlib2.writer.pool;
import org.jf.dexlib2.iface.reference.StringReference;
import org.jf.dexlib2.writer.StringSection;
import org.jf.util.ExceptionWithContext;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -49,6 +50,10 @@ public class StringPool extends StringTypeBasePool implements StringSection<Char
}
@Override public int getItemIndex(@Nonnull StringReference key) {
return getItemIndex(key.getString());
Integer index = internedItems.get(key.toString());
if (index == null) {
throw new ExceptionWithContext("Item not found.: %s", key.toString());
}
return index;
}
}

View File

@ -1,400 +0,0 @@
/*
* Copyright 2013, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.writer.util;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.jf.dexlib2.Format;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.ReferenceInstruction;
import org.jf.dexlib2.iface.instruction.SwitchElement;
import org.jf.dexlib2.iface.instruction.SwitchPayload;
import org.jf.dexlib2.iface.instruction.formats.*;
import org.jf.dexlib2.iface.reference.*;
import org.jf.dexlib2.immutable.instruction.*;
import org.jf.dexlib2.util.InstructionUtil;
import org.jf.dexlib2.util.MethodUtil;
import org.jf.dexlib2.writer.InstructionFactory;
import org.jf.util.ExceptionWithContext;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class InstructionWriteUtil<StringRef extends StringReference, BaseReference extends Reference> {
private final StringIndexProvider<StringRef> stringIndexProvider;
private final InstructionFactory<BaseReference> instructionFactory;
private final Iterable<? extends Instruction> originalInstructions;
private List<Instruction> instructions;
private ArrayList<Integer> codeOffsetShifts;
private HashMap<Integer,Format> offsetToNewInstructionMap;
private int codeUnitCount;
private int outParamCount;
public static interface StringIndexProvider<StringRef extends StringReference> {
int getItemIndex(@Nonnull StringRef reference);
}
public InstructionWriteUtil(@Nonnull Iterable<? extends Instruction> instructions,
@Nonnull StringIndexProvider<StringRef> stringIndexProvider,
@Nonnull InstructionFactory<BaseReference> instructionFactory) {
this.stringIndexProvider = stringIndexProvider;
this.instructionFactory = instructionFactory;
this.originalInstructions = instructions;
calculateMaxOutParamCount();
findCodeOffsetShifts();
modifyInstructions();
}
private void calculateMaxOutParamCount() {
for (Instruction instruction: originalInstructions) {
codeUnitCount += instruction.getCodeUnits();
if (instruction.getOpcode().referenceType == ReferenceType.METHOD) {
ReferenceInstruction refInsn = (ReferenceInstruction)instruction;
MethodReference methodRef = (MethodReference)refInsn.getReference();
int paramCount = MethodUtil.getParameterRegisterCount(methodRef, InstructionUtil.isInvokeStatic(instruction.getOpcode()));
if (paramCount > outParamCount) {
outParamCount = paramCount;
}
}
}
}
public Iterable<? extends Instruction> getInstructions() {
if (instructions != null) {
return instructions;
} else {
return originalInstructions;
}
}
public int getCodeUnitCount() {
return codeUnitCount;
}
public int getOutParamCount() {
return outParamCount;
}
private int targetOffsetShift(int instrOffset, int targetOffset) {
int targetOffsetShift = 0;
if (codeOffsetShifts != null) {
int instrShift = codeOffsetShift(instrOffset);
int targetShift = codeOffsetShift(instrOffset+targetOffset);
targetOffsetShift = targetShift - instrShift;
}
return targetOffsetShift;
}
public int codeOffsetShift(int offset) {
int shift = 0;
if (codeOffsetShifts != null) {
int numCodeOffsetShifts = codeOffsetShifts.size();
if (numCodeOffsetShifts > 0) {
if (offset >= codeOffsetShifts.get(numCodeOffsetShifts-1)) {
shift = numCodeOffsetShifts;
} else if (numCodeOffsetShifts>1) {
for (int i=1;i<numCodeOffsetShifts;i++) {
if (offset >= codeOffsetShifts.get(i-1) && offset < codeOffsetShifts.get(i)) {
shift = i;
break;
}
}
}
}
}
return shift;
}
/*
* This method creates a list of code offsets of instructions, whose (and subsequent instructions')
* code offset will get shifted by one code unit with respect to previous instruction(s).
* This happens when the previous instruction has to be changed to a larger sized one
* to fit the new value or payload instruction has to be prepended by nop to ensure alignment.
*/
private void findCodeOffsetShifts() {
// first, process const-string to const-string/jumbo conversions
int currentCodeOffset = 0;
codeOffsetShifts = Lists.newArrayList();
offsetToNewInstructionMap = Maps.newHashMap();
for (Instruction instruction: originalInstructions) {
if (instruction.getOpcode().equals(Opcode.CONST_STRING)) {
ReferenceInstruction refInstr = (ReferenceInstruction) instruction;
int referenceIndex = stringIndexProvider.getItemIndex((StringRef)refInstr.getReference());
if (referenceIndex > 0xFFFF) {
codeOffsetShifts.add(currentCodeOffset+instruction.getCodeUnits());
offsetToNewInstructionMap.put(currentCodeOffset, Opcode.CONST_STRING_JUMBO.format);
}
}
currentCodeOffset += instruction.getCodeUnits();
}
// next, let's check if this caused any conversions in goto instructions due to changes in offset values
// since code offset delta is equivalent to the position of instruction's code offset in the shift list,
// we use it as a position here
// we also check if we will have to insert nops to ensure 4-byte alignment for switch statements and packed arrays
boolean shiftsInserted;
do {
currentCodeOffset = 0;
shiftsInserted = false;
for (Instruction instruction: originalInstructions) {
if (instruction.getOpcode().format.equals(Format.Format10t) && !offsetToNewInstructionMap.containsKey(currentCodeOffset)) {
int targetOffset = ((Instruction10t)instruction).getCodeOffset();
int codeOffsetDelta = codeOffsetShift(currentCodeOffset);
int newTargetOffset = targetOffset + targetOffsetShift(currentCodeOffset, targetOffset);
if ((byte)newTargetOffset != newTargetOffset) {
if ((short)newTargetOffset != newTargetOffset) {
// handling very small (negligible) possibility of goto becoming goto/32
// we insert extra 1 code unit shift referring to the same position
// this will cause subsequent code offsets to be shifted by 2 code units
codeOffsetShifts.add(codeOffsetDelta, currentCodeOffset+instruction.getCodeUnits());
offsetToNewInstructionMap.put(currentCodeOffset, Format.Format30t);
} else {
offsetToNewInstructionMap.put(currentCodeOffset, Format.Format20t);
}
codeOffsetShifts.add(codeOffsetDelta, currentCodeOffset+instruction.getCodeUnits());
shiftsInserted = true;
}
} else if (instruction.getOpcode().format.equals(Format.Format20t) && !offsetToNewInstructionMap.containsKey(currentCodeOffset)) {
int targetOffset = ((Instruction20t)instruction).getCodeOffset();
int codeOffsetDelta = codeOffsetShift(currentCodeOffset);
int newTargetOffset = targetOffset + targetOffsetShift(currentCodeOffset, targetOffset);
if ((short)newTargetOffset != newTargetOffset) {
codeOffsetShifts.add(codeOffsetDelta, currentCodeOffset+instruction.getCodeUnits());
offsetToNewInstructionMap.put(currentCodeOffset, Format.Format30t);
shiftsInserted = true;
}
} else if (instruction.getOpcode().format.equals(Format.ArrayPayload)
|| instruction.getOpcode().format.equals(Format.SparseSwitchPayload)
|| instruction.getOpcode().format.equals(Format.PackedSwitchPayload)) {
int codeOffsetDelta = codeOffsetShift(currentCodeOffset);
if ((currentCodeOffset+codeOffsetDelta)%2 != 0) {
if (codeOffsetShifts.contains(currentCodeOffset)) {
codeOffsetShifts.remove(codeOffsetDelta-1);
offsetToNewInstructionMap.remove(currentCodeOffset);
} else {
codeOffsetShifts.add(codeOffsetDelta, currentCodeOffset);
offsetToNewInstructionMap.put(currentCodeOffset, Format.Format10x);
shiftsInserted = true;
}
}
}
currentCodeOffset += instruction.getCodeUnits();
}
} while (shiftsInserted);
codeUnitCount += codeOffsetShifts.size();
}
private void modifyInstructions() {
if (codeOffsetShifts == null) {
return;
}
instructions = Lists.newArrayList();
int currentCodeOffset = 0;
for (Instruction instruction: originalInstructions) {
Instruction modifiedInstruction = null;
switch (instruction.getOpcode().format) {
case Format10t: {
Instruction10t instr = (Instruction10t)instruction;
int targetOffset = instr.getCodeOffset();
int newTargetOffset = targetOffset + targetOffsetShift(currentCodeOffset, targetOffset);
Format newInstructionFormat = offsetToNewInstructionMap.get(currentCodeOffset);
if (newInstructionFormat != null) {
if (newInstructionFormat.equals(Format.Format30t)) {
modifiedInstruction = instructionFactory.makeInstruction30t(Opcode.GOTO_32, newTargetOffset);
} else if (newInstructionFormat.equals(Format.Format20t)) {
modifiedInstruction = instructionFactory.makeInstruction20t(Opcode.GOTO_16, newTargetOffset);
}
} else if (newTargetOffset != targetOffset) {
modifiedInstruction = instructionFactory.makeInstruction10t(instr.getOpcode(), newTargetOffset);
}
break;
}
case Format20t: {
Instruction20t instr = (Instruction20t)instruction;
int targetOffset = instr.getCodeOffset();
int newTargetOffset = targetOffset + targetOffsetShift(currentCodeOffset, targetOffset);
Format newInstructionFormat = offsetToNewInstructionMap.get(currentCodeOffset);
if (newInstructionFormat != null && newInstructionFormat.equals(Format.Format30t)) {
modifiedInstruction = instructionFactory.makeInstruction30t(Opcode.GOTO_32, newTargetOffset);
} else if (newTargetOffset != targetOffset) {
modifiedInstruction = instructionFactory.makeInstruction20t(Opcode.GOTO_16, newTargetOffset);
}
break;
}
case Format21c: {
Instruction21c instr = (Instruction21c)instruction;
if (instr.getOpcode().equals(Opcode.CONST_STRING)) {
int referenceIndex = stringIndexProvider.getItemIndex((StringRef)instr.getReference());
if (referenceIndex > 0xFFFF) {
modifiedInstruction = instructionFactory.makeInstruction31c(Opcode.CONST_STRING_JUMBO,
instr.getRegisterA(), (BaseReference)instr.getReference());
}
}
break;
}
case Format21t: {
Instruction21t instr = (Instruction21t)instruction;
int targetOffset = instr.getCodeOffset();
int newTargetOffset = targetOffset + targetOffsetShift(currentCodeOffset, targetOffset);
if (newTargetOffset != targetOffset) {
modifiedInstruction = instructionFactory.makeInstruction21t(instr.getOpcode(),
instr.getRegisterA(), newTargetOffset);
}
break;
}
case Format22t: {
Instruction22t instr = (Instruction22t)instruction;
int targetOffset = instr.getCodeOffset();
int newTargetOffset = targetOffset + targetOffsetShift(currentCodeOffset, targetOffset);
if (newTargetOffset != targetOffset) {
modifiedInstruction = instructionFactory.makeInstruction22t(instr.getOpcode(),
instr.getRegisterA(), instr.getRegisterB(), newTargetOffset);
}
break;
}
case Format30t: {
Instruction30t instr = (Instruction30t)instruction;
int targetOffset = instr.getCodeOffset();
int newTargetOffset = targetOffset + targetOffsetShift(currentCodeOffset, targetOffset);
if (newTargetOffset != targetOffset) {
modifiedInstruction = instructionFactory.makeInstruction30t(instr.getOpcode(), newTargetOffset);
}
break;
}
case Format31t: {
Instruction31t instr = (Instruction31t)instruction;
int targetOffset = instr.getCodeOffset();
int newTargetOffset = targetOffset + targetOffsetShift(currentCodeOffset, targetOffset);
if (newTargetOffset != targetOffset) {
modifiedInstruction = instructionFactory.makeInstruction31t(instr.getOpcode(),
instr.getRegisterA(), newTargetOffset);
}
break;
}
case SparseSwitchPayload: {
alignPayload(currentCodeOffset);
int switchInstructionOffset = findSwitchInstructionOffset(currentCodeOffset);
SwitchPayload payload = (SwitchPayload)instruction;
if (isSwitchTargetOffsetChanged(payload, switchInstructionOffset)) {
List<SwitchElement> newSwitchElements = modifySwitchElements(payload, switchInstructionOffset);
modifiedInstruction = instructionFactory.makeSparseSwitchPayload(newSwitchElements);
}
break;
}
case PackedSwitchPayload: {
alignPayload(currentCodeOffset);
int switchInstructionOffset = findSwitchInstructionOffset(currentCodeOffset);
SwitchPayload payload = (SwitchPayload)instruction;
if (isSwitchTargetOffsetChanged(payload, switchInstructionOffset)) {
List<SwitchElement> newSwitchElements = modifySwitchElements(payload, switchInstructionOffset);
modifiedInstruction = instructionFactory.makePackedSwitchPayload(newSwitchElements);
}
break;
}
case ArrayPayload: {
alignPayload(currentCodeOffset);
break;
}
}
if (modifiedInstruction != null) {
instructions.add(modifiedInstruction);
} else {
instructions.add(instruction);
}
currentCodeOffset += instruction.getCodeUnits();
}
}
private void alignPayload(int codeOffset) {
Format newInstructionFormat = offsetToNewInstructionMap.get(codeOffset);
if (newInstructionFormat != null && newInstructionFormat.equals(Format.Format10x)) {
instructions.add(instructionFactory.makeInstruction10x(Opcode.NOP));
}
}
private int findSwitchInstructionOffset(int payloadOffset) {
int currentCodeOffset = 0;
int switchInstructionOffset = -1;
for (Instruction instruction: originalInstructions) {
if (instruction.getOpcode().equals(Opcode.PACKED_SWITCH)
|| instruction.getOpcode().equals(Opcode.SPARSE_SWITCH)) {
int targetOffset = currentCodeOffset + ((Instruction31t)instruction).getCodeOffset();
if (targetOffset == payloadOffset) {
if (switchInstructionOffset < 0) {
switchInstructionOffset = currentCodeOffset;
} else {
throw new ExceptionWithContext("Multiple switch instructions refer to the same switch payload!");
}
}
}
currentCodeOffset += instruction.getCodeUnits();
}
return switchInstructionOffset;
}
private boolean isSwitchTargetOffsetChanged(SwitchPayload payload, int switchInstructionOffset) {
for (SwitchElement switchElement: payload.getSwitchElements()) {
if (targetOffsetShift(switchInstructionOffset, switchElement.getOffset()) != 0) {
return true;
}
}
return false;
}
private ArrayList<SwitchElement> modifySwitchElements(SwitchPayload payload, int switchInstructionOffset) {
ArrayList<SwitchElement> switchElements = Lists.newArrayList();
for (SwitchElement switchElement: payload.getSwitchElements()) {
int targetOffset = switchElement.getOffset();
int newTargetOffset = targetOffset + targetOffsetShift(switchInstructionOffset, targetOffset);
if (newTargetOffset != targetOffset) {
ImmutableSwitchElement immuSwitchElement = new ImmutableSwitchElement(switchElement.getKey(), newTargetOffset);
switchElements.add(immuSwitchElement);
} else {
switchElements.add(switchElement);
}
}
return switchElements;
}
}

View File

@ -31,26 +31,8 @@
package org.jf.dexlib2.writer;
import com.google.common.collect.Lists;
import junit.framework.Assert;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.iface.MethodImplementation;
import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.SwitchElement;
import org.jf.dexlib2.iface.instruction.formats.*;
import org.jf.dexlib2.iface.reference.Reference;
import org.jf.dexlib2.iface.reference.StringReference;
import org.jf.dexlib2.immutable.ImmutableMethodImplementation;
import org.jf.dexlib2.immutable.instruction.*;
import org.jf.dexlib2.immutable.reference.ImmutableStringReference;
import org.jf.dexlib2.writer.util.InstructionWriteUtil;
import org.junit.Before;
import org.junit.Test;
import javax.annotation.Nonnull;
import java.util.ArrayList;
public class JumboStringConversionTest {
// TODO: uncomment/reimplement
/*public class JumboStringConversionTest {
private static final int MIN_NUM_JUMBO_STRINGS = 2;
private MockStringIndexProvider mockStringIndexProvider;
@ -378,4 +360,4 @@ public class JumboStringConversionTest {
codeOffset += instruction.getCodeUnits();
}
}
}
}*/

View File

@ -1,55 +0,0 @@
/*
* Copyright 2012, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.writer;
import com.google.common.collect.Maps;
import org.jf.dexlib2.iface.reference.StringReference;
import org.jf.dexlib2.writer.util.InstructionWriteUtil.StringIndexProvider;
import javax.annotation.Nonnull;
import java.util.HashMap;
public class MockStringIndexProvider implements StringIndexProvider<StringReference> {
private HashMap<String, Integer> internedItems = Maps.newHashMap();
public void intern(@Nonnull CharSequence string, int index) {
internedItems.put(string.toString(), index);
}
@Override public int getItemIndex(@Nonnull StringReference reference) {
return internedItems.get(reference.getString());
}
public int getNumItems() {
return internedItems.size();
}
}

View File

@ -31,24 +31,8 @@
package org.jf.dexlib2.writer;
import com.google.common.collect.Lists;
import junit.framework.Assert;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.iface.MethodImplementation;
import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.SwitchElement;
import org.jf.dexlib2.iface.reference.Reference;
import org.jf.dexlib2.iface.reference.StringReference;
import org.jf.dexlib2.immutable.ImmutableMethodImplementation;
import org.jf.dexlib2.immutable.instruction.*;
import org.jf.dexlib2.writer.util.InstructionWriteUtil;
import org.junit.Before;
import org.junit.Test;
import javax.annotation.Nonnull;
import java.util.ArrayList;
public class PayloadAlignmentTest {
// TODO: uncomment/reimplement
/*public class PayloadAlignmentTest {
private MockStringIndexProvider mockStringIndexProvider;
private class InsnWriteUtil extends InstructionWriteUtil<StringReference, Reference> {
@ -128,4 +112,4 @@ public class PayloadAlignmentTest {
codeOffset += instr.getCodeUnits();
}
}
}
}*/