From 3ff884b1c345dbd030430e3eecf37e4d409f18b0 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sun, 12 Jul 2015 12:52:57 -0700 Subject: [PATCH] Add art-specific opcodes and opcode values --- .../src/main/java/org/jf/baksmali/dump.java | 2 +- .../java/org/jf/baksmali/DisassemblyTest.java | 2 +- .../java/org/jf/dexlib2/DexFileFactory.java | 6 +- .../src/main/java/org/jf/dexlib2/Opcode.java | 630 ++++++++++-------- .../src/main/java/org/jf/dexlib2/Opcodes.java | 82 ++- .../main/java/org/jf/dexlib2/VersionMap.java | 50 ++ .../jf/dexlib2/analysis/MethodAnalyzer.java | 19 +- .../org/jf/dexlib2/dexbacked/OatFile.java | 9 +- .../jf/dexlib2/util/SyntheticAccessorFSM.java | 83 +-- .../java/org/jf/dexlib2/writer/DexWriter.java | 12 +- .../jf/dexlib2/writer/InstructionWriter.java | 78 ++- .../jf/dexlib2/writer/builder/DexBuilder.java | 22 +- .../org/jf/dexlib2/writer/pool/DexPool.java | 17 +- .../src/main/ragel/SyntheticAccessorFSM.rl | 5 +- .../org/jf/dexlib2/writer/DexWriterTest.java | 4 +- .../writer/JumboStringConversionTest.java | 8 +- smali/src/main/antlr/smaliParser.g | 2 +- smali/src/main/antlr/smaliTreeWalker.g | 2 +- .../java/org/jf/smali/SmaliTestUtils.java | 5 +- smali/src/main/java/org/jf/smali/main.java | 5 +- smali/src/main/jflex/smaliLexer.jflex | 6 +- .../resources/LexerTest/InstructionTest.smali | 5 + .../LexerTest/InstructionTest.tokens | 5 + 23 files changed, 642 insertions(+), 417 deletions(-) create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/VersionMap.java diff --git a/baksmali/src/main/java/org/jf/baksmali/dump.java b/baksmali/src/main/java/org/jf/baksmali/dump.java index 1ef7df0e..57a48af8 100644 --- a/baksmali/src/main/java/org/jf/baksmali/dump.java +++ b/baksmali/src/main/java/org/jf/baksmali/dump.java @@ -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) { diff --git a/baksmali/src/test/java/org/jf/baksmali/DisassemblyTest.java b/baksmali/src/test/java/org/jf/baksmali/DisassemblyTest.java index 35304f7e..1fbafeab 100644 --- a/baksmali/src/test/java/org/jf/baksmali/DisassemblyTest.java +++ b/baksmali/src/test/java/org/jf/baksmali/DisassemblyTest.java @@ -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); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java index 113b60a3..fb433bb3 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java @@ -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 diff --git a/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java b/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java index 3b082ee8..5fb2a8c0 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java @@ -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 apiToValueMap; + public final RangeMap 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 versionConstraints, String opcodeName, int referenceType, Format format, int flags) { + ImmutableRangeMap.Builder apiToValueBuilder = ImmutableRangeMap.builder(); + ImmutableRangeMap.Builder 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 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 lastApi(int opcodeValue, int api) { + Range range; + return Lists.newArrayList(new VersionConstraint(Range.atMost(api), Range.openClosed(0, 0), opcodeValue)); + } + + private static List firstArtVersion(int opcodeValue, int artVersion) { + return Lists.newArrayList(new VersionConstraint(Range.openClosed(0, 0), Range.atLeast(artVersion), opcodeValue)); + } + + private static List lastArtVersion(int opcodeValue, int artVersion) { + return Lists.newArrayList(new VersionConstraint(Range.openClosed(0, 0), Range.atMost(artVersion), opcodeValue)); + } + + private static List allVersions(int opcodeValue) { + return Lists.newArrayList(new VersionConstraint(Range.all(), Range.all(), opcodeValue)); + } + + private static List allApis(int opcodeValue) { + return Lists.newArrayList(new VersionConstraint(Range.all(), Range.openClosed(0, 0), opcodeValue)); + } + + private static List allArtVersions(int opcodeValue) { + return Lists.newArrayList(new VersionConstraint(Range.openClosed(0, 0), Range.all(), opcodeValue)); + } + + @SuppressWarnings("unchecked") + private static List combine(List... versionConstraints) { + List combinedList = Lists.newArrayList(); + for (List 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 apiRange; + @Nonnull public final Range artVersionRange; + public final int opcodeValue; + + public VersionConstraint(@Nonnull Range apiRange, @Nonnull Range artVersionRange, + int opcodeValue) { + this.apiRange = apiRange; + this.artVersionRange = artVersionRange; + this.opcodeValue = opcodeValue; + } + } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/Opcodes.java b/dexlib2/src/main/java/org/jf/dexlib2/Opcodes.java index e718e275..17f80132 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/Opcodes.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/Opcodes.java @@ -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 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 opcodeValues; + @Nonnull private final HashMap 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.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 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; + } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/VersionMap.java b/dexlib2/src/main/java/org/jf/dexlib2/VersionMap.java new file mode 100644 index 00000000..42802bc0 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/VersionMap.java @@ -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; + } + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java index 4402c624..d5d9d722 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java @@ -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); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/OatFile.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/OatFile.java index 157b1668..88ef08c7 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/OatFile.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/OatFile.java @@ -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() { diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java b/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java index aa428b05..1e8b010b 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/SyntheticAccessorFSM.java @@ -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; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java index be23978e..9d353982 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java @@ -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 annotationSection; protected final AnnotationSetSection annotationSetSection; - protected DexWriter(int api, + protected DexWriter(Opcodes opcodes, StringSection stringSection, TypeSection typeSection, ProtoSection protoSection, @@ -146,7 +147,8 @@ public abstract class DexWriter< AnnotationSection annotationSection, AnnotationSetSection 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); } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java index c9aa73a1..f16256c5 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java @@ -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 { + @Nonnull private final Opcodes opcodes; @Nonnull private final DexDataWriter writer; @Nonnull private final StringSection stringSection; @Nonnull private final TypeSection typeSection; @@ -59,20 +62,23 @@ public class InstructionWriter InstructionWriter makeInstructionWriter( + @Nonnull Opcodes opcodes, @Nonnull DexDataWriter writer, @Nonnull StringSection stringSection, @Nonnull TypeSection typeSection, @Nonnull FieldSection fieldSection, @Nonnull MethodSection methodSection) { return new InstructionWriter( - writer, stringSection, typeSection, fieldSection, methodSection); + opcodes, writer, stringSection, typeSection, fieldSection, methodSection); } - InstructionWriter(@Nonnull DexDataWriter writer, + InstructionWriter(@Nonnull Opcodes opcodes, + @Nonnull DexDataWriter writer, @Nonnull StringSection stringSection, @Nonnull TypeSection typeSection, @Nonnull FieldSection fieldSection, @Nonnull MethodSection methodSection) { + this.opcodes = opcodes; this.writer = writer; this.stringSection = stringSection; this.typeSection = typeSection; @@ -80,9 +86,17 @@ public class InstructionWriter elements = instruction.getArrayElements(); writer.writeInt(elements.size()); @@ -393,7 +407,7 @@ public class InstructionWriter> 8); + writer.writeUbyte(getOpcodeValue(instruction.getOpcode()) >> 8); List elements = Ordering.from(switchElementComparator).immutableSortedCopy( instruction.getSwitchElements()); writer.writeUshort(elements.size()); @@ -417,7 +431,7 @@ public class InstructionWriter> 8); + writer.writeUbyte(getOpcodeValue(instruction.getOpcode()) >> 8); List elements = instruction.getSwitchElements(); writer.writeUshort(elements.size()); if (elements.size() == 0) { diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java index 9a727b27..d1190249 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java @@ -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 { - 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; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/DexPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/DexPool.java index d7f63922..27d8044e 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/DexPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/DexPool.java @@ -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>, 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 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); diff --git a/smali/src/main/antlr/smaliParser.g b/smali/src/main/antlr/smaliParser.g index 6d07452c..db769338 100644 --- a/smali/src/main/antlr/smaliParser.g +++ b/smali/src/main/antlr/smaliParser.g @@ -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; diff --git a/smali/src/main/antlr/smaliTreeWalker.g b/smali/src/main/antlr/smaliTreeWalker.g index 8eed2b20..f5c4a685 100644 --- a/smali/src/main/antlr/smaliTreeWalker.g +++ b/smali/src/main/antlr/smaliTreeWalker.g @@ -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) { diff --git a/smali/src/main/java/org/jf/smali/SmaliTestUtils.java b/smali/src/main/java/org/jf/smali/SmaliTestUtils.java index 26de0089..bef07414 100644 --- a/smali/src/main/java/org/jf/smali/SmaliTestUtils.java +++ b/smali/src/main/java/org/jf/smali/SmaliTestUtils.java @@ -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); } diff --git a/smali/src/main/java/org/jf/smali/main.java b/smali/src/main/java/org/jf/smali/main.java index 98fb7a1f..b36b088d 100644 --- a/smali/src/main/java/org/jf/smali/main.java +++ b/smali/src/main/java/org/jf/smali/main.java @@ -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> tasks = Lists.newArrayList(); diff --git a/smali/src/main/jflex/smaliLexer.jflex b/smali/src/main/jflex/smaliLexer.jflex index bc17362f..c0be81e2 100644 --- a/smali/src/main/jflex/smaliLexer.jflex +++ b/smali/src/main/jflex/smaliLexer.jflex @@ -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); } diff --git a/smali/src/test/resources/LexerTest/InstructionTest.smali b/smali/src/test/resources/LexerTest/InstructionTest.smali index f6dcbb1e..174cff8c 100644 --- a/smali/src/test/resources/LexerTest/InstructionTest.smali +++ b/smali/src/test/resources/LexerTest/InstructionTest.smali @@ -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 diff --git a/smali/src/test/resources/LexerTest/InstructionTest.tokens b/smali/src/test/resources/LexerTest/InstructionTest.tokens index fb5503b5..fa959bad 100644 --- a/smali/src/test/resources/LexerTest/InstructionTest.tokens +++ b/smali/src/test/resources/LexerTest/InstructionTest.tokens @@ -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")