mirror of
https://github.com/revanced/smali.git
synced 2025-05-04 08:34:25 +02:00
Implement support in dexlib2 for payload instructions
This commit is contained in:
parent
68f69b899f
commit
c307c1887d
@ -63,20 +63,20 @@ public enum Format {
|
|||||||
Format3rmi(6),
|
Format3rmi(6),
|
||||||
Format3rms(6),
|
Format3rms(6),
|
||||||
Format51l(10),
|
Format51l(10),
|
||||||
ArrayData(-1, true),
|
ArrayPayload(-1, true),
|
||||||
PackedSwitchData(-1, true),
|
PackedSwitchPayload(-1, true),
|
||||||
SparseSwitchData(-1, true),
|
SparseSwitchPayload(-1, true),
|
||||||
UnresolvedOdexInstruction(-1, false);
|
UnresolvedOdexInstruction(-1);
|
||||||
|
|
||||||
public final int size;
|
public final int size;
|
||||||
public final boolean variableSizeFormat;
|
public final boolean payloadFormat;
|
||||||
|
|
||||||
private Format(int size) {
|
private Format(int size) {
|
||||||
this(size, false);
|
this(size, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Format(int size, boolean variableSizeFormat) {
|
private Format(int size, boolean payloadFormat) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.variableSizeFormat = variableSizeFormat;
|
this.payloadFormat = payloadFormat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,7 +283,11 @@ public enum Opcode
|
|||||||
|
|
||||||
IPUT_OBJECT_VOLATILE((short)0xfc, "iput-object-volatile", ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
IPUT_OBJECT_VOLATILE((short)0xfc, "iput-object-volatile", ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||||
SGET_OBJECT_VOLATILE((short)0xfd, "sget-object-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
SGET_OBJECT_VOLATILE((short)0xfd, "sget-object-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||||
SPUT_OBJECT_VOLATILE((short)0xfe, "sput-object-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE);
|
SPUT_OBJECT_VOLATILE((short)0xfe, "sput-object-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||||
|
|
||||||
|
PACKED_SWITCH_PAYLOAD((short)0x100, "packed-switch-payload", ReferenceType.NONE, Format.PackedSwitchPayload, 0),
|
||||||
|
SPARSE_SWITCH_PAYLOAD((short)0x200, "sparse-switch-payload", ReferenceType.NONE, Format.SparseSwitchPayload, 0),
|
||||||
|
ARRAY_PAYLOAD((short)0x300, "array-payload", ReferenceType.NONE, Format.ArrayPayload, 0);
|
||||||
|
|
||||||
private static final Opcode[] opcodesByValue;
|
private static final Opcode[] opcodesByValue;
|
||||||
private static final HashMap<Integer, Opcode> opcodesByName;
|
private static final HashMap<Integer, Opcode> opcodesByName;
|
||||||
@ -316,10 +320,12 @@ public enum Opcode
|
|||||||
opcodesByName = new HashMap<Integer, Opcode>();
|
opcodesByName = new HashMap<Integer, Opcode>();
|
||||||
|
|
||||||
for (Opcode opcode: Opcode.values()) {
|
for (Opcode opcode: Opcode.values()) {
|
||||||
//INVOKE_DIRECT_EMPTY was changed to INVOKE_OBJECT_INIT_RANGE in ICS
|
if (!opcode.format.payloadFormat) {
|
||||||
if (opcode != INVOKE_DIRECT_EMPTY) {
|
//INVOKE_DIRECT_EMPTY was changed to INVOKE_OBJECT_INIT_RANGE in ICS
|
||||||
opcodesByValue[opcode.value] = opcode;
|
if (opcode != INVOKE_DIRECT_EMPTY) {
|
||||||
opcodesByName.put(opcode.name.hashCode(), opcode);
|
opcodesByValue[opcode.value] = opcode;
|
||||||
|
opcodesByName.put(opcode.name.hashCode(), opcode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,7 +335,16 @@ public enum Opcode
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Opcode getOpcodeByValue(int opcodeValue) {
|
public static Opcode getOpcodeByValue(int opcodeValue) {
|
||||||
return opcodesByValue[opcodeValue];
|
switch (opcodeValue) {
|
||||||
|
case 0x100:
|
||||||
|
return SPARSE_SWITCH_PAYLOAD;
|
||||||
|
case 0x200:
|
||||||
|
return PACKED_SWITCH_PAYLOAD;
|
||||||
|
case 0x300:
|
||||||
|
return ARRAY_PAYLOAD;
|
||||||
|
default:
|
||||||
|
return opcodesByValue[opcodeValue];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void removeOpcodes(Opcode... toRemove) {
|
private static void removeOpcodes(Opcode... toRemove) {
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* 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.dexbacked.instruction;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.Opcode;
|
||||||
|
import org.jf.dexlib2.dexbacked.DexBuffer;
|
||||||
|
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
||||||
|
import org.jf.dexlib2.iface.instruction.formats.ArrayPayload;
|
||||||
|
import org.jf.util.ExceptionWithContext;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DexBackedArrayPayload implements ArrayPayload {
|
||||||
|
public static final Opcode OPCODE = Opcode.ARRAY_PAYLOAD;
|
||||||
|
|
||||||
|
@Nonnull public final DexBuffer dexBuf;
|
||||||
|
private final int instructionOffset;
|
||||||
|
|
||||||
|
public final int elementWidth;
|
||||||
|
public final int elementCount;
|
||||||
|
|
||||||
|
private static final int ELEMENT_WIDTH_OFFSET = 2;
|
||||||
|
private static final int ELEMENT_COUNT_OFFSET = 4;
|
||||||
|
private static final int ELEMENTS_OFFSET = 8;
|
||||||
|
|
||||||
|
public DexBackedArrayPayload(DexBuffer dexBuf,
|
||||||
|
int instructionOffset) {
|
||||||
|
this.dexBuf = dexBuf;
|
||||||
|
this.instructionOffset = instructionOffset;
|
||||||
|
|
||||||
|
this.elementWidth = dexBuf.readUshort(instructionOffset + ELEMENT_WIDTH_OFFSET);
|
||||||
|
this.elementCount = dexBuf.readSmallUint(instructionOffset + ELEMENT_COUNT_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getElementWidth() { return elementWidth; }
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public List<Number> getArrayElements() {
|
||||||
|
final int elementsStart = instructionOffset + ELEMENTS_OFFSET;
|
||||||
|
|
||||||
|
abstract class ReturnedList extends FixedSizeList<Number> {
|
||||||
|
@Override public int size() { return elementCount; }
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (elementWidth) {
|
||||||
|
case 1:
|
||||||
|
return new ReturnedList() {
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Number readItem(int index) {
|
||||||
|
return dexBuf.readByte(elementsStart + index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case 2:
|
||||||
|
return new ReturnedList() {
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Number readItem(int index) {
|
||||||
|
return dexBuf.readShort(elementsStart + index*2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case 4:
|
||||||
|
return new ReturnedList() {
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Number readItem(int index) {
|
||||||
|
return dexBuf.readInt(elementsStart + index*4);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case 8:
|
||||||
|
return new ReturnedList() {
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Number readItem(int index) {
|
||||||
|
return dexBuf.readLong(elementsStart + index*8);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
throw new ExceptionWithContext("Invalid element width: %d", elementWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCodeUnits() {
|
||||||
|
return 4 + (elementWidth*elementCount + 1) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Opcode getOpcode() { return OPCODE; }
|
||||||
|
}
|
@ -45,6 +45,10 @@ public abstract class DexBackedInstruction {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public static Instruction readFrom(@Nonnull DexReader reader) {
|
public static Instruction readFrom(@Nonnull DexReader reader) {
|
||||||
int opcodeValue = reader.readUbyte();
|
int opcodeValue = reader.readUbyte();
|
||||||
|
if (opcodeValue == 0) {
|
||||||
|
reader.moveRelative(-1);
|
||||||
|
opcodeValue = reader.readUshort();
|
||||||
|
}
|
||||||
|
|
||||||
Opcode opcode = Opcode.getOpcodeByValue(opcodeValue);
|
Opcode opcode = Opcode.getOpcodeByValue(opcodeValue);
|
||||||
|
|
||||||
@ -101,6 +105,13 @@ public abstract class DexBackedInstruction {
|
|||||||
return instruction3rc(opcode, reader);
|
return instruction3rc(opcode, reader);
|
||||||
case Format51l:
|
case Format51l:
|
||||||
return instruction51l(opcode, reader);
|
return instruction51l(opcode, reader);
|
||||||
|
case PackedSwitchPayload:
|
||||||
|
return packedSwitchPayload(reader);
|
||||||
|
case SparseSwitchPayload:
|
||||||
|
return sparseSwitchPayload(reader);
|
||||||
|
case ArrayPayload:
|
||||||
|
return arrayPayload(reader);
|
||||||
|
//TODO: temporary, until we get all instructions implemented
|
||||||
default:
|
default:
|
||||||
throw new ExceptionWithContext("Unexpected opcode format: %s", opcode.format.toString());
|
throw new ExceptionWithContext("Unexpected opcode format: %s", opcode.format.toString());
|
||||||
}
|
}
|
||||||
@ -308,4 +319,33 @@ public abstract class DexBackedInstruction {
|
|||||||
long literal = reader.readLong();
|
long literal = reader.readLong();
|
||||||
return new ImmutableInstruction51l(opcode, registerA, literal);
|
return new ImmutableInstruction51l(opcode, registerA, literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static DexBackedPackedSwitchPayload packedSwitchPayload(@Nonnull DexReader reader) {
|
||||||
|
// the reader is currently positioned after the 2-byte "opcode"
|
||||||
|
int instructionStartOffset = reader.getOffset() - 2;
|
||||||
|
DexBackedPackedSwitchPayload instruction =
|
||||||
|
new DexBackedPackedSwitchPayload(reader.getDexBuffer(), instructionStartOffset);
|
||||||
|
reader.moveRelative(instruction.getCodeUnits() * 2);
|
||||||
|
return instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static DexBackedSparseSwitchPayload sparseSwitchPayload(@Nonnull DexReader reader) {
|
||||||
|
// the reader is currently positioned after the 2-byte "opcode"
|
||||||
|
int instructionStartOffset = reader.getOffset() - 2;
|
||||||
|
DexBackedSparseSwitchPayload instruction =
|
||||||
|
new DexBackedSparseSwitchPayload(reader.getDexBuffer(), instructionStartOffset);
|
||||||
|
reader.moveRelative(instruction.getCodeUnits() * 2);
|
||||||
|
return instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static DexBackedArrayPayload arrayPayload(@Nonnull DexReader reader) {
|
||||||
|
// the reader is currently positioned after the 2-byte "opcode"
|
||||||
|
int instructionStartOffset = reader.getOffset() - 2;
|
||||||
|
DexBackedArrayPayload instruction = new DexBackedArrayPayload(reader.getDexBuffer(), instructionStartOffset);
|
||||||
|
reader.moveRelative(instruction.getCodeUnits() * 2);
|
||||||
|
return instruction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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.dexbacked.instruction;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.Opcode;
|
||||||
|
import org.jf.dexlib2.dexbacked.DexBuffer;
|
||||||
|
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
||||||
|
import org.jf.dexlib2.iface.instruction.SwitchElement;
|
||||||
|
import org.jf.dexlib2.iface.instruction.formats.PackedSwitchPayload;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DexBackedPackedSwitchPayload implements PackedSwitchPayload {
|
||||||
|
public static final Opcode OPCODE = Opcode.PACKED_SWITCH_PAYLOAD;
|
||||||
|
|
||||||
|
@Nonnull public final DexBuffer dexBuf;
|
||||||
|
private final int instructionOffset;
|
||||||
|
|
||||||
|
public final int elementCount;
|
||||||
|
|
||||||
|
private static final int ELEMENT_COUNT_OFFSET = 2;
|
||||||
|
private static final int FIRST_KEY_OFFSET = 4;
|
||||||
|
private static final int TARGETS_OFFSET = 8;
|
||||||
|
|
||||||
|
public DexBackedPackedSwitchPayload(@Nonnull DexBuffer dexBuf,
|
||||||
|
int instructionOffset) {
|
||||||
|
this.dexBuf = dexBuf;
|
||||||
|
this.instructionOffset = instructionOffset;
|
||||||
|
|
||||||
|
this.elementCount = dexBuf.readByte(instructionOffset + ELEMENT_COUNT_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public List<? extends SwitchElement> getSwitchElements() {
|
||||||
|
final int firstKey = dexBuf.readInt(instructionOffset + FIRST_KEY_OFFSET);
|
||||||
|
return new FixedSizeList<SwitchElement>() {
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public SwitchElement readItem(final int index) {
|
||||||
|
return new SwitchElement() {
|
||||||
|
@Override
|
||||||
|
public int getKey() {
|
||||||
|
return firstKey + index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset() {
|
||||||
|
return dexBuf.readInt(instructionOffset + TARGETS_OFFSET + index*4);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int size() { return elementCount; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getCodeUnits() { return 4 + elementCount*2; }
|
||||||
|
@Override public Opcode getOpcode() { return OPCODE; }
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* 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.dexbacked.instruction;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.Opcode;
|
||||||
|
import org.jf.dexlib2.dexbacked.DexBuffer;
|
||||||
|
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
||||||
|
import org.jf.dexlib2.iface.instruction.SwitchElement;
|
||||||
|
import org.jf.dexlib2.iface.instruction.formats.SparseSwitchPayload;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DexBackedSparseSwitchPayload implements SparseSwitchPayload {
|
||||||
|
public static final Opcode OPCODE = Opcode.SPARSE_SWITCH_PAYLOAD;
|
||||||
|
|
||||||
|
@Nonnull public final DexBuffer dexBuf;
|
||||||
|
private final int instructionOffset;
|
||||||
|
|
||||||
|
public final int elementCount;
|
||||||
|
|
||||||
|
private static final int ELEMENT_COUNT_OFFSET = 2;
|
||||||
|
private static final int KEYS_OFFSET = 4;
|
||||||
|
|
||||||
|
public DexBackedSparseSwitchPayload(@Nonnull DexBuffer dexBuf,
|
||||||
|
int instructionOffset) {
|
||||||
|
this.dexBuf = dexBuf;
|
||||||
|
this.instructionOffset = instructionOffset;
|
||||||
|
|
||||||
|
this.elementCount = dexBuf.readUshort(instructionOffset + ELEMENT_COUNT_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public List<? extends SwitchElement> getSwitchElements() {
|
||||||
|
return new FixedSizeList<SwitchElement>() {
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public SwitchElement readItem(final int index) {
|
||||||
|
return new SwitchElement() {
|
||||||
|
@Override
|
||||||
|
public int getKey() {
|
||||||
|
return dexBuf.readInt(instructionOffset + KEYS_OFFSET + index*4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset() {
|
||||||
|
return dexBuf.readInt(instructionOffset + KEYS_OFFSET + elementCount*4 + index*4);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int size() { return elementCount; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getCodeUnits() { return 2 + elementCount*4; }
|
||||||
|
@Override public Opcode getOpcode() { return OPCODE; }
|
||||||
|
}
|
@ -35,4 +35,5 @@ import org.jf.dexlib2.Opcode;
|
|||||||
|
|
||||||
public interface Instruction {
|
public interface Instruction {
|
||||||
Opcode getOpcode();
|
Opcode getOpcode();
|
||||||
|
int getCodeUnits();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.iface.instruction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty marker interface for the switch/array payload instructions
|
||||||
|
*/
|
||||||
|
public interface PayloadInstruction extends Instruction {
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.iface.instruction;
|
||||||
|
|
||||||
|
public interface SwitchElement {
|
||||||
|
public int getKey();
|
||||||
|
public int getOffset();
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.iface.instruction;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface SwitchPayload extends PayloadInstruction {
|
||||||
|
@Nonnull List<? extends SwitchElement> getSwitchElements();
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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.iface.instruction.formats;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.iface.instruction.PayloadInstruction;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ArrayPayload extends PayloadInstruction {
|
||||||
|
public int getElementWidth();
|
||||||
|
@Nonnull public List<Number> getArrayElements();
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.iface.instruction.formats;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.iface.instruction.SwitchPayload;
|
||||||
|
|
||||||
|
public interface PackedSwitchPayload extends SwitchPayload {
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.iface.instruction.formats;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.iface.instruction.SwitchPayload;
|
||||||
|
|
||||||
|
public interface SparseSwitchPayload extends SwitchPayload {
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* 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.immutable.instruction;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import org.jf.dexlib2.Format;
|
||||||
|
import org.jf.dexlib2.Opcode;
|
||||||
|
import org.jf.dexlib2.iface.instruction.formats.ArrayPayload;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImmutableArrayPayload extends ImmutableInstruction implements ArrayPayload {
|
||||||
|
public static final Opcode OPCODE = Opcode.ARRAY_PAYLOAD;
|
||||||
|
|
||||||
|
public final int elementWidth;
|
||||||
|
@Nonnull public final ImmutableList<Number> arrayElements;
|
||||||
|
|
||||||
|
public ImmutableArrayPayload(int elementWidth,
|
||||||
|
@Nullable List<Number> arrayElements) {
|
||||||
|
super(OPCODE);
|
||||||
|
this.elementWidth = elementWidth;
|
||||||
|
this.arrayElements = arrayElements==null ? ImmutableList.<Number>of() : ImmutableList.copyOf(arrayElements);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmutableArrayPayload(int elementWidth,
|
||||||
|
@Nullable ImmutableList<Number> arrayElements) {
|
||||||
|
super(OPCODE);
|
||||||
|
//TODO: need to ensure this is a valid width (1, 2, 4, 8)
|
||||||
|
this.elementWidth = elementWidth;
|
||||||
|
//TODO: need to validate the elements fit within the width
|
||||||
|
this.arrayElements = Objects.firstNonNull(arrayElements, ImmutableList.<Number>of());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static ImmutableArrayPayload of(ArrayPayload instruction) {
|
||||||
|
if (instruction instanceof ImmutableArrayPayload) {
|
||||||
|
return (ImmutableArrayPayload)instruction;
|
||||||
|
}
|
||||||
|
return new ImmutableArrayPayload(
|
||||||
|
instruction.getElementWidth(),
|
||||||
|
instruction.getArrayElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getElementWidth() { return elementWidth; }
|
||||||
|
@Nonnull @Override public List<Number> getArrayElements() { return arrayElements; }
|
||||||
|
|
||||||
|
@Override public int getCodeUnits() { return 4 + (elementWidth * arrayElements.size() + 1) / 2; }
|
||||||
|
@Override public Format getFormat() { return OPCODE.format; }
|
||||||
|
}
|
@ -43,7 +43,7 @@ import javax.annotation.Nonnull;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class ImmutableInstruction implements Instruction {
|
public abstract class ImmutableInstruction implements Instruction {
|
||||||
public final Opcode opcode;
|
@Nonnull public final Opcode opcode;
|
||||||
|
|
||||||
protected ImmutableInstruction(@Nonnull Opcode opcode) {
|
protected ImmutableInstruction(@Nonnull Opcode opcode) {
|
||||||
this.opcode = opcode;
|
this.opcode = opcode;
|
||||||
@ -51,6 +51,7 @@ public abstract class ImmutableInstruction implements Instruction {
|
|||||||
Preconditions.checkFormat(opcode, getFormat());
|
Preconditions.checkFormat(opcode, getFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public static ImmutableInstruction of(Instruction instruction) {
|
public static ImmutableInstruction of(Instruction instruction) {
|
||||||
if (instruction instanceof ImmutableInstruction) {
|
if (instruction instanceof ImmutableInstruction) {
|
||||||
return (ImmutableInstruction)instruction;
|
return (ImmutableInstruction)instruction;
|
||||||
@ -107,9 +108,16 @@ public abstract class ImmutableInstruction implements Instruction {
|
|||||||
return ImmutableInstruction3rc.of((Instruction3rc)instruction);
|
return ImmutableInstruction3rc.of((Instruction3rc)instruction);
|
||||||
case Format51l:
|
case Format51l:
|
||||||
return ImmutableInstruction51l.of((Instruction51l)instruction);
|
return ImmutableInstruction51l.of((Instruction51l)instruction);
|
||||||
|
case PackedSwitchPayload:
|
||||||
|
return ImmutablePackedSwitchPayload.of((PackedSwitchPayload) instruction);
|
||||||
|
case SparseSwitchPayload:
|
||||||
|
return ImmutableSparseSwitchPayload.of((SparseSwitchPayload) instruction);
|
||||||
|
case ArrayPayload:
|
||||||
|
return ImmutableArrayPayload.of((ArrayPayload) instruction);
|
||||||
|
//TODO: temporary, until we get all instructions implemented
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unexpected instruction type");
|
||||||
}
|
}
|
||||||
//TODO: temporary, until we get all instructions implemented
|
|
||||||
throw new RuntimeException("Unexpected instruction type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Opcode getOpcode() {
|
public Opcode getOpcode() {
|
||||||
@ -118,6 +126,10 @@ public abstract class ImmutableInstruction implements Instruction {
|
|||||||
|
|
||||||
public abstract Format getFormat();
|
public abstract Format getFormat();
|
||||||
|
|
||||||
|
public int getCodeUnits() {
|
||||||
|
return getFormat().size * 2;
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static ImmutableList<ImmutableInstruction> immutableListOf(List<? extends Instruction> list) {
|
public static ImmutableList<ImmutableInstruction> immutableListOf(List<? extends Instruction> list) {
|
||||||
return CONVERTER.convert(list);
|
return CONVERTER.convert(list);
|
||||||
@ -130,6 +142,7 @@ public abstract class ImmutableInstruction implements Instruction {
|
|||||||
return item instanceof ImmutableInstruction;
|
return item instanceof ImmutableInstruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
protected ImmutableInstruction makeImmutable(Instruction item) {
|
protected ImmutableInstruction makeImmutable(Instruction item) {
|
||||||
return ImmutableInstruction.of(item);
|
return ImmutableInstruction.of(item);
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* 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.immutable.instruction;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import org.jf.dexlib2.Format;
|
||||||
|
import org.jf.dexlib2.Opcode;
|
||||||
|
import org.jf.dexlib2.iface.instruction.SwitchElement;
|
||||||
|
import org.jf.dexlib2.iface.instruction.formats.PackedSwitchPayload;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImmutablePackedSwitchPayload extends ImmutableInstruction implements PackedSwitchPayload {
|
||||||
|
public static final Opcode OPCODE = Opcode.PACKED_SWITCH_PAYLOAD;
|
||||||
|
|
||||||
|
@Nonnull public final ImmutableList<? extends ImmutableSwitchElement> switchElements;
|
||||||
|
|
||||||
|
public ImmutablePackedSwitchPayload(@Nullable List<? extends SwitchElement> switchElements) {
|
||||||
|
super(OPCODE);
|
||||||
|
//TODO: need to validate that the keys are sequential
|
||||||
|
this.switchElements = ImmutableSwitchElement.immutableListOf(switchElements);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmutablePackedSwitchPayload(
|
||||||
|
@Nullable ImmutableList<? extends ImmutableSwitchElement> switchElements) {
|
||||||
|
super(OPCODE);
|
||||||
|
this.switchElements = Objects.firstNonNull(switchElements, ImmutableList.<ImmutableSwitchElement>of());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static ImmutablePackedSwitchPayload of(PackedSwitchPayload instruction) {
|
||||||
|
if (instruction instanceof ImmutablePackedSwitchPayload) {
|
||||||
|
return (ImmutablePackedSwitchPayload)instruction;
|
||||||
|
}
|
||||||
|
return new ImmutablePackedSwitchPayload(
|
||||||
|
instruction.getSwitchElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull @Override public List<? extends SwitchElement> getSwitchElements() { return switchElements; }
|
||||||
|
|
||||||
|
@Override public int getCodeUnits() { return 4 + switchElements.size() * 2; }
|
||||||
|
@Override public Format getFormat() { return OPCODE.format; }
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* 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.immutable.instruction;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import org.jf.dexlib2.Format;
|
||||||
|
import org.jf.dexlib2.Opcode;
|
||||||
|
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.Nullable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImmutableSparseSwitchPayload extends ImmutableInstruction implements SparseSwitchPayload {
|
||||||
|
public static final Opcode OPCODE = Opcode.SPARSE_SWITCH_PAYLOAD;
|
||||||
|
|
||||||
|
@Nonnull public final ImmutableList<? extends ImmutableSwitchElement> switchElements;
|
||||||
|
|
||||||
|
public ImmutableSparseSwitchPayload(@Nullable List<? extends SwitchElement> switchElements) {
|
||||||
|
super(OPCODE);
|
||||||
|
this.switchElements = ImmutableSwitchElement.immutableListOf(switchElements);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmutableSparseSwitchPayload(
|
||||||
|
@Nullable ImmutableList<? extends ImmutableSwitchElement> switchElements) {
|
||||||
|
super(OPCODE);
|
||||||
|
this.switchElements = Objects.firstNonNull(switchElements, ImmutableList.<ImmutableSwitchElement>of());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static ImmutableSparseSwitchPayload of(SparseSwitchPayload instruction) {
|
||||||
|
if (instruction instanceof ImmutableSparseSwitchPayload) {
|
||||||
|
return (ImmutableSparseSwitchPayload)instruction;
|
||||||
|
}
|
||||||
|
return new ImmutableSparseSwitchPayload(
|
||||||
|
instruction.getSwitchElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull @Override public List<? extends SwitchElement> getSwitchElements() { return switchElements; }
|
||||||
|
|
||||||
|
@Override public int getCodeUnits() { return 2 + switchElements.size() * 4; }
|
||||||
|
@Override public Format getFormat() { return OPCODE.format; }
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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.immutable.instruction;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import org.jf.dexlib2.iface.instruction.SwitchElement;
|
||||||
|
import org.jf.util.ImmutableListConverter;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImmutableSwitchElement implements SwitchElement {
|
||||||
|
public final int key;
|
||||||
|
public final int offset;
|
||||||
|
|
||||||
|
public ImmutableSwitchElement(int key,
|
||||||
|
int offset) {
|
||||||
|
this.key = key;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static ImmutableSwitchElement of(SwitchElement switchElement) {
|
||||||
|
if (switchElement instanceof ImmutableSwitchElement) {
|
||||||
|
return (ImmutableSwitchElement)switchElement;
|
||||||
|
}
|
||||||
|
return new ImmutableSwitchElement(
|
||||||
|
switchElement.getKey(),
|
||||||
|
switchElement.getOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getKey() { return key; }
|
||||||
|
@Override public int getOffset() { return offset; }
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static ImmutableList<ImmutableSwitchElement> immutableListOf(List<? extends SwitchElement> list) {
|
||||||
|
return CONVERTER.convert(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ImmutableListConverter<ImmutableSwitchElement, SwitchElement> CONVERTER =
|
||||||
|
new ImmutableListConverter<ImmutableSwitchElement, SwitchElement>() {
|
||||||
|
@Override
|
||||||
|
protected boolean isImmutable(SwitchElement item) {
|
||||||
|
return item instanceof ImmutableSwitchElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
protected ImmutableSwitchElement makeImmutable(SwitchElement item) {
|
||||||
|
return ImmutableSwitchElement.of(item);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user