Add art-specific opcodes and opcode values

This commit is contained in:
Ben Gruver 2015-07-12 12:52:57 -07:00
parent e5266afb14
commit 3ff884b1c3
23 changed files with 642 additions and 417 deletions

View File

@ -52,7 +52,7 @@ public class dump {
consoleWidth = 120;
}
RawDexFile rawDexFile = new RawDexFile(new Opcodes(apiLevel, experimental), dexFile);
RawDexFile rawDexFile = new RawDexFile(Opcodes.forApi(apiLevel), dexFile);
DexAnnotator annotator = new DexAnnotator(rawDexFile, consoleWidth);
annotator.writeAnnotations(writer);
} catch (IOException ex) {

View File

@ -81,7 +81,7 @@ public class DisassemblyTest {
String inputFilename = getInputFilename(testName);
byte[] inputBytes = BaksmaliTestUtils.readResourceBytesFully(getInputFilename(testName));
DexBackedDexFile inputDex = new DexBackedDexFile(new Opcodes(options.apiLevel, false), inputBytes);
DexBackedDexFile inputDex = new DexBackedDexFile(Opcodes.forApi(options.apiLevel), inputBytes);
Assert.assertEquals(1, inputDex.getClassCount());
ClassDef inputClass = Iterables.getFirst(inputDex.getClasses(), null);
Assert.assertNotNull(inputClass);

View File

@ -53,7 +53,7 @@ public final class DexFileFactory {
@Nonnull
public static DexBackedDexFile loadDexFile(String path, int api, boolean experimental)
throws IOException {
return loadDexFile(new File(path), "classes.dex", new Opcodes(api, experimental));
return loadDexFile(new File(path), "classes.dex", Opcodes.forApi(api, experimental));
}
@Nonnull
@ -64,13 +64,13 @@ public final class DexFileFactory {
@Nonnull
public static DexBackedDexFile loadDexFile(File dexFile, int api, boolean experimental)
throws IOException {
return loadDexFile(dexFile, "classes.dex", new Opcodes(api, experimental));
return loadDexFile(dexFile, "classes.dex", Opcodes.forApi(api, experimental));
}
@Nonnull
public static DexBackedDexFile loadDexFile(File dexFile, String dexEntry, int api,
boolean experimental) throws IOException {
return loadDexFile(dexFile, dexEntry, new Opcodes(api, experimental));
return loadDexFile(dexFile, dexEntry, Opcodes.forApi(api, experimental));
}
@Nonnull

View File

@ -31,271 +31,289 @@
package org.jf.dexlib2;
import com.google.common.collect.ImmutableRangeMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Range;
import com.google.common.collect.RangeMap;
import javax.annotation.Nonnull;
import java.util.List;
public enum Opcode
{
NOP((short)0x00, "nop", ReferenceType.NONE, Format.Format10x, Opcode.CAN_CONTINUE),
MOVE((short)0x01, "move", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_FROM16((short)0x02, "move/from16", ReferenceType.NONE, Format.Format22x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_16((short)0x03, "move/16", ReferenceType.NONE, Format.Format32x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_WIDE((short)0x04, "move-wide", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MOVE_WIDE_FROM16((short)0x05, "move-wide/from16", ReferenceType.NONE, Format.Format22x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MOVE_WIDE_16((short)0x06, "move-wide/16", ReferenceType.NONE, Format.Format32x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MOVE_OBJECT((short)0x07, "move-object", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_OBJECT_FROM16((short)0x08, "move-object/from16", ReferenceType.NONE, Format.Format22x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_OBJECT_16((short)0x09, "move-object/16", ReferenceType.NONE, Format.Format32x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_RESULT((short)0x0a, "move-result", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_RESULT_WIDE((short)0x0b, "move-result-wide", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MOVE_RESULT_OBJECT((short)0x0c, "move-result-object", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_EXCEPTION((short)0x0d, "move-exception", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
RETURN_VOID((short)0x0e, "return-void", ReferenceType.NONE, Format.Format10x),
RETURN((short)0x0f, "return", ReferenceType.NONE, Format.Format11x),
RETURN_WIDE((short)0x10, "return-wide", ReferenceType.NONE, Format.Format11x),
RETURN_OBJECT((short)0x11, "return-object", ReferenceType.NONE, Format.Format11x),
CONST_4((short)0x12, "const/4", ReferenceType.NONE, Format.Format11n, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CONST_16((short)0x13, "const/16", ReferenceType.NONE, Format.Format21s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CONST((short)0x14, "const", ReferenceType.NONE, Format.Format31i, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CONST_HIGH16((short)0x15, "const/high16", ReferenceType.NONE, Format.Format21ih, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CONST_WIDE_16((short)0x16, "const-wide/16", ReferenceType.NONE, Format.Format21s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
CONST_WIDE_32((short)0x17, "const-wide/32", ReferenceType.NONE, Format.Format31i, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
CONST_WIDE((short)0x18, "const-wide", ReferenceType.NONE, Format.Format51l, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
CONST_WIDE_HIGH16((short)0x19, "const-wide/high16", ReferenceType.NONE, Format.Format21lh, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
CONST_STRING((short)0x1a, "const-string", ReferenceType.STRING, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0x1b),
CONST_STRING_JUMBO((short)0x1b, "const-string/jumbo", ReferenceType.STRING, Format.Format31c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CONST_CLASS((short)0x1c, "const-class", ReferenceType.TYPE, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MONITOR_ENTER((short)0x1d, "monitor-enter", ReferenceType.NONE, Format.Format11x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
MONITOR_EXIT((short)0x1e, "monitor-exit", ReferenceType.NONE, Format.Format11x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
CHECK_CAST((short)0x1f, "check-cast", ReferenceType.TYPE, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
INSTANCE_OF((short)0x20, "instance-of", ReferenceType.TYPE, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ARRAY_LENGTH((short)0x21, "array-length", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
NEW_INSTANCE((short)0x22, "new-instance", ReferenceType.TYPE, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
NEW_ARRAY((short)0x23, "new-array", ReferenceType.TYPE, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
FILLED_NEW_ARRAY((short)0x24, "filled-new-array", ReferenceType.TYPE, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
FILLED_NEW_ARRAY_RANGE((short)0x25, "filled-new-array/range", ReferenceType.TYPE, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
FILL_ARRAY_DATA((short)0x26, "fill-array-data", ReferenceType.NONE, Format.Format31t, Opcode.CAN_CONTINUE),
THROW((short)0x27, "throw", ReferenceType.NONE, Format.Format11x, Opcode.CAN_THROW),
GOTO((short)0x28, "goto", ReferenceType.NONE, Format.Format10t),
GOTO_16((short)0x29, "goto/16", ReferenceType.NONE, Format.Format20t),
GOTO_32((short)0x2a, "goto/32", ReferenceType.NONE, Format.Format30t),
PACKED_SWITCH((short)0x2b, "packed-switch", ReferenceType.NONE, Format.Format31t, Opcode.CAN_CONTINUE),
SPARSE_SWITCH((short)0x2c, "sparse-switch", ReferenceType.NONE, Format.Format31t, Opcode.CAN_CONTINUE),
CMPL_FLOAT((short)0x2d, "cmpl-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CMPG_FLOAT((short)0x2e, "cmpg-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CMPL_DOUBLE((short)0x2f, "cmpl-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CMPG_DOUBLE((short)0x30, "cmpg-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CMP_LONG((short)0x31, "cmp-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IF_EQ((short)0x32, "if-eq", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_NE((short)0x33, "if-ne", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_LT((short)0x34, "if-lt", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_GE((short)0x35, "if-ge", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_GT((short)0x36, "if-gt", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_LE((short)0x37, "if-le", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_EQZ((short)0x38, "if-eqz", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
IF_NEZ((short)0x39, "if-nez", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
IF_LTZ((short)0x3a, "if-ltz", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
IF_GEZ((short)0x3b, "if-gez", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
IF_GTZ((short)0x3c, "if-gtz", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
IF_LEZ((short)0x3d, "if-lez", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
AGET((short)0x44, "aget", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AGET_WIDE((short)0x45, "aget-wide", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
AGET_OBJECT((short)0x46, "aget-object", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AGET_BOOLEAN((short)0x47, "aget-boolean", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AGET_BYTE((short)0x48, "aget-byte", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AGET_CHAR((short)0x49, "aget-char", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AGET_SHORT((short)0x4a, "aget-short", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
APUT((short)0x4b, "aput", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_WIDE((short)0x4c, "aput-wide", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_OBJECT((short)0x4d, "aput-object", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_BOOLEAN((short)0x4e, "aput-boolean", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_BYTE((short)0x4f, "aput-byte", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_CHAR((short)0x50, "aput-char", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_SHORT((short)0x51, "aput-short", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IGET((short)0x52, "iget", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_WIDE((short)0x53, "iget-wide", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
IGET_OBJECT((short)0x54, "iget-object", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_BOOLEAN((short)0x55, "iget-boolean", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_BYTE((short)0x56, "iget-byte", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_CHAR((short)0x57, "iget-char", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_SHORT((short)0x58, "iget-short", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IPUT((short)0x59, "iput", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_WIDE((short)0x5a, "iput-wide", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_OBJECT((short)0x5b, "iput-object", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_BOOLEAN((short)0x5c, "iput-boolean", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_BYTE((short)0x5d, "iput-byte", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_CHAR((short)0x5e, "iput-char", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_SHORT((short)0x5f, "iput-short", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SGET((short)0x60, "sget", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SGET_WIDE((short)0x61, "sget-wide", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SGET_OBJECT((short)0x62, "sget-object", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SGET_BOOLEAN((short)0x63, "sget-boolean", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SGET_BYTE((short)0x64, "sget-byte", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SGET_CHAR((short)0x65, "sget-char", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SGET_SHORT((short)0x66, "sget-short", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SPUT((short)0x67, "sput", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_WIDE((short)0x68, "sput-wide", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_OBJECT((short)0x69, "sput-object", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_BOOLEAN((short)0x6a, "sput-boolean", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_BYTE((short)0x6b, "sput-byte", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_CHAR((short)0x6c, "sput-char", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_SHORT((short)0x6d, "sput-short", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
INVOKE_VIRTUAL((short)0x6e, "invoke-virtual", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_SUPER((short)0x6f, "invoke-super", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_DIRECT((short)0x70, "invoke-direct", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
INVOKE_STATIC((short)0x71, "invoke-static", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_INTERFACE((short)0x72, "invoke-interface", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_VIRTUAL_RANGE((short)0x74, "invoke-virtual/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_SUPER_RANGE((short)0x75, "invoke-super/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_DIRECT_RANGE((short)0x76, "invoke-direct/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
INVOKE_STATIC_RANGE((short)0x77, "invoke-static/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_INTERFACE_RANGE((short)0x78, "invoke-interface/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
NEG_INT((short)0x7b, "neg-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
NOT_INT((short)0x7c, "not-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
NEG_LONG((short)0x7d, "neg-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
NOT_LONG((short)0x7e, "not-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
NEG_FLOAT((short)0x7f, "neg-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
NEG_DOUBLE((short)0x80, "neg-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
INT_TO_LONG((short)0x81, "int-to-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
INT_TO_FLOAT((short)0x82, "int-to-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
INT_TO_DOUBLE((short)0x83, "int-to-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
LONG_TO_INT((short)0x84, "long-to-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
LONG_TO_FLOAT((short)0x85, "long-to-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
LONG_TO_DOUBLE((short)0x86, "long-to-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
FLOAT_TO_INT((short)0x87, "float-to-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
FLOAT_TO_LONG((short)0x88, "float-to-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
FLOAT_TO_DOUBLE((short)0x89, "float-to-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DOUBLE_TO_INT((short)0x8a, "double-to-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DOUBLE_TO_LONG((short)0x8b, "double-to-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DOUBLE_TO_FLOAT((short)0x8c, "double-to-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
INT_TO_BYTE((short)0x8d, "int-to-byte", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
INT_TO_CHAR((short)0x8e, "int-to-char", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
INT_TO_SHORT((short)0x8f, "int-to-short", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_INT((short)0x90, "add-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SUB_INT((short)0x91, "sub-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_INT((short)0x92, "mul-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_INT((short)0x93, "div-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_INT((short)0x94, "rem-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AND_INT((short)0x95, "and-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
OR_INT((short)0x96, "or-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
XOR_INT((short)0x97, "xor-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHL_INT((short)0x98, "shl-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHR_INT((short)0x99, "shr-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
USHR_INT((short)0x9a, "ushr-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_LONG((short)0x9b, "add-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SUB_LONG((short)0x9c, "sub-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MUL_LONG((short)0x9d, "mul-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DIV_LONG((short)0x9e, "div-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
REM_LONG((short)0x9f, "rem-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
AND_LONG((short)0xa0, "and-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
OR_LONG((short)0xa1, "or-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
XOR_LONG((short)0xa2, "xor-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SHL_LONG((short)0xa3, "shl-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SHR_LONG((short)0xa4, "shr-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
USHR_LONG((short)0xa5, "ushr-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
ADD_FLOAT((short)0xa6, "add-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SUB_FLOAT((short)0xa7, "sub-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_FLOAT((short)0xa8, "mul-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_FLOAT((short)0xa9, "div-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_FLOAT((short)0xaa, "rem-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_DOUBLE((short)0xab, "add-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SUB_DOUBLE((short)0xac, "sub-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MUL_DOUBLE((short)0xad, "mul-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DIV_DOUBLE((short)0xae, "div-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
REM_DOUBLE((short)0xaf, "rem-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
ADD_INT_2ADDR((short)0xb0, "add-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SUB_INT_2ADDR((short)0xb1, "sub-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_INT_2ADDR((short)0xb2, "mul-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_INT_2ADDR((short)0xb3, "div-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_INT_2ADDR((short)0xb4, "rem-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AND_INT_2ADDR((short)0xb5, "and-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
OR_INT_2ADDR((short)0xb6, "or-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
XOR_INT_2ADDR((short)0xb7, "xor-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHL_INT_2ADDR((short)0xb8, "shl-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHR_INT_2ADDR((short)0xb9, "shr-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
USHR_INT_2ADDR((short)0xba, "ushr-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_LONG_2ADDR((short)0xbb, "add-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SUB_LONG_2ADDR((short)0xbc, "sub-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MUL_LONG_2ADDR((short)0xbd, "mul-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DIV_LONG_2ADDR((short)0xbe, "div-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
REM_LONG_2ADDR((short)0xbf, "rem-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
AND_LONG_2ADDR((short)0xc0, "and-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
OR_LONG_2ADDR((short)0xc1, "or-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
XOR_LONG_2ADDR((short)0xc2, "xor-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SHL_LONG_2ADDR((short)0xc3, "shl-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SHR_LONG_2ADDR((short)0xc4, "shr-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
USHR_LONG_2ADDR((short)0xc5, "ushr-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
ADD_FLOAT_2ADDR((short)0xc6, "add-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SUB_FLOAT_2ADDR((short)0xc7, "sub-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_FLOAT_2ADDR((short)0xc8, "mul-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_FLOAT_2ADDR((short)0xc9, "div-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_FLOAT_2ADDR((short)0xca, "rem-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_DOUBLE_2ADDR((short)0xcb, "add-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SUB_DOUBLE_2ADDR((short)0xcc, "sub-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MUL_DOUBLE_2ADDR((short)0xcd, "mul-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DIV_DOUBLE_2ADDR((short)0xce, "div-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
REM_DOUBLE_2ADDR((short)0xcf, "rem-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
ADD_INT_LIT16((short)0xd0, "add-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
RSUB_INT((short)0xd1, "rsub-int", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_INT_LIT16((short)0xd2, "mul-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_INT_LIT16((short)0xd3, "div-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_INT_LIT16((short)0xd4, "rem-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AND_INT_LIT16((short)0xd5, "and-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
OR_INT_LIT16((short)0xd6, "or-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
XOR_INT_LIT16((short)0xd7, "xor-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_INT_LIT8((short)0xd8, "add-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
RSUB_INT_LIT8((short)0xd9, "rsub-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_INT_LIT8((short)0xda, "mul-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_INT_LIT8((short)0xdb, "div-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_INT_LIT8((short)0xdc, "rem-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AND_INT_LIT8((short)0xdd, "and-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
OR_INT_LIT8((short)0xde, "or-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
XOR_INT_LIT8((short)0xdf, "xor-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHL_INT_LIT8((short)0xe0, "shl-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHR_INT_LIT8((short)0xe1, "shr-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
USHR_INT_LIT8((short)0xe2, "ushr-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
NOP(0x00, "nop", ReferenceType.NONE, Format.Format10x, Opcode.CAN_CONTINUE),
MOVE(0x01, "move", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_FROM16(0x02, "move/from16", ReferenceType.NONE, Format.Format22x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_16(0x03, "move/16", ReferenceType.NONE, Format.Format32x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_WIDE(0x04, "move-wide", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MOVE_WIDE_FROM16(0x05, "move-wide/from16", ReferenceType.NONE, Format.Format22x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MOVE_WIDE_16(0x06, "move-wide/16", ReferenceType.NONE, Format.Format32x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MOVE_OBJECT(0x07, "move-object", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_OBJECT_FROM16(0x08, "move-object/from16", ReferenceType.NONE, Format.Format22x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_OBJECT_16(0x09, "move-object/16", ReferenceType.NONE, Format.Format32x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_RESULT(0x0a, "move-result", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_RESULT_WIDE(0x0b, "move-result-wide", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MOVE_RESULT_OBJECT(0x0c, "move-result-object", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MOVE_EXCEPTION(0x0d, "move-exception", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
RETURN_VOID(0x0e, "return-void", ReferenceType.NONE, Format.Format10x),
RETURN(0x0f, "return", ReferenceType.NONE, Format.Format11x),
RETURN_WIDE(0x10, "return-wide", ReferenceType.NONE, Format.Format11x),
RETURN_OBJECT(0x11, "return-object", ReferenceType.NONE, Format.Format11x),
CONST_4(0x12, "const/4", ReferenceType.NONE, Format.Format11n, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CONST_16(0x13, "const/16", ReferenceType.NONE, Format.Format21s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CONST(0x14, "const", ReferenceType.NONE, Format.Format31i, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CONST_HIGH16(0x15, "const/high16", ReferenceType.NONE, Format.Format21ih, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CONST_WIDE_16(0x16, "const-wide/16", ReferenceType.NONE, Format.Format21s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
CONST_WIDE_32(0x17, "const-wide/32", ReferenceType.NONE, Format.Format31i, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
CONST_WIDE(0x18, "const-wide", ReferenceType.NONE, Format.Format51l, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
CONST_WIDE_HIGH16(0x19, "const-wide/high16", ReferenceType.NONE, Format.Format21lh, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
CONST_STRING(0x1a, "const-string", ReferenceType.STRING, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CONST_STRING_JUMBO(0x1b, "const-string/jumbo", ReferenceType.STRING, Format.Format31c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CONST_CLASS(0x1c, "const-class", ReferenceType.TYPE, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MONITOR_ENTER(0x1d, "monitor-enter", ReferenceType.NONE, Format.Format11x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
MONITOR_EXIT(0x1e, "monitor-exit", ReferenceType.NONE, Format.Format11x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
CHECK_CAST(0x1f, "check-cast", ReferenceType.TYPE, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
INSTANCE_OF(0x20, "instance-of", ReferenceType.TYPE, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ARRAY_LENGTH(0x21, "array-length", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
NEW_INSTANCE(0x22, "new-instance", ReferenceType.TYPE, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
NEW_ARRAY(0x23, "new-array", ReferenceType.TYPE, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
FILLED_NEW_ARRAY(0x24, "filled-new-array", ReferenceType.TYPE, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
FILLED_NEW_ARRAY_RANGE(0x25, "filled-new-array/range", ReferenceType.TYPE, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
FILL_ARRAY_DATA(0x26, "fill-array-data", ReferenceType.NONE, Format.Format31t, Opcode.CAN_CONTINUE),
THROW(0x27, "throw", ReferenceType.NONE, Format.Format11x, Opcode.CAN_THROW),
GOTO(0x28, "goto", ReferenceType.NONE, Format.Format10t),
GOTO_16(0x29, "goto/16", ReferenceType.NONE, Format.Format20t),
GOTO_32(0x2a, "goto/32", ReferenceType.NONE, Format.Format30t),
PACKED_SWITCH(0x2b, "packed-switch", ReferenceType.NONE, Format.Format31t, Opcode.CAN_CONTINUE),
SPARSE_SWITCH(0x2c, "sparse-switch", ReferenceType.NONE, Format.Format31t, Opcode.CAN_CONTINUE),
CMPL_FLOAT(0x2d, "cmpl-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CMPG_FLOAT(0x2e, "cmpg-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CMPL_DOUBLE(0x2f, "cmpl-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CMPG_DOUBLE(0x30, "cmpg-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
CMP_LONG(0x31, "cmp-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IF_EQ(0x32, "if-eq", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_NE(0x33, "if-ne", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_LT(0x34, "if-lt", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_GE(0x35, "if-ge", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_GT(0x36, "if-gt", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_LE(0x37, "if-le", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
IF_EQZ(0x38, "if-eqz", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
IF_NEZ(0x39, "if-nez", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
IF_LTZ(0x3a, "if-ltz", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
IF_GEZ(0x3b, "if-gez", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
IF_GTZ(0x3c, "if-gtz", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
IF_LEZ(0x3d, "if-lez", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
AGET(0x44, "aget", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AGET_WIDE(0x45, "aget-wide", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
AGET_OBJECT(0x46, "aget-object", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AGET_BOOLEAN(0x47, "aget-boolean", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AGET_BYTE(0x48, "aget-byte", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AGET_CHAR(0x49, "aget-char", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AGET_SHORT(0x4a, "aget-short", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
APUT(0x4b, "aput", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_WIDE(0x4c, "aput-wide", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_OBJECT(0x4d, "aput-object", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_BOOLEAN(0x4e, "aput-boolean", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_BYTE(0x4f, "aput-byte", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_CHAR(0x50, "aput-char", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
APUT_SHORT(0x51, "aput-short", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IGET(0x52, "iget", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_WIDE(0x53, "iget-wide", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
IGET_OBJECT(0x54, "iget-object", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_BOOLEAN(0x55, "iget-boolean", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_BYTE(0x56, "iget-byte", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_CHAR(0x57, "iget-char", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_SHORT(0x58, "iget-short", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IPUT(0x59, "iput", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_WIDE(0x5a, "iput-wide", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_OBJECT(0x5b, "iput-object", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_BOOLEAN(0x5c, "iput-boolean", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_BYTE(0x5d, "iput-byte", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_CHAR(0x5e, "iput-char", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_SHORT(0x5f, "iput-short", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SGET(0x60, "sget", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SGET_WIDE(0x61, "sget-wide", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SGET_OBJECT(0x62, "sget-object", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SGET_BOOLEAN(0x63, "sget-boolean", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SGET_BYTE(0x64, "sget-byte", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SGET_CHAR(0x65, "sget-char", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SGET_SHORT(0x66, "sget-short", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SPUT(0x67, "sput", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_WIDE(0x68, "sput-wide", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_OBJECT(0x69, "sput-object", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_BOOLEAN(0x6a, "sput-boolean", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_BYTE(0x6b, "sput-byte", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_CHAR(0x6c, "sput-char", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SPUT_SHORT(0x6d, "sput-short", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
INVOKE_VIRTUAL(0x6e, "invoke-virtual", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_SUPER(0x6f, "invoke-super", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_DIRECT(0x70, "invoke-direct", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
INVOKE_STATIC(0x71, "invoke-static", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_INTERFACE(0x72, "invoke-interface", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_VIRTUAL_RANGE(0x74, "invoke-virtual/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_SUPER_RANGE(0x75, "invoke-super/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_DIRECT_RANGE(0x76, "invoke-direct/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
INVOKE_STATIC_RANGE(0x77, "invoke-static/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_INTERFACE_RANGE(0x78, "invoke-interface/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
NEG_INT(0x7b, "neg-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
NOT_INT(0x7c, "not-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
NEG_LONG(0x7d, "neg-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
NOT_LONG(0x7e, "not-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
NEG_FLOAT(0x7f, "neg-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
NEG_DOUBLE(0x80, "neg-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
INT_TO_LONG(0x81, "int-to-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
INT_TO_FLOAT(0x82, "int-to-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
INT_TO_DOUBLE(0x83, "int-to-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
LONG_TO_INT(0x84, "long-to-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
LONG_TO_FLOAT(0x85, "long-to-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
LONG_TO_DOUBLE(0x86, "long-to-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
FLOAT_TO_INT(0x87, "float-to-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
FLOAT_TO_LONG(0x88, "float-to-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
FLOAT_TO_DOUBLE(0x89, "float-to-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DOUBLE_TO_INT(0x8a, "double-to-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DOUBLE_TO_LONG(0x8b, "double-to-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DOUBLE_TO_FLOAT(0x8c, "double-to-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
INT_TO_BYTE(0x8d, "int-to-byte", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
INT_TO_CHAR(0x8e, "int-to-char", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
INT_TO_SHORT(0x8f, "int-to-short", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_INT(0x90, "add-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SUB_INT(0x91, "sub-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_INT(0x92, "mul-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_INT(0x93, "div-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_INT(0x94, "rem-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AND_INT(0x95, "and-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
OR_INT(0x96, "or-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
XOR_INT(0x97, "xor-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHL_INT(0x98, "shl-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHR_INT(0x99, "shr-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
USHR_INT(0x9a, "ushr-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_LONG(0x9b, "add-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SUB_LONG(0x9c, "sub-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MUL_LONG(0x9d, "mul-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DIV_LONG(0x9e, "div-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
REM_LONG(0x9f, "rem-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
AND_LONG(0xa0, "and-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
OR_LONG(0xa1, "or-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
XOR_LONG(0xa2, "xor-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SHL_LONG(0xa3, "shl-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SHR_LONG(0xa4, "shr-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
USHR_LONG(0xa5, "ushr-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
ADD_FLOAT(0xa6, "add-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SUB_FLOAT(0xa7, "sub-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_FLOAT(0xa8, "mul-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_FLOAT(0xa9, "div-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_FLOAT(0xaa, "rem-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_DOUBLE(0xab, "add-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SUB_DOUBLE(0xac, "sub-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MUL_DOUBLE(0xad, "mul-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DIV_DOUBLE(0xae, "div-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
REM_DOUBLE(0xaf, "rem-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
ADD_INT_2ADDR(0xb0, "add-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SUB_INT_2ADDR(0xb1, "sub-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_INT_2ADDR(0xb2, "mul-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_INT_2ADDR(0xb3, "div-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_INT_2ADDR(0xb4, "rem-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AND_INT_2ADDR(0xb5, "and-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
OR_INT_2ADDR(0xb6, "or-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
XOR_INT_2ADDR(0xb7, "xor-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHL_INT_2ADDR(0xb8, "shl-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHR_INT_2ADDR(0xb9, "shr-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
USHR_INT_2ADDR(0xba, "ushr-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_LONG_2ADDR(0xbb, "add-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SUB_LONG_2ADDR(0xbc, "sub-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MUL_LONG_2ADDR(0xbd, "mul-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DIV_LONG_2ADDR(0xbe, "div-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
REM_LONG_2ADDR(0xbf, "rem-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
AND_LONG_2ADDR(0xc0, "and-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
OR_LONG_2ADDR(0xc1, "or-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
XOR_LONG_2ADDR(0xc2, "xor-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SHL_LONG_2ADDR(0xc3, "shl-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SHR_LONG_2ADDR(0xc4, "shr-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
USHR_LONG_2ADDR(0xc5, "ushr-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
ADD_FLOAT_2ADDR(0xc6, "add-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SUB_FLOAT_2ADDR(0xc7, "sub-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_FLOAT_2ADDR(0xc8, "mul-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_FLOAT_2ADDR(0xc9, "div-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_FLOAT_2ADDR(0xca, "rem-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_DOUBLE_2ADDR(0xcb, "add-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SUB_DOUBLE_2ADDR(0xcc, "sub-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
MUL_DOUBLE_2ADDR(0xcd, "mul-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
DIV_DOUBLE_2ADDR(0xce, "div-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
REM_DOUBLE_2ADDR(0xcf, "rem-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
ADD_INT_LIT16(0xd0, "add-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
RSUB_INT(0xd1, "rsub-int", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_INT_LIT16(0xd2, "mul-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_INT_LIT16(0xd3, "div-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_INT_LIT16(0xd4, "rem-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AND_INT_LIT16(0xd5, "and-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
OR_INT_LIT16(0xd6, "or-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
XOR_INT_LIT16(0xd7, "xor-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
ADD_INT_LIT8(0xd8, "add-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
RSUB_INT_LIT8(0xd9, "rsub-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
MUL_INT_LIT8(0xda, "mul-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
DIV_INT_LIT8(0xdb, "div-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
REM_INT_LIT8(0xdc, "rem-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
AND_INT_LIT8(0xdd, "and-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
OR_INT_LIT8(0xde, "or-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
XOR_INT_LIT8(0xdf, "xor-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHL_INT_LIT8(0xe0, "shl-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SHR_INT_LIT8(0xe1, "shr-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
USHR_INT_LIT8(0xe2, "ushr-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_VOLATILE((short)0xe3, "iget-volatile", minApi(9), ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IPUT_VOLATILE((short)0xe4, "iput-volatile", minApi(9), ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SGET_VOLATILE((short)0xe5, "sget-volatile", minApi(9), ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SPUT_VOLATILE((short)0xe6, "sput-volatile", minApi(9), ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IGET_OBJECT_VOLATILE((short)0xe7, "iget-object-volatile", minApi(9), ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_WIDE_VOLATILE((short)0xe8, "iget-wide-volatile", minApi(9), ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
IPUT_WIDE_VOLATILE((short)0xe9, "iput-wide-volatile", minApi(9), ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SGET_WIDE_VOLATILE((short)0xea, "sget-wide-volatile", minApi(9), ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SPUT_WIDE_VOLATILE((short)0xeb, "sput-wide-volatile", minApi(9), ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IGET_VOLATILE(firstApi(0xe3, 9), "iget-volatile", ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IPUT_VOLATILE(firstApi(0xe4, 9), "iput-volatile", ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SGET_VOLATILE(firstApi(0xe5, 9), "sget-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
SPUT_VOLATILE(firstApi(0xe6, 9), "sput-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IGET_OBJECT_VOLATILE(firstApi(0xe7, 9), "iget-object-volatile", ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_WIDE_VOLATILE(firstApi(0xe8, 9), "iget-wide-volatile", ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
IPUT_WIDE_VOLATILE(firstApi(0xe9, 9), "iput-wide-volatile", ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SGET_WIDE_VOLATILE(firstApi(0xea, 9), "sget-wide-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
SPUT_WIDE_VOLATILE(firstApi(0xeb, 9), "sput-wide-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
THROW_VERIFICATION_ERROR((short)0xed, "throw-verification-error", minApi(5), ReferenceType.NONE, Format.Format20bc, Opcode.ODEX_ONLY | Opcode.CAN_THROW),
EXECUTE_INLINE((short)0xee, "execute-inline", ReferenceType.NONE, Format.Format35mi, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
EXECUTE_INLINE_RANGE((short)0xef, "execute-inline/range", minApi(8), ReferenceType.NONE, Format.Format3rmi, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_DIRECT_EMPTY((short)0xf0, "invoke-direct-empty", maxApi(13), ReferenceType.METHOD, Format.Format35c, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
INVOKE_OBJECT_INIT_RANGE((short)0xf0, "invoke-object-init/range", minApi(14), ReferenceType.METHOD, Format.Format3rc, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
RETURN_VOID_BARRIER((short)0xf1, "return-void-barrier", minApi(11), ReferenceType.NONE, Format.Format10x, Opcode.ODEX_ONLY),
IGET_QUICK((short)0xf2, "iget-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_WIDE_QUICK((short)0xf3, "iget-wide-quick", maxApi(22), ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
IGET_OBJECT_QUICK((short)0xf4, "iget-object-quick", maxApi(22), ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IPUT_QUICK((short)0xf5, "iput-quick", maxApi(22), ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_WIDE_QUICK((short)0xf6, "iput-wide-quick", maxApi(22), ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_OBJECT_QUICK((short)0xf7, "iput-object-quick", maxApi(22), ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
INVOKE_VIRTUAL_QUICK((short)0xf8, "invoke-virtual-quick", maxApi(22), ReferenceType.NONE, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_VIRTUAL_QUICK_RANGE((short)0xf9, "invoke-virtual-quick/range", maxApi(22), ReferenceType.NONE, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_SUPER_QUICK((short)0xfa, "invoke-super-quick", ReferenceType.NONE, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_SUPER_QUICK_RANGE((short)0xfb, "invoke-super-quick/range", ReferenceType.NONE, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
THROW_VERIFICATION_ERROR(firstApi(0xed, 5), "throw-verification-error", ReferenceType.NONE, Format.Format20bc, Opcode.ODEX_ONLY | Opcode.CAN_THROW),
EXECUTE_INLINE(allApis(0xee), "execute-inline", ReferenceType.NONE, Format.Format35mi, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
EXECUTE_INLINE_RANGE(firstApi(0xef, 8), "execute-inline/range", ReferenceType.NONE, Format.Format3rmi, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_DIRECT_EMPTY(lastApi(0xf0, 13), "invoke-direct-empty", ReferenceType.METHOD, Format.Format35c, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
INVOKE_OBJECT_INIT_RANGE(firstApi(0xf0, 14), "invoke-object-init/range", ReferenceType.METHOD, Format.Format3rc, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
RETURN_VOID_BARRIER(combine(firstApi(0xf1, 11), lastArtVersion(0x73, 59)), "return-void-barrier", ReferenceType.NONE, Format.Format10x, Opcode.ODEX_ONLY),
RETURN_VOID_NO_BARRIER(firstArtVersion(0x73, 60), "return-void-no-barrier", ReferenceType.NONE, Format.Format10x, Opcode.ODEX_ONLY),
IGET_QUICK(combine(allApis(0xf2), allArtVersions(0xe3)), "iget-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_WIDE_QUICK(combine(allApis(0xf3), allArtVersions(0xe4)), "iget-wide-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
IGET_OBJECT_QUICK(combine(allApis(0xf4), allArtVersions(0xe5)), "iget-object-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IPUT_QUICK(combine(allApis(0xf5), allArtVersions(0xe6)), "iput-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_WIDE_QUICK(combine(allApis(0xf6), allArtVersions(0xe7)), "iput-wide-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_OBJECT_QUICK(combine(allApis(0xf7), allArtVersions(0xe8)), "iput-object-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_BOOLEAN_QUICK(allArtVersions(0xeb), "iput-boolean-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.ODEXED_INSTANCE_QUICK),
IPUT_BYTE_QUICK(allArtVersions(0xec), "iput-byte-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.ODEXED_INSTANCE_QUICK),
IPUT_CHAR_QUICK(allArtVersions(0xed), "iput-char-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.ODEXED_INSTANCE_QUICK),
IPUT_SHORT_QUICK(allArtVersions(0xee), "iput-short-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.ODEXED_INSTANCE_QUICK),
IGET_BOOLEAN_QUICK(allArtVersions(0xef), "iget-boolean-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_BYTE_QUICK(allArtVersions(0xf0), "iget-byte-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_CHAR_QUICK(allArtVersions(0xf1), "iget-char-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
IGET_SHORT_QUICK(allArtVersions(0xf2), "iget-short-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
INVOKE_VIRTUAL_QUICK(combine(allApis(0xf8), allArtVersions(0xe9)), "invoke-virtual-quick", ReferenceType.NONE, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_VIRTUAL_QUICK_RANGE(combine(allApis(0xf9), allArtVersions(0xea)), "invoke-virtual-quick/range", ReferenceType.NONE, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_SUPER_QUICK(allApis(0xfa), "invoke-super-quick", ReferenceType.NONE, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
INVOKE_SUPER_QUICK_RANGE(allApis(0xfb), "invoke-super-quick/range", ReferenceType.NONE, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
IPUT_OBJECT_VOLATILE((short)0xfc, "iput-object-volatile", minApi(9), 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", minApi(9), 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", minApi(9), ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
IPUT_OBJECT_VOLATILE(firstApi(0xfc, 9), "iput-object-volatile", ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
SGET_OBJECT_VOLATILE(firstApi(0xfd, 9), "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(firstApi(0xfe, 9), "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),
PACKED_SWITCH_PAYLOAD(0x100, "packed-switch-payload", ReferenceType.NONE, Format.PackedSwitchPayload, 0),
SPARSE_SWITCH_PAYLOAD(0x200, "sparse-switch-payload", ReferenceType.NONE, Format.SparseSwitchPayload, 0),
ARRAY_PAYLOAD(0x300, "array-payload", ReferenceType.NONE, Format.ArrayPayload, 0),
// Reuse the deprecated f3-ff opcodes in Art:
INVOKE_LAMBDA((short)0xf3, "invoke-lambda", minApi(23), ReferenceType.NONE, Format.Format25x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.EXPERIMENTAL),
INVOKE_LAMBDA(allArtVersions(0xf3),"invoke-lambda", ReferenceType.NONE, Format.Format25x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.EXPERIMENTAL),
// TODO: What about JUMBO support if the string ID is too large?
CAPTURE_VARIABLE((short)0xf5, "capture-variable", minApi(23), ReferenceType.STRING, Format.Format21c, Opcode.EXPERIMENTAL),
CREATE_LAMBDA((short)0xf6, "create-lambda", minApi(23), ReferenceType.METHOD, Format.Format21c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL),
CAPTURE_VARIABLE(allArtVersions(0xf5), "capture-variable", ReferenceType.STRING, Format.Format21c, Opcode.EXPERIMENTAL),
CREATE_LAMBDA(allArtVersions(0xf6), "create-lambda", ReferenceType.METHOD, Format.Format21c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL),
// TODO: do we need a capture/liberate wide?
LIBERATE_VARIABLE((short)0xf7, "liberate-variable", minApi(23), ReferenceType.STRING, Format.Format22c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL),
BOX_LAMBDA((short)0xf8, "box-lambda", minApi(23), ReferenceType.NONE, Format.Format22x, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL),
UNBOX_LAMBDA((short)0xf9, "unbox-lambda", minApi(23), ReferenceType.TYPE, Format.Format22c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL);
LIBERATE_VARIABLE(allArtVersions(0xf7), "liberate-variable", ReferenceType.STRING, Format.Format22c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL),
BOX_LAMBDA(allArtVersions(0xf8), "box-lambda", ReferenceType.NONE, Format.Format22x, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL),
UNBOX_LAMBDA(allArtVersions(0xf9), "unbox-lambda", ReferenceType.TYPE, Format.Format22c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL);
//if the instruction can throw an exception
public static final int CAN_THROW = 0x1;
@ -332,58 +350,81 @@ public enum Opcode
return api << 16;
}
public final short value;
// values and minApis provide a mapping of api -> bytecode value.
// the apis in minApis are guaranteed to be
public final RangeMap<Integer, Short> apiToValueMap;
public final RangeMap<Integer, Short> artVersionToValueMap;
public final String name;
// high 16-bits is the max api, low 16-bits is the min api
public final int apiConstraints;
public final int referenceType;
public final Format format;
public final int flags;
Opcode(short opcodeValue, String opcodeName, int referenceType, Format format) {
this(opcodeValue, opcodeName, ALL_APIS, referenceType, format, 0, (short)-1);
Opcode(int opcodeValue, String opcodeName, int referenceType, Format format) {
this(opcodeValue, opcodeName, referenceType, format, 0);
}
Opcode(short opcodeValue, String opcodeName, int referenceType, Format format, int flags) {
this(opcodeValue, opcodeName, ALL_APIS, referenceType, format, flags, (short)-1);
Opcode(int opcodeValue, String opcodeName, int referenceType, Format format, int flags) {
this(allVersions(opcodeValue), opcodeName, referenceType, format, flags);
}
Opcode(short opcodeValue, String opcodeName, int referenceType, Format format, int flags, short jumboOpcodeValue) {
this(opcodeValue, opcodeName, ALL_APIS, referenceType, format, flags, jumboOpcodeValue);
}
Opcode(List<VersionConstraint> versionConstraints, String opcodeName, int referenceType, Format format, int flags) {
ImmutableRangeMap.Builder<Integer, Short> apiToValueBuilder = ImmutableRangeMap.builder();
ImmutableRangeMap.Builder<Integer, Short> artVersionToValueBuilder = ImmutableRangeMap.builder();
Opcode(short opcodeValue, String opcodeName, int apiConstraints, int referenceType, Format format) {
this(opcodeValue, opcodeName, apiConstraints, referenceType, format, 0, (short)-1);
}
for (VersionConstraint versionConstraint : versionConstraints) {
if (!versionConstraint.apiRange.isEmpty()) {
apiToValueBuilder.put(versionConstraint.apiRange, (short)versionConstraint.opcodeValue);
}
if (!versionConstraint.artVersionRange.isEmpty()) {
artVersionToValueBuilder.put(versionConstraint.artVersionRange, (short)versionConstraint.opcodeValue);
}
}
Opcode(short opcodeValue, String opcodeName, int apiConstraints, int referenceType, Format format, int flags) {
this(opcodeValue, opcodeName, apiConstraints, referenceType, format, flags, (short)-1);
}
Opcode(short opcodeValue, String opcodeName, int apiConstraints, int referenceType, Format format, int flags,
short jumboOpcodeValue) {
this.value = opcodeValue;
this.apiToValueMap = apiToValueBuilder.build();
this.artVersionToValueMap = artVersionToValueBuilder.build();
this.name = opcodeName;
this.apiConstraints = apiConstraints;
this.referenceType = referenceType;
this.format = format;
this.flags = flags;
// TODO: implement jumbo opcodes for dexlib2 and uncomment
// this.jumboOpcode = jumboOpcodeValue;
}
/**
* @return the minimum api level that can use this opcode (inclusive)
*/
public int getMinApi() {
return apiConstraints & 0xFFFF;
private static List<VersionConstraint> firstApi(int opcodeValue, int api) {
return Lists.newArrayList(new VersionConstraint(Range.atLeast(api), Range.openClosed(0, 0), opcodeValue));
}
/**
* @return the maximum api level that can to use this opcode (inclusive)
*/
public int getMaxApi() {
return apiConstraints >>> 16;
private static List<VersionConstraint> lastApi(int opcodeValue, int api) {
Range range;
return Lists.newArrayList(new VersionConstraint(Range.atMost(api), Range.openClosed(0, 0), opcodeValue));
}
private static List<VersionConstraint> firstArtVersion(int opcodeValue, int artVersion) {
return Lists.newArrayList(new VersionConstraint(Range.openClosed(0, 0), Range.atLeast(artVersion), opcodeValue));
}
private static List<VersionConstraint> lastArtVersion(int opcodeValue, int artVersion) {
return Lists.newArrayList(new VersionConstraint(Range.openClosed(0, 0), Range.atMost(artVersion), opcodeValue));
}
private static List<VersionConstraint> allVersions(int opcodeValue) {
return Lists.newArrayList(new VersionConstraint(Range.<Integer>all(), Range.<Integer>all(), opcodeValue));
}
private static List<VersionConstraint> allApis(int opcodeValue) {
return Lists.newArrayList(new VersionConstraint(Range.<Integer>all(), Range.openClosed(0, 0), opcodeValue));
}
private static List<VersionConstraint> allArtVersions(int opcodeValue) {
return Lists.newArrayList(new VersionConstraint(Range.openClosed(0, 0), Range.<Integer>all(), opcodeValue));
}
@SuppressWarnings("unchecked")
private static List<VersionConstraint> combine(List<VersionConstraint>... versionConstraints) {
List<VersionConstraint> combinedList = Lists.newArrayList();
for (List<VersionConstraint> versionConstraintList: versionConstraints) {
combinedList.addAll(versionConstraintList);
}
return combinedList;
}
public final boolean canThrow() {
@ -433,4 +474,17 @@ public enum Opcode
public final boolean isExperimental() {
return (flags & EXPERIMENTAL) != 0;
}
private static class VersionConstraint {
@Nonnull public final Range<Integer> apiRange;
@Nonnull public final Range<Integer> artVersionRange;
public final int opcodeValue;
public VersionConstraint(@Nonnull Range<Integer> apiRange, @Nonnull Range<Integer> artVersionRange,
int opcodeValue) {
this.apiRange = apiRange;
this.artVersionRange = artVersionRange;
this.opcodeValue = opcodeValue;
}
}
}

View File

@ -32,35 +32,90 @@
package org.jf.dexlib2;
import com.google.common.collect.Maps;
import com.google.common.collect.RangeMap;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.EnumMap;
import java.util.HashMap;
public class Opcodes {
private final Opcode[] opcodesByValue;
private final HashMap<String, Opcode> opcodesByName;
/**
* Either the api level for dalvik opcodes, or the art version for art opcodes
*/
public final int api;
public final int artVersion;
@Nonnull private final Opcode[] opcodesByValue = new Opcode[255];
@Nonnull private final EnumMap<Opcode, Short> opcodeValues;
@Nonnull private final HashMap<String, Opcode> opcodesByName;
@Nonnull
public static Opcodes forApi(int api) {
return new Opcodes(api, VersionMap.mapApiToArtVersion(api), false);
}
@Nonnull
public static Opcodes forApi(int api, boolean experimental) {
return new Opcodes(api, VersionMap.mapApiToArtVersion(api), experimental);
}
@Nonnull
public static Opcodes forArtVersion(int artVersion) {
return forArtVersion(artVersion, false);
}
@Nonnull
public static Opcodes forArtVersion(int artVersion, boolean experimental) {
return new Opcodes(VersionMap.mapArtVersionToApi(artVersion), artVersion, experimental);
}
@Deprecated
public Opcodes(int api) {
this(api, false);
}
@Deprecated
public Opcodes(int api, boolean experimental) {
opcodesByValue = new Opcode[256];
this(api, VersionMap.mapApiToArtVersion(api), experimental);
}
private Opcodes(int api, int artVersion, boolean experimental) {
this.api = api;
this.artVersion = artVersion;
opcodeValues = new EnumMap<Opcode, Short>(Opcode.class);
opcodesByName = Maps.newHashMap();
int version;
if (isArt()) {
version = artVersion;
} else {
version = api;
}
for (Opcode opcode: Opcode.values()) {
if (!opcode.format.isPayloadFormat) {
if (api <= opcode.getMaxApi() && api >= opcode.getMinApi() &&
(experimental || !opcode.isExperimental())) {
opcodesByValue[opcode.value] = opcode;
opcodesByName.put(opcode.name.toLowerCase(), opcode);
RangeMap<Integer, Short> versionToValueMap;
if (isArt()) {
versionToValueMap = opcode.artVersionToValueMap;
} else {
versionToValueMap = opcode.apiToValueMap;
}
Short opcodeValue = versionToValueMap.get(version);
if (opcodeValue != null && (!opcode.isExperimental() || experimental)) {
if (!opcode.format.isPayloadFormat) {
opcodesByValue[opcodeValue] = opcode;
}
opcodeValues.put(opcode, opcodeValue);
opcodesByName.put(opcode.name.toLowerCase(), opcode);
}
}
}
@Nullable
public Opcode getOpcodeByName(String opcodeName) {
public Opcode getOpcodeByName(@Nonnull String opcodeName) {
return opcodesByName.get(opcodeName.toLowerCase());
}
@ -80,4 +135,13 @@ public class Opcodes {
return null;
}
}
@Nullable
public Short getOpcodeValue(@Nonnull Opcode opcode) {
return opcodeValues.get(opcode);
}
public boolean isArt() {
return artVersion != VersionMap.NO_VERSION;
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright 2015, 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;
public class VersionMap {
public static final int NO_VERSION = -1;
public static int mapArtVersionToApi(int artVersion) {
// TODO: implement this
return 20;
}
public static int mapApiToArtVersion(int api) {
// TODO: implement this
if (api < 20) {
return NO_VERSION;
} else {
return 56;
}
}
}

View File

@ -251,7 +251,7 @@ public class MethodAnalyzer {
int objectRegisterNumber;
switch (instruction.getOpcode().format) {
case Format10x:
analyzeReturnVoidBarrier(analyzedInstruction, false);
analyzeOdexReturnVoid(analyzedInstruction, false);
continue;
case Format21c:
case Format22c:
@ -578,7 +578,8 @@ public class MethodAnalyzer {
case RETURN_OBJECT:
return true;
case RETURN_VOID_BARRIER:
analyzeReturnVoidBarrier(analyzedInstruction);
case RETURN_VOID_NO_BARRIER:
analyzeOdexReturnVoid(analyzedInstruction);
return true;
case CONST_4:
case CONST_16:
@ -955,6 +956,14 @@ public class MethodAnalyzer {
case IPUT_QUICK:
case IPUT_WIDE_QUICK:
case IPUT_OBJECT_QUICK:
case IPUT_BOOLEAN_QUICK:
case IPUT_BYTE_QUICK:
case IPUT_CHAR_QUICK:
case IPUT_SHORT_QUICK:
case IGET_BOOLEAN_QUICK:
case IGET_BYTE_QUICK:
case IGET_CHAR_QUICK:
case IGET_SHORT_QUICK:
return analyzeIputIgetQuick(analyzedInstruction);
case INVOKE_VIRTUAL_QUICK:
return analyzeInvokeVirtualQuick(analyzedInstruction, false, false);
@ -1061,11 +1070,11 @@ public class MethodAnalyzer {
setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, exceptionType);
}
private void analyzeReturnVoidBarrier(AnalyzedInstruction analyzedInstruction) {
analyzeReturnVoidBarrier(analyzedInstruction, true);
private void analyzeOdexReturnVoid(AnalyzedInstruction analyzedInstruction) {
analyzeOdexReturnVoid(analyzedInstruction, true);
}
private void analyzeReturnVoidBarrier(@Nonnull AnalyzedInstruction analyzedInstruction, boolean analyzeResult) {
private void analyzeOdexReturnVoid(@Nonnull AnalyzedInstruction analyzedInstruction, boolean analyzeResult) {
Instruction10x deodexedInstruction = new ImmutableInstruction10x(Opcode.RETURN_VOID);
analyzedInstruction.setDeodexedInstruction(deodexedInstruction);

View File

@ -63,7 +63,7 @@ public class OatFile extends BaseDexBuffer {
@Nonnull private final OatHeader oatHeader;
@Nonnull private final Opcodes opcodes;
public OatFile(@Nonnull Opcodes opcodes, @Nonnull byte[] buf) {
public OatFile(@Nonnull byte[] buf) {
super(buf);
if (buf.length < ELF_HEADER_SIZE) {
@ -72,8 +72,6 @@ public class OatFile extends BaseDexBuffer {
verifyMagic(buf);
this.opcodes = opcodes;
OatHeader oatHeader = null;
SymbolTable symbolTable = getSymbolTable();
for (Symbol symbol: symbolTable.getSymbols()) {
@ -91,6 +89,8 @@ public class OatFile extends BaseDexBuffer {
if (!oatHeader.isValid()) {
throw new InvalidOatFileException("Invalid oat magic value");
}
this.opcodes = Opcodes.forArtVersion(oatHeader.getVersion());
}
private static void verifyMagic(byte[] buf) {
@ -101,7 +101,6 @@ public class OatFile extends BaseDexBuffer {
}
}
@Nonnull
public static OatFile fromInputStream(@Nonnull InputStream is)
throws IOException {
if (!is.markSupported()) {
@ -122,7 +121,7 @@ public class OatFile extends BaseDexBuffer {
is.reset();
byte[] buf = ByteStreams.toByteArray(is);
return new OatFile(new Opcodes(21), buf);
return new OatFile(buf);
}
public int isSupportedVersion() {

View File

@ -36,14 +36,15 @@ package org.jf.dexlib2.util;
import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction;
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction;
import org.jf.dexlib2.Opcodes;
import java.util.List;
public class SyntheticAccessorFSM {
// line 42 "SyntheticAccessorFSM.rl"
// line 43 "SyntheticAccessorFSM.rl"
// line 47 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java"
// line 48 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java"
private static byte[] init__SyntheticAccessorFSM_actions_0()
{
return new byte [] {
@ -187,7 +188,7 @@ static final int SyntheticAccessorFSM_error = 0;
static final int SyntheticAccessorFSM_en_main = 1;
// line 43 "SyntheticAccessorFSM.rl"
// line 44 "SyntheticAccessorFSM.rl"
// math type constants
public static final int ADD = SyntheticAccessorResolver.ADD_ASSIGNMENT;
@ -230,13 +231,15 @@ static final int SyntheticAccessorFSM_en_main = 1;
// The return register;
int returnRegister = -1;
Opcodes opcodes = Opcodes.forApi(20);
// line 235 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java"
// line 238 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java"
{
cs = SyntheticAccessorFSM_start;
}
// line 240 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java"
// line 243 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java"
{
int _klen;
int _trans = 0;
@ -270,9 +273,9 @@ case 1:
break;
_mid = _lower + ((_upper-_lower) >> 1);
if ( ( instructions.get(p).getOpcode().value) < _SyntheticAccessorFSM_trans_keys[_mid] )
if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) < _SyntheticAccessorFSM_trans_keys[_mid] )
_upper = _mid - 1;
else if ( ( instructions.get(p).getOpcode().value) > _SyntheticAccessorFSM_trans_keys[_mid] )
else if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) > _SyntheticAccessorFSM_trans_keys[_mid] )
_lower = _mid + 1;
else {
_trans += (_mid - _keys);
@ -293,9 +296,9 @@ case 1:
break;
_mid = _lower + (((_upper-_lower) >> 1) & ~1);
if ( ( instructions.get(p).getOpcode().value) < _SyntheticAccessorFSM_trans_keys[_mid] )
if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) < _SyntheticAccessorFSM_trans_keys[_mid] )
_upper = _mid - 2;
else if ( ( instructions.get(p).getOpcode().value) > _SyntheticAccessorFSM_trans_keys[_mid+1] )
else if ( ( opcodes.getOpcodeValue(instructions.get(p).getOpcode())) > _SyntheticAccessorFSM_trans_keys[_mid+1] )
_lower = _mid + 2;
else {
_trans += ((_mid - _keys)>>1);
@ -317,19 +320,19 @@ case 1:
switch ( _SyntheticAccessorFSM_actions[_acts++] )
{
case 0:
// line 93 "SyntheticAccessorFSM.rl"
// line 96 "SyntheticAccessorFSM.rl"
{
putRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA();
}
break;
case 1:
// line 100 "SyntheticAccessorFSM.rl"
// line 103 "SyntheticAccessorFSM.rl"
{
constantValue = ((WideLiteralInstruction)instructions.get(p)).getWideLiteral();
}
break;
case 2:
// line 104 "SyntheticAccessorFSM.rl"
// line 107 "SyntheticAccessorFSM.rl"
{
mathType = INT;
mathOp = ADD;
@ -337,146 +340,146 @@ case 1:
}
break;
case 3:
// line 110 "SyntheticAccessorFSM.rl"
// line 113 "SyntheticAccessorFSM.rl"
{ mathType = INT; }
break;
case 4:
// line 111 "SyntheticAccessorFSM.rl"
// line 114 "SyntheticAccessorFSM.rl"
{ mathType = LONG; }
break;
case 5:
// line 112 "SyntheticAccessorFSM.rl"
// line 115 "SyntheticAccessorFSM.rl"
{ mathType = FLOAT; }
break;
case 6:
// line 113 "SyntheticAccessorFSM.rl"
// line 116 "SyntheticAccessorFSM.rl"
{mathType = DOUBLE; }
break;
case 7:
// line 113 "SyntheticAccessorFSM.rl"
// line 116 "SyntheticAccessorFSM.rl"
{
mathOp = ADD;
}
break;
case 8:
// line 116 "SyntheticAccessorFSM.rl"
// line 119 "SyntheticAccessorFSM.rl"
{ mathType = INT; }
break;
case 9:
// line 117 "SyntheticAccessorFSM.rl"
// line 120 "SyntheticAccessorFSM.rl"
{ mathType = LONG; }
break;
case 10:
// line 118 "SyntheticAccessorFSM.rl"
// line 121 "SyntheticAccessorFSM.rl"
{ mathType = FLOAT; }
break;
case 11:
// line 119 "SyntheticAccessorFSM.rl"
// line 122 "SyntheticAccessorFSM.rl"
{mathType = DOUBLE; }
break;
case 12:
// line 119 "SyntheticAccessorFSM.rl"
// line 122 "SyntheticAccessorFSM.rl"
{
mathOp = SUB;
}
break;
case 13:
// line 123 "SyntheticAccessorFSM.rl"
// line 126 "SyntheticAccessorFSM.rl"
{
mathOp = MUL;
}
break;
case 14:
// line 127 "SyntheticAccessorFSM.rl"
// line 130 "SyntheticAccessorFSM.rl"
{
mathOp = DIV;
}
break;
case 15:
// line 131 "SyntheticAccessorFSM.rl"
// line 134 "SyntheticAccessorFSM.rl"
{
mathOp = REM;
}
break;
case 16:
// line 134 "SyntheticAccessorFSM.rl"
// line 137 "SyntheticAccessorFSM.rl"
{
mathOp = AND;
}
break;
case 17:
// line 137 "SyntheticAccessorFSM.rl"
// line 140 "SyntheticAccessorFSM.rl"
{
mathOp = OR;
}
break;
case 18:
// line 140 "SyntheticAccessorFSM.rl"
// line 143 "SyntheticAccessorFSM.rl"
{
mathOp = XOR;
}
break;
case 19:
// line 143 "SyntheticAccessorFSM.rl"
// line 146 "SyntheticAccessorFSM.rl"
{
mathOp = SHL;
}
break;
case 20:
// line 146 "SyntheticAccessorFSM.rl"
// line 149 "SyntheticAccessorFSM.rl"
{
mathOp = SHR;
}
break;
case 21:
// line 149 "SyntheticAccessorFSM.rl"
// line 152 "SyntheticAccessorFSM.rl"
{
mathOp = USHR;
}
break;
case 22:
// line 155 "SyntheticAccessorFSM.rl"
// line 158 "SyntheticAccessorFSM.rl"
{
returnRegister = ((OneRegisterInstruction)instructions.get(p)).getRegisterA();
}
break;
case 23:
// line 161 "SyntheticAccessorFSM.rl"
// line 164 "SyntheticAccessorFSM.rl"
{
accessorType = SyntheticAccessorResolver.GETTER; { p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
case 24:
// line 165 "SyntheticAccessorFSM.rl"
// line 168 "SyntheticAccessorFSM.rl"
{
accessorType = SyntheticAccessorResolver.SETTER; { p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
case 25:
// line 169 "SyntheticAccessorFSM.rl"
// line 172 "SyntheticAccessorFSM.rl"
{
accessorType = SyntheticAccessorResolver.METHOD; { p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
case 26:
// line 173 "SyntheticAccessorFSM.rl"
// line 176 "SyntheticAccessorFSM.rl"
{
accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister);
}
break;
case 27:
// line 177 "SyntheticAccessorFSM.rl"
// line 180 "SyntheticAccessorFSM.rl"
{
accessorType = getIncrementType(mathOp, mathType, constantValue, putRegister, returnRegister);
}
break;
case 28:
// line 185 "SyntheticAccessorFSM.rl"
// line 188 "SyntheticAccessorFSM.rl"
{
accessorType = mathOp; { p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
// line 480 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java"
// line 483 "/home/jesusfreke/projects/smali/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java"
}
}
}
@ -496,7 +499,7 @@ case 5:
break; }
}
// line 198 "SyntheticAccessorFSM.rl"
// line 201 "SyntheticAccessorFSM.rl"
return accessorType;

View File

@ -37,6 +37,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.base.BaseAnnotation;
import org.jf.dexlib2.base.BaseAnnotationElement;
@ -94,7 +95,7 @@ public abstract class DexWriter<
public static final int NO_INDEX = -1;
public static final int NO_OFFSET = 0;
protected final int api;
protected final Opcodes opcodes;
protected int stringIndexSectionOffset = NO_OFFSET;
protected int typeSectionOffset = NO_OFFSET;
@ -134,7 +135,7 @@ public abstract class DexWriter<
protected final AnnotationSection<StringKey, TypeKey, AnnotationKey, AnnotationElement, EncodedValue> annotationSection;
protected final AnnotationSetSection<AnnotationKey, AnnotationSetKey> annotationSetSection;
protected DexWriter(int api,
protected DexWriter(Opcodes opcodes,
StringSection<StringKey, StringRef> stringSection,
TypeSection<StringKey, TypeKey, TypeRef> typeSection,
ProtoSection<StringKey, TypeKey, ProtoKey, TypeListKey> protoSection,
@ -146,7 +147,8 @@ public abstract class DexWriter<
AnnotationSection<StringKey, TypeKey, AnnotationKey, AnnotationElement,
EncodedValue> annotationSection,
AnnotationSetSection<AnnotationKey, AnnotationSetKey> annotationSetSection) {
this.api = api;
this.opcodes = opcodes;
this.stringSection = stringSection;
this.typeSection = typeSection;
this.protoSection = protoSection;
@ -943,7 +945,7 @@ public abstract class DexWriter<
writer.writeInt(debugItemOffset);
InstructionWriter instructionWriter =
InstructionWriter.makeInstructionWriter(writer, stringSection, typeSection, fieldSection,
InstructionWriter.makeInstructionWriter(opcodes, writer, stringSection, typeSection, fieldSection,
methodSection);
writer.writeInt(codeUnitCount);
@ -1266,6 +1268,6 @@ public abstract class DexWriter<
// Workaround for a crash in Dalvik VM before Jelly Bean MR1 (4.2)
// which is triggered by NO_OFFSET in parameter annotation list.
// (https://code.google.com/p/android/issues/detail?id=35304)
return (api < 17);
return (opcodes.api < 17);
}
}

View File

@ -33,6 +33,8 @@ package org.jf.dexlib2.writer;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.ReferenceType;
import org.jf.dexlib2.iface.instruction.ReferenceInstruction;
import org.jf.dexlib2.iface.instruction.SwitchElement;
@ -50,6 +52,7 @@ import java.util.List;
public class InstructionWriter<StringRef extends StringReference, TypeRef extends TypeReference,
FieldRefKey extends FieldReference, MethodRefKey extends MethodReference> {
@Nonnull private final Opcodes opcodes;
@Nonnull private final DexDataWriter writer;
@Nonnull private final StringSection<?, StringRef> stringSection;
@Nonnull private final TypeSection<?, ?, TypeRef> typeSection;
@ -59,20 +62,23 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
@Nonnull static <StringRef extends StringReference, TypeRef extends TypeReference, FieldRefKey extends FieldReference, MethodRefKey extends MethodReference>
InstructionWriter<StringRef, TypeRef, FieldRefKey, MethodRefKey>
makeInstructionWriter(
@Nonnull Opcodes opcodes,
@Nonnull DexDataWriter writer,
@Nonnull StringSection<?, StringRef> stringSection,
@Nonnull TypeSection<?, ?, TypeRef> typeSection,
@Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection,
@Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection) {
return new InstructionWriter<StringRef, TypeRef, FieldRefKey, MethodRefKey>(
writer, stringSection, typeSection, fieldSection, methodSection);
opcodes, writer, stringSection, typeSection, fieldSection, methodSection);
}
InstructionWriter(@Nonnull DexDataWriter writer,
InstructionWriter(@Nonnull Opcodes opcodes,
@Nonnull DexDataWriter writer,
@Nonnull StringSection<?, StringRef> stringSection,
@Nonnull TypeSection<?, ?, TypeRef> typeSection,
@Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection,
@Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection) {
this.opcodes = opcodes;
this.writer = writer;
this.stringSection = stringSection;
this.typeSection = typeSection;
@ -80,9 +86,17 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
this.methodSection = methodSection;
}
private short getOpcodeValue(Opcode opcode) {
Short value = opcodes.getOpcodeValue(opcode);
if (value == null) {
throw new ExceptionWithContext("Instruction %s is invalid for api %d", opcode.name, opcodes.api);
}
return value;
}
public void write(@Nonnull Instruction10t instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getCodeOffset());
} catch (IOException ex) {
throw new RuntimeException(ex);
@ -91,7 +105,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction10x instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(0);
} catch (IOException ex) {
throw new RuntimeException(ex);
@ -100,7 +114,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction11n instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(packNibbles(instruction.getRegisterA(), instruction.getNarrowLiteral()));
} catch (IOException ex) {
throw new RuntimeException(ex);
@ -109,7 +123,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction11x instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
} catch (IOException ex) {
throw new RuntimeException(ex);
@ -118,7 +132,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction12x instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(packNibbles(instruction.getRegisterA(), instruction.getRegisterB()));
} catch (IOException ex) {
throw new RuntimeException(ex);
@ -127,7 +141,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction20bc instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getVerificationError());
writer.writeUshort(getReferenceIndex(instruction));
} catch (IOException ex) {
@ -137,7 +151,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction20t instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(0);
writer.writeShort(instruction.getCodeOffset());
} catch (IOException ex) {
@ -147,7 +161,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction21c instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.writeUshort(getReferenceIndex(instruction));
} catch (IOException ex) {
@ -157,7 +171,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction21ih instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.writeShort(instruction.getHatLiteral());
} catch (IOException ex) {
@ -167,7 +181,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction21lh instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.writeShort(instruction.getHatLiteral());
} catch (IOException ex) {
@ -177,7 +191,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction21s instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.writeShort(instruction.getNarrowLiteral());
} catch (IOException ex) {
@ -187,7 +201,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction21t instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.writeShort(instruction.getCodeOffset());
} catch (IOException ex) {
@ -197,7 +211,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction22b instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.write(instruction.getRegisterB());
writer.write(instruction.getNarrowLiteral());
@ -208,7 +222,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction22c instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(packNibbles(instruction.getRegisterA(), instruction.getRegisterB()));
writer.writeUshort(getReferenceIndex(instruction));
} catch (IOException ex) {
@ -218,7 +232,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction22s instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(packNibbles(instruction.getRegisterA(), instruction.getRegisterB()));
writer.writeShort(instruction.getNarrowLiteral());
} catch (IOException ex) {
@ -228,7 +242,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction22t instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(packNibbles(instruction.getRegisterA(), instruction.getRegisterB()));
writer.writeShort(instruction.getCodeOffset());
} catch (IOException ex) {
@ -238,7 +252,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction22x instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.writeUshort(instruction.getRegisterB());
} catch (IOException ex) {
@ -248,7 +262,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction23x instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.write(instruction.getRegisterB());
writer.write(instruction.getRegisterC());
@ -259,7 +273,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction30t instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(0);
writer.writeInt(instruction.getCodeOffset());
} catch (IOException ex) {
@ -269,7 +283,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction31c instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.writeInt(getReferenceIndex(instruction));
} catch (IOException ex) {
@ -279,7 +293,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction31i instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.writeInt(instruction.getNarrowLiteral());
} catch (IOException ex) {
@ -289,7 +303,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction31t instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.writeInt(instruction.getCodeOffset());
} catch (IOException ex) {
@ -299,7 +313,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction32x instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(0);
writer.writeUshort(instruction.getRegisterA());
writer.writeUshort(instruction.getRegisterB());
@ -310,7 +324,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction35c instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(packNibbles(instruction.getRegisterG(), instruction.getRegisterCount()));
writer.writeUshort(getReferenceIndex(instruction));
writer.write(packNibbles(instruction.getRegisterC(), instruction.getRegisterD()));
@ -322,7 +336,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction25x instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(packNibbles(
instruction.getRegisterParameterG(), instruction.getParameterRegisterCount()));
writer.write(packNibbles(
@ -335,7 +349,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
}
public void write(@Nonnull Instruction3rc instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterCount());
writer.writeUshort(getReferenceIndex(instruction));
writer.writeUshort(instruction.getStartRegister());
@ -346,7 +360,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull Instruction51l instruction) {
try {
writer.write(instruction.getOpcode().value);
writer.write(getOpcodeValue(instruction.getOpcode()));
writer.write(instruction.getRegisterA());
writer.writeLong(instruction.getWideLiteral());
} catch (IOException ex) {
@ -356,7 +370,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull ArrayPayload instruction) {
try {
writer.writeUshort(instruction.getOpcode().value);
writer.writeUshort(getOpcodeValue(instruction.getOpcode()));
writer.writeUshort(instruction.getElementWidth());
List<Number> elements = instruction.getArrayElements();
writer.writeInt(elements.size());
@ -393,7 +407,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull SparseSwitchPayload instruction) {
try {
writer.writeUbyte(0);
writer.writeUbyte(instruction.getOpcode().value >> 8);
writer.writeUbyte(getOpcodeValue(instruction.getOpcode()) >> 8);
List<? extends SwitchElement> elements = Ordering.from(switchElementComparator).immutableSortedCopy(
instruction.getSwitchElements());
writer.writeUshort(elements.size());
@ -417,7 +431,7 @@ public class InstructionWriter<StringRef extends StringReference, TypeRef extend
public void write(@Nonnull PackedSwitchPayload instruction) {
try {
writer.writeUbyte(0);
writer.writeUbyte(instruction.getOpcode().value >> 8);
writer.writeUbyte(getOpcodeValue(instruction.getOpcode()) >> 8);
List<? extends SwitchElement> elements = instruction.getSwitchElements();
writer.writeUshort(elements.size());
if (elements.size() == 0) {

View File

@ -34,8 +34,8 @@ package org.jf.dexlib2.writer.builder;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.MethodImplementation;
@ -49,7 +49,6 @@ import org.jf.util.ExceptionWithContext;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@ -59,20 +58,27 @@ public class DexBuilder extends DexWriter<BuilderStringReference, BuilderStringR
BuilderClassDef, BuilderAnnotation, BuilderAnnotationSet, BuilderTypeList, BuilderField, BuilderMethod,
BuilderEncodedValue, BuilderAnnotationElement> {
private final BuilderContext context;
@Nonnull private final BuilderContext context;
public static DexBuilder makeDexBuilder() {
@Nonnull public static DexBuilder makeDexBuilder() {
BuilderContext context = new BuilderContext();
return new DexBuilder(15, context);
return new DexBuilder(Opcodes.forApi(20), context);
}
@Deprecated
@Nonnull
public static DexBuilder makeDexBuilder(int api) {
BuilderContext context = new BuilderContext();
return new DexBuilder(api, context);
return new DexBuilder(Opcodes.forApi(api), context);
}
private DexBuilder(int api, @Nonnull BuilderContext context) {
super(api, context.stringPool, context.typePool, context.protoPool,
@Nonnull public static DexBuilder makeDexBuilder(@Nonnull Opcodes opcodes) {
BuilderContext context = new BuilderContext();
return new DexBuilder(opcodes, context);
}
private DexBuilder(@Nonnull Opcodes opcodes, @Nonnull BuilderContext context) {
super(opcodes, context.stringPool, context.typePool, context.protoPool,
context.fieldPool, context.methodPool, context.classPool, context.typeListPool, context.annotationPool,
context.annotationSetPool);
this.context = context;

View File

@ -31,6 +31,7 @@
package org.jf.dexlib2.writer.pool;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.AnnotationElement;
@ -56,11 +57,19 @@ public class DexPool extends DexWriter<CharSequence, StringReference, CharSequen
TypeListPool.Key<? extends Collection<? extends CharSequence>>, Field, PoolMethod,
EncodedValue, AnnotationElement> {
@Nonnull
public static DexPool makeDexPool() {
return makeDexPool(15);
return makeDexPool(Opcodes.forApi(20));
}
@Deprecated
@Nonnull
public static DexPool makeDexPool(int api) {
return makeDexPool(Opcodes.forApi(api));
}
@Nonnull
public static DexPool makeDexPool(@Nonnull Opcodes opcodes) {
StringPool stringPool = new StringPool();
TypePool typePool = new TypePool(stringPool);
FieldPool fieldPool = new FieldPool(stringPool, typePool);
@ -72,14 +81,14 @@ public class DexPool extends DexWriter<CharSequence, StringReference, CharSequen
ClassPool classPool = new ClassPool(stringPool, typePool, fieldPool, methodPool, annotationSetPool,
typeListPool);
return new DexPool(api, stringPool, typePool, protoPool, fieldPool, methodPool, classPool, typeListPool,
return new DexPool(opcodes, stringPool, typePool, protoPool, fieldPool, methodPool, classPool, typeListPool,
annotationPool, annotationSetPool);
}
private DexPool(int api, StringPool stringPool, TypePool typePool, ProtoPool protoPool, FieldPool fieldPool,
private DexPool(Opcodes opcodes, StringPool stringPool, TypePool typePool, ProtoPool protoPool, FieldPool fieldPool,
MethodPool methodPool, ClassPool classPool, TypeListPool typeListPool,
AnnotationPool annotationPool, AnnotationSetPool annotationSetPool) {
super(api, stringPool, typePool, protoPool, fieldPool, methodPool,
super(opcodes, stringPool, typePool, protoPool, fieldPool, methodPool,
classPool, typeListPool, annotationPool, annotationSetPool);
}

View File

@ -34,6 +34,7 @@ package org.jf.dexlib2.util;
import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction;
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction;
import org.jf.dexlib2.Opcodes;
import java.util.List;
@ -82,10 +83,12 @@ public class SyntheticAccessorFSM {
// The return register;
int returnRegister = -1;
Opcodes opcodes = Opcodes.forApi(20);
%%{
import "Opcodes.rl";
alphtype short;
getkey instructions.get(p).getOpcode().value;
getkey opcodes.getOpcodeValue(instructions.get(p).getOpcode());
get = (0x52 .. 0x58) | (0x60 .. 0x66); # all igets/sgets

View File

@ -77,7 +77,7 @@ public class DexWriterTest {
throw new RuntimeException(ex);
}
DexBackedDexFile dexFile = new DexBackedDexFile(new Opcodes(15, false), dataStore.getData());
DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(15), dataStore.getData());
ClassDef dbClassDef = Iterables.getFirst(dexFile.getClasses(), null);
Assert.assertNotNull(dbClassDef);
Annotation dbAnnotation = Iterables.getFirst(dbClassDef.getAnnotations(), null);
@ -117,7 +117,7 @@ public class DexWriterTest {
throw new RuntimeException(ex);
}
DexBackedDexFile dexFile = new DexBackedDexFile(new Opcodes(15, false), dataStore.getData());
DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(15), dataStore.getData());
ClassDef dbClassDef = Iterables.getFirst(dexFile.getClasses(), null);
Assert.assertNotNull(dbClassDef);
Annotation dbAnnotation = Iterables.getFirst(dbClassDef.getAnnotations(), null);

View File

@ -62,7 +62,7 @@ import java.util.List;
public class JumboStringConversionTest {
@Test
public void testJumboStringConversion() throws IOException {
DexBuilder dexBuilder = DexBuilder.makeDexBuilder(15);
DexBuilder dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(15));
MethodImplementationBuilder methodBuilder = new MethodImplementationBuilder(1);
for (int i=0; i<66000; i++) {
@ -92,7 +92,7 @@ public class JumboStringConversionTest {
MemoryDataStore dexStore = new MemoryDataStore();
dexBuilder.writeTo(dexStore);
DexBackedDexFile dexFile = new DexBackedDexFile(new Opcodes(15, false), dexStore.getData());
DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(15), dexStore.getData());
ClassDef classDef = Iterables.getFirst(dexFile.getClasses(), null);
Assert.assertNotNull(classDef);
@ -122,7 +122,7 @@ public class JumboStringConversionTest {
@Test
public void testJumboStringConversion_NonMethodBuilder() throws IOException {
DexBuilder dexBuilder = DexBuilder.makeDexBuilder(15);
DexBuilder dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(15));
final List<Instruction> instructions = Lists.newArrayList();
for (int i=0; i<66000; i++) {
@ -189,7 +189,7 @@ public class JumboStringConversionTest {
MemoryDataStore dexStore = new MemoryDataStore();
dexBuilder.writeTo(dexStore);
DexBackedDexFile dexFile = new DexBackedDexFile(new Opcodes(15, false), dexStore.getData());
DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(15), dexStore.getData());
ClassDef classDef = Iterables.getFirst(dexFile.getClasses(), null);
Assert.assertNotNull(classDef);

View File

@ -260,7 +260,7 @@ import org.jf.dexlib2.Opcodes;
private boolean verboseErrors = false;
private boolean allowOdex = false;
private int apiLevel = 15;
private Opcodes opcodes = new Opcodes(apiLevel, false);
private Opcodes opcodes = Opcodes.forApi(apiLevel);
public void setVerboseErrors(boolean verboseErrors) {
this.verboseErrors = verboseErrors;

View File

@ -77,7 +77,7 @@ import java.util.*;
public String classType;
private boolean verboseErrors = false;
private int apiLevel = 15;
private Opcodes opcodes = new Opcodes(apiLevel, false);
private Opcodes opcodes = Opcodes.forApi(apiLevel);
private DexBuilder dexBuilder;
public void setDexBuilder(DexBuilder dexBuilder) {

View File

@ -57,7 +57,7 @@ public class SmaliTestUtils {
throws RecognitionException, IOException {
CommonTokenStream tokens;
LexerErrorInterface lexer;
DexBuilder dexBuilder = DexBuilder.makeDexBuilder(apiLevel);
DexBuilder dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(apiLevel, experimental));
Reader reader = new StringReader(smaliText);
@ -94,8 +94,7 @@ public class SmaliTestUtils {
dexBuilder.writeTo(dataStore);
DexBackedDexFile dexFile = new DexBackedDexFile(
new Opcodes(apiLevel, experimental), dataStore.getData());
DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(apiLevel, experimental), dataStore.getData());
return Iterables.getFirst(dexFile.getClasses(), null);
}

View File

@ -36,8 +36,8 @@ import org.antlr.runtime.Token;
import org.antlr.runtime.TokenSource;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.antlr.runtime.tree.TreeNodeStream;
import org.apache.commons.cli.*;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.writer.builder.DexBuilder;
import org.jf.dexlib2.writer.io.FileDataStore;
import org.jf.util.ConsoleUtil;
@ -218,7 +218,8 @@ public class main {
boolean errors = false;
final DexBuilder dexBuilder = DexBuilder.makeDexBuilder(apiLevel);
final DexBuilder dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(apiLevel, experimental));
ExecutorService executor = Executors.newFixedThreadPool(jobs);
List<Future<Boolean>> tasks = Lists.newArrayList();

View File

@ -406,7 +406,7 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayDescriptor}
return newToken(INSTRUCTION_FORMAT10x);
}
"return-void-barrier" {
"return-void-barrier" | "return-void-no-barrier" {
return newToken(INSTRUCTION_FORMAT10x_ODEX);
}
@ -507,7 +507,9 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayDescriptor}
"liberate-variable" {
return newToken(INSTRUCTION_FORMAT22c_STRING);
}
"iget-quick" | "iget-wide-quick" | "iget-object-quick" | "iput-quick" | "iput-wide-quick" | "iput-object-quick" {
"iget-quick" | "iget-wide-quick" | "iget-object-quick" | "iput-quick" | "iput-wide-quick" | "iput-object-quick" |
"iput-boolean-quick" | "iput-byte-quick" | "iput-char-quick" | "iput-short-quick" {
return newToken(INSTRUCTION_FORMAT22cs_FIELD);
}

View File

@ -2,6 +2,7 @@ goto
return-void
nop
return-void-barrier
return-void-no-barrier
const/4
move-result
move-result-wide
@ -132,6 +133,10 @@ iget-object-quick
iput-quick
iput-wide-quick
iput-object-quick
iput-boolean-quick
iput-byte-quick
iput-char-quick
iput-short-quick
rsub-int
add-int/lit16
mul-int/lit16

View File

@ -2,6 +2,7 @@ INSTRUCTION_FORMAT10t("goto")
INSTRUCTION_FORMAT10x("return-void")
INSTRUCTION_FORMAT10x("nop")
INSTRUCTION_FORMAT10x_ODEX("return-void-barrier")
INSTRUCTION_FORMAT10x_ODEX("return-void-no-barrier")
INSTRUCTION_FORMAT11n("const/4")
INSTRUCTION_FORMAT11x("move-result")
INSTRUCTION_FORMAT11x("move-result-wide")
@ -132,6 +133,10 @@ INSTRUCTION_FORMAT22cs_FIELD("iget-object-quick")
INSTRUCTION_FORMAT22cs_FIELD("iput-quick")
INSTRUCTION_FORMAT22cs_FIELD("iput-wide-quick")
INSTRUCTION_FORMAT22cs_FIELD("iput-object-quick")
INSTRUCTION_FORMAT22cs_FIELD("iput-boolean-quick")
INSTRUCTION_FORMAT22cs_FIELD("iput-byte-quick")
INSTRUCTION_FORMAT22cs_FIELD("iput-char-quick")
INSTRUCTION_FORMAT22cs_FIELD("iput-short-quick")
INSTRUCTION_FORMAT22s_OR_ID("rsub-int")
INSTRUCTION_FORMAT22s("add-int/lit16")
INSTRUCTION_FORMAT22s("mul-int/lit16")