changeset 6:2672c39e014c

Added visitor interfaces for DEX file parser. * This changeset contains a lot of code contributed by Remi Forax. * dex/DexClassVisitor.java: Added the visitor interface for DEX classes. * dex/DexFieldVisitor.java: Likewise for fields. * dex/DexFileVisitor.java: Likewise for DEX files. * dex/DexMethodVisitor.java: Likewise for methods. * dex/Label.java: Added a label class pointing into bytecode streams. * dex/Opcode.java: Added a type-safe enumeration of all available opcodes.
author Michael Starzinger <michi@complang.tuwien.ac.at>
date Fri, 11 Mar 2011 20:33:43 +0100
parents bfd49213d13c
children 85501f58a1bc
files src/main/java/org/icedrobot/daneel/dex/DexClassVisitor.java src/main/java/org/icedrobot/daneel/dex/DexFieldVisitor.java src/main/java/org/icedrobot/daneel/dex/DexFileVisitor.java src/main/java/org/icedrobot/daneel/dex/DexMethodVisitor.java src/main/java/org/icedrobot/daneel/dex/Label.java src/main/java/org/icedrobot/daneel/dex/Opcode.java
diffstat 6 files changed, 742 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/icedrobot/daneel/dex/DexClassVisitor.java	Fri Mar 11 20:33:43 2011 +0100
@@ -0,0 +1,83 @@
+/*
+ * Daneel - Dalvik to Java bytecode compiler
+ * Copyright (C) 2011  IcedRobot team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.icedrobot.daneel.dex;
+
+/**
+ * A visitor for classes contained in DEX files.
+ * @author Rémi Forax
+ * @author Michael Starzinger <michi@complang.tuwien.ac.at>
+ */
+public interface DexClassVisitor {
+
+    /**
+     * Visits the header of the class.
+     * @param access The access flags of the class.
+     * @param name The name of the class as a type descriptor.
+     * @param supername The name of the superclass as a type descriptor or
+     * {@code null} if the class has no superclass (i.e. only for definition of
+     * {@code java.lang.Object}).
+     * @param interfaces The names of implemented interfaces as type
+     * descriptors.
+     */
+    void visit(int access, String name, String supername, String[] interfaces);
+
+    /**
+     * Visits the source of the class.
+     * @param source The name of the file containing the original source for
+     * (at least most of) this class.
+     */
+    void visitSource(String source);
+
+    /**
+     * Visits a field of the class. In case this visitor is interested in
+     * further details about the field (i.e. annotations) it should return a
+     * new visitor object, otherwise it should return {@code null}.
+     * @param access The field's access flags.
+     * @param name The field's name.
+     * @param type The field's type as a type descriptor.
+     * @param value The field's initial value. This parameter can be a boxed
+     * primitive value, a {@code String} object or {@code null} if the field
+     * does not have an initial value. Is always {@code null} for instance
+     * fields.
+     * @return A visitor object for the field or {@code null} if this visitor
+     * is not interested in details about the field.
+     */
+    DexFieldVisitor visitField(int access, String name, String type,
+            Object value);
+
+    /**
+     * Visits a method of the class. In case this visitor is interested in
+     * further details about the method it should return a new visitor object,
+     * otherwise it should return {@code null}.
+     * @param access The method's access flags.
+     * @param name The method's name.
+     * @param shorty The method's prototype as a short form descriptor.
+     * @param returnType The method's return type as a type descriptor.
+     * @param parameterTypes The method's parameter types as type descriptors.
+     * @return A visitor object for the method or {@code null} if this visitor
+     * is not interested in details about the method.
+     */
+    DexMethodVisitor visitMethod(int access, String name, String shorty,
+            String returnType, String[] parameterTypes);
+
+    /**
+     * Visits the end of the class.
+     */
+    void visitEnd();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/icedrobot/daneel/dex/DexFieldVisitor.java	Fri Mar 11 20:33:43 2011 +0100
@@ -0,0 +1,32 @@
+/*
+ * Daneel - Dalvik to Java bytecode compiler
+ * Copyright (C) 2011  IcedRobot team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.icedrobot.daneel.dex;
+
+/**
+ * A visitor for fields contained in DEX files.
+ * @author Rémi Forax
+ * @author Michael Starzinger <michi@complang.tuwien.ac.at>
+ */
+public interface DexFieldVisitor {
+
+    /**
+     * Visits the end of the field.
+     */
+    void visitEnd();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/icedrobot/daneel/dex/DexFileVisitor.java	Fri Mar 11 20:33:43 2011 +0100
@@ -0,0 +1,42 @@
+/*
+ * Daneel - Dalvik to Java bytecode compiler
+ * Copyright (C) 2011  IcedRobot team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.icedrobot.daneel.dex;
+
+/**
+ * A visitor for DEX files.
+ * @author Rémi Forax
+ * @author Michael Starzinger <michi@complang.tuwien.ac.at>
+ */
+public interface DexFileVisitor {
+
+    /**
+     * Visits a class of the DEX file. In case this visitor is interested in
+     * further details about the class it should return a new visitor object,
+     * otherwise it should return {@code null}.
+     * @param name The name of the class as a type descriptor.
+     * @return A visitor object for the class or {@code null} if this visitor
+     * is not interested in details about the class.
+     */
+    DexClassVisitor visitClass(String name);
+
+    /**
+     * Visit the end of the DEX file.
+     */
+    void visitEnd();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/icedrobot/daneel/dex/DexMethodVisitor.java	Fri Mar 11 20:33:43 2011 +0100
@@ -0,0 +1,260 @@
+/*
+ * Daneel - Dalvik to Java bytecode compiler
+ * Copyright (C) 2011  IcedRobot team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General License for more details.
+ *
+ * You should have received a copy of the GNU General License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.icedrobot.daneel.dex;
+
+import java.util.Map;
+
+/**
+ * A visitor for methods contained in DEX files.
+ * @author Rémi Forax
+ * @author Michael Starzinger <michi@complang.tuwien.ac.at>
+ */
+public interface DexMethodVisitor {
+
+    /**
+     * Starts visiting the method's code. The code is visited by subsequent
+     * calls to {@code visitLabel()} and {@code visitInstr*()} methods.
+     */
+    void visitCode();
+
+    /**
+     * Visits a label. The given label refers to the instruction immediately
+     * following it. Labels can be used as branch targets or in try-catch
+     * blocks.
+     * @param label The target of a branch.
+     */
+    void visitLabel(Label label);
+
+    /**
+     * Visits an instruction with a {@code 10x} format id.
+     * @param opcode An opcode among NOP, RETURN_VOID.
+     */
+    void visitInstr(Opcode opcode);
+
+    /**
+     * Visits an instruction with a {@code 11x} format id.
+     * @param opcode An opcode among MOVE_RESULT, MOVE_RESULT_WIDE,
+     * MOVE_RESULT_OBJECT, MOVE_EXCEPTION, RETURN, MONITOR_ENTER, MONITOR_EXIT,
+     * RETURN_WIDE, RETURN_OBJECT, THROW.
+     * @param srcOrDst Source or destination register or register pair.
+     */
+    void visitInstrOp(Opcode opcode, int srcOrDst);
+
+    /**
+     * Visits an instruction with a {@code 12x|22x|32x} format id.
+     * @param opcode An opcode among MOVE, MOVE_FROM_16, MOVE_16, MOVE_WIDE,
+     * MOVE_WIDE_FROM_16, MOVE_WIDE_16, MOVE_OBJECT, MOVE_OBJECT_FROM_16,
+     * MOVE_OBJECT_16, NEG_INT, NOT_INT, NEG_LONG, NOT_LONG, NEG_FLOAT,
+     * NEG_DOUBLE, INT_TO_LONG, INT_TO_FLOAT, INT_TO_DOUBLE, LONG_TO_INT,
+     * LONG_TO_FLOAT, LONG_TO_DOUBLE, FLOAT_TO_INT, FLOAT_TO_LONG,
+     * DOUBLE_TO_INT, DOUBLE_TO_LONG, DOUBLE_TO_FLOAT, INT_TO_BYTE, INT_TO_CHAR,
+     * INT_TO_SHORT, ARRAY_LENGTH.
+     * @param vdest Destination register or register pair.
+     * @param vsrc Source register or register pair.
+     */
+    void visitInstrUnaryOp(Opcode opcode, int vdest, int vsrc);
+
+    /**
+     * Visits an instruction with a {@code 23x} format id.
+     * @param opcode An opcode among CMPL_FLOAT, CMPG_FLOAT, CMPL_DOUBLE,
+     * CMPG_DOUBLE, CMP_LONG, ADD_INT, SUB_INT, MUL_INT, DIV_INT, REM_INT,
+     * AND_INT, OR_INT, XOR_INT, SHL_INT, SHR_INT, USHR_INT, ADD_LONG, SUB_LONG,
+     * MUL_LONG, DIV_LONG, REM_LONG, AND_LONG, OR_LONG, XOR_LONG, SHL_LONG,
+     * SHR_LONG, USHR_LONG, ADD_FLOAT, SUB_FLOAT, MUL_FLOAT, DIV_FLOAT,
+     * REM_FLOAT, ADD_DOUBLE, SUB_DOUBLE, MUL_DOUBLE, DIV_DOUBLE, REM_DOUBLE,
+     * ADD_INT_2ADDR, SUB_INT_2ADDR, MUL_INT_2ADDR, DIV_INT_2ADDR,
+     * REM_INT_2ADDR, AND_INT_2ADDR, OR_INT_2ADDR, XOR_INT_2ADDR, SHL_INT_2ADDR,
+     * SHR_INT_2ADDR, USHR_INT_2ADDR, ADD_LONG_2ADDR, SUB_LONG_2ADDR,
+     * MUL_LONG_2ADDR, DIV_LONG_2ADDR, REM_LONG_2ADDR, AND_LONG_2ADDR,
+     * OR_LONG_2ADDR, XOR_LONG_2ADDR, SHL_LONG_2ADDR, SHR_LONG_2ADDR,
+     * USHR_LONG_2ADDR, ADD_FLOAT_2ADDR, SUB_FLOAT_2ADDR, MUL_FLOAT_2ADDR,
+     * DIV_FLOAT_2ADDR, REM_FLOAT_2ADDR, ADD_DOUBLE_2ADDR, SUB_DOUBLE_2ADDR,
+     * MUL_DOUBLE_2ADDR, DIV_DOUBLE_2ADDR, REM_DOUBLE_2ADDR.
+     * @param vdest Destination register or register pair.
+     * @param vsrc1 First source register or register pair.
+     * @param vsrc2 Second source register or register pair.
+     */
+    void visitInstrBinOp(Opcode opcode, int vdest, int vsrc, int vsrc2);
+
+    /**
+     * Visits an instruction with a {@code 22b|22s} format id.
+     * @param opcode An opcode among ADD_INT_LIT16, RSUB_INT_LIT16,
+     * MUL_INT_LIT16, DIV_INT_LIT16, REM_INT_LIT16, AND_INT_LIT16, OR_INT_LIT16,
+     * XOR_INT_LIT16, ADD_INT_LIT8, RSUB_INT_LIT8, MUL_INT_LIT8, DIV_INT_LIT8,
+     * REM_INT_LIT8, AND_INT_LIT8, OR_INT_LIT8, XOR_INT_LIT8, SHL_INT_LIT8,
+     * SHR_INT_LIT8, USHR_INT_LIT8.
+     * @param vdest Destination register or register pair.
+     * @param vsrc Source register or register pair.
+     * @param value Constant literal value.
+     */
+    void visitInstrBinOpAndLiteral(Opcode opcode, int vdest, int vsrc, int value);
+
+    /**
+     * Visits an instruction with a {@code 21c|31c} format id.
+     * @param opcode An opcode among CONST_STRING, CONST_STRING_JUMBO.
+     * @param vdest Destination register (no register pair).
+     * @param value Constant string literal value.
+     */
+    void visitInstrConstString(Opcode opcode, int vdest, String value);
+
+    /**
+     * Visits an instruction with a {@code 11n|21h|21s|31i} format id.
+     * @param opcode An opcode among CONST_4, CONST_16, CONST, CONST_HIGH16.
+     * @param vdest Destination register (no register pair).
+     * @param value Constant literal value.
+     */
+    void visitInstrConstU32(Opcode opcode, int vdest, int value);
+
+    /**
+     * Visits an instruction with a {@code 21h|21s|31i|51l} format id.
+     * @param opcode An opcode among CONST_WIDE_16, CONST_WIDE_32, CONST_WIDE,
+     * CONST_WIDE_HIGH16.
+     * @param vdest Destination register pair (no single register).
+     * @param value Constant literal value.
+     */
+    void visitInstrConstU64(Opcode opcode, int vdest, long value);
+
+    /**
+     * Visits an instruction with a {@code 21c} format id.
+     * @param opcode An opcode among CONST_CLASS, CHECK_CAST, NEW_INSTANCE.
+     * @param vdest Destination register (no register pair).
+     * @param type Constant type descriptor value.
+     */
+    void visitInstrClass(Opcode opcode, int vdest, String type);
+
+    /**
+     * Visits an instruction with a {@code 22c} format id.
+     * @param opcode The opcode INSTANCE_OF.
+     * @param vdest Destination register (no register pair).
+     * @param vsrc Source register (no register pair).
+     * @param type Constant type descriptor value.
+     */
+    void visitInstrInstanceof(Opcode opcode, int vdest, int vsrc, String type);
+
+    /**
+     * Visits an instruction with a {@code 10t|20t|30t} format id.
+     * @param opcode An opcode among GOTO_32, GOTO, GOTO_16.
+     * @param label The target of the branch.
+     */
+    void visitInstrGoto(Opcode opcode, Label label);
+
+    /**
+     * Visits an instruction with a {@code 21t} format id.
+     * @param opcode An opcode among IF_EQZ, IF_NEZ, IF_LTZ, IF_GEZ, IF_GTZ,
+     * IF_LEZ.
+     * @param vsrc Source register (no register pair).
+     * @param label The target of the branch.
+     */
+    void visitInstrIfTestZ(Opcode opcode, int vsrc, Label label);
+
+    /**
+     * Visits an instruction with a {@code 22t} format id.
+     * @param opcode An opcode among IF_EQ, IF_NE, IF_LT, IF_GE, IF_GT, IF_LE.
+     * @param vsrc1 First source register (no register pair).
+     * @param vsrc2 Second source register (no register pair).
+     * @param label The target of the branch.
+     */
+    void visitInstrIfTest(Opcode opcode, int vsrc1, int vsrc2, Label label);
+
+    /**
+     * Visits an instruction with a {@code 31t} format id.
+     * @param opcode An opcode among PACKED_SWITCH, SPARSE_SWITCH.
+     * @param vsrc Source register (no register pair).
+     * @param labels The target of the branch.
+     */
+    void visitInstrSwitch(Opcode opcode, int vsrc, Map<Integer, Label> labels);
+
+    /**
+     * Visits an instruction with a {@code 23x} format id.
+     * @param opcode An opcode among APUT, APUT_WIDE, APUT_OBJECT, APUT_BOOLEAN,
+     * APUT_BYTE, APUT_CHAR, APUT_SHORT, AGET, AGET_WIDE, AGET_OBJECT,
+     * AGET_BOOLEAN, AGET_BYTE, AGET_CHAR, AGET_SHORT.
+     * @param vsrcOrDest Source or destination register or register pair.
+     * @param varray The array register.
+     * @param vindex The index register.
+     */
+    void visitInstrArray(Opcode opcode, int vsrcOrDest, int varray, int vindex);
+
+    /**
+     * Visits an instruction with a {@code 21c|22c} format id.
+     * @param opcode opcode among IGET, IGET_WIDE, IGET_OBJECT, IGET_BOOLEAN,
+     * IGET_BYTE, IGET_CHAR, IGET_SHORT, IPUT, IPUT_WIDE, IPUT_OBJECT,
+     * IPUT_BOOLEAN, IPUT_BYTE, IPUT_CHAR, IPUT_SHORT, SGET, SGET_WIDE,
+     * SGET_OBJECT, SGET_BOOLEAN, SGET_BYTE, SGET_CHAR, SGET_SHORT, SPUT,
+     * SPUT_WIDE, SPUT_OBJECT, SPUT_BOOLEAN, SPUT_BYTE, SPUT_CHAR, SPUT_SHORT.
+     * @param vsrcOrDest Source or destination register or register pair.
+     * @param vref The object register in instance mode or 0 in static mode.
+     * @param owner The field's owner as type descriptor.
+     * @param name The fied's name.
+     * @param desc The field's type descriptor.
+     */
+    void visitInstrField(Opcode opcode, int vsrcOrDest, int vref, String owner,
+            String name, String desc);
+
+    /**
+     * Visits an instruction with a {@code 35c|3rc} format id.
+     * @param opcode An opcode among INVOKE_VIRTUAL, INVOKE_SUPER,
+     * INVOKE_DIRECT, INVOKE_STATIC, INVOKE_INTERFACE, INVOKE_VIRTUAL_RANGE,
+     * INVOKE_SUPER_RANGE, INVOKE_DIRECT_RANGE, INVOKE_STATIC_RANGE,
+     * INVOKE_INTERFACE_RANGE.
+     * @param num The number of registers involved.
+     * @param va Register A in normal mode or first register in range mode.
+     * @param vpacked Register D,E,F,G (4 bits each) in normal mode or 0 in
+     * range mode.
+     * @param owner The method's owner as type descriptor.
+     * @param name The method's name.
+     * @param desc The method's type descriptor.
+     */
+    void visitInstrMethod(Opcode opcode, int num, int va, int vpacked,
+            String owner, String name, String desc);
+
+    /**
+     * Visits an instruction with a {@code 35c|3rc} format id.
+     * @param opcode An opcode among FILLED_NEW_ARRAY, FILLED_NEW_ARRAY_RANGE.
+     * @param num The number of registers involved.
+     * @param va Register A in normal mode or first register in range mode.
+     * @param vpacked Register D,E,F,G (4 bits each) in normal mode or 0 in
+     * range mode.
+     * @param type Constant type descriptor value.
+     */
+    void visitInstrFilledNewArray(Opcode opcode, int num, int va, int vpacked,
+            String type);
+
+    /**
+     * Visits an instruction with a {@code 22c} format id.
+     * @param opcode The opcode NEW_ARRAY.
+     * @param vdest Destination register (no register pair).
+     * @param vsize The size register.
+     * @param type Constant type descriptor value.
+     */
+    void visitInstrNewArray(Opcode opcode, int vdest, int vsize, String type);
+
+    /**
+     * Visits an instruction with a {@code 31t} format id.
+     * @param opcode The opcode FILL_ARRAY_DATA.
+     * @param vsrc The array register.
+     * @param arrayData XXX Specify me!
+     */
+    void visitInstrFillArrayData(Opcode opcode, int vsrc, Object arrayData);
+
+    /**
+     * Visits the end of the method.
+     */
+    void visitEnd();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/icedrobot/daneel/dex/Label.java	Fri Mar 11 20:33:43 2011 +0100
@@ -0,0 +1,27 @@
+/*
+ * Daneel - Dalvik to Java bytecode compiler
+ * Copyright (C) 2011  IcedRobot team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General License for more details.
+ *
+ * You should have received a copy of the GNU General License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.icedrobot.daneel.dex;
+
+/**
+ * A label referencing a certain position in Dalvik VM bytecode.
+ * @author Rémi Forax
+ */
+public class Label {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/org/icedrobot/daneel/dex/Opcode.java	Fri Mar 11 20:33:43 2011 +0100
@@ -0,0 +1,298 @@
+/*
+ * Daneel - Dalvik to Java bytecode compiler
+ * Copyright (C) 2011  IcedRobot team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General License for more details.
+ *
+ * You should have received a copy of the GNU General License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.icedrobot.daneel.dex;
+
+/**
+ * Enumeration of all opcodes available in Dalvik VM bytecode.
+ * @author Rémi Forax
+ */
+public enum Opcode {
+    NOP(0x00),
+    MOVE(0x01),
+    MOVE_FROM16(0x02),
+    MOVE_16(0x03),
+    MOVE_WIDE(0x04),
+    MOVE_WIDE_FROM16(0x05),
+    MOVE_WIDE_16(0x06),
+    MOVE_OBJECT(0x07),
+    MOVE_OBJECT_FROM16(0x08),
+    MOVE_OBJECT_16(0x09),
+    MOVE_RESULT(0x0a),
+    MOVE_RESULT_WIDE(0x0b),
+    MOVE_RESULT_OBJECT(0x0c),
+    MOVE_EXCEPTION(0x0d),
+    RETURN_VOID(0x0e),
+    RETURN(0x0f),
+    RETURN_WIDE(0x10),
+    RETURN_OBJECT(0x11),
+    CONST_4(0x12),
+    CONST_16(0x13),
+    CONST(0x14),
+    CONST_HIGH16(0x15),
+    CONST_WIDE_16(0x16),
+    CONST_WIDE_32(0x17),
+    CONST_WIDE(0x18),
+    CONST_WIDE_HIGH16(0x19),
+    CONST_STRING(0x1a),
+    CONST_STRING_JUMBO(0x1b),
+    CONST_CLASS(0x1c),
+    MONITOR_ENTER(0x1d),
+    MONITOR_EXIT(0x1e),
+    CHECK_CAST(0x1f),
+    INSTANCE_OF(0x20),
+    ARRAY_LENGTH(0x21),
+    NEW_INSTANCE(0x22),
+    NEW_ARRAY(0x23),
+    FILLED_NEW_ARRAY(0x24),
+    FILLED_NEW_ARRAY_RANGE(0x25),
+    FILL_ARRAY_DATA(0x26),
+    THROW(0x27),
+    GOTO(0x28),
+    GOTO_16(0x29),
+    GOTO_32(0x2a),
+    PACKED_SWITCH(0x2b),
+    SPARSE_SWITCH(0x2c),
+    CMPL_FLOAT(0x2d),
+    CMPG_FLOAT(0x2e),
+    CMPL_DOUBLE(0x2f),
+    CMPG_DOUBLE(0x30),
+    CMP_LONG(0x31),
+    IF_EQ(0x32),
+    IF_NE(0x33),
+    IF_LT(0x34),
+    IF_GE(0x35),
+    IF_GT(0x36),
+    IF_LE(0x37),
+    IF_EQZ(0x38),
+    IF_NEZ(0x39),
+    IF_LTZ(0x3a),
+    IF_GEZ(0x3b),
+    IF_GTZ(0x3c),
+    IF_LEZ(0x3d),
+    UNUSED_3E(0x3e),
+    UNUSED_3F(0x3f),
+    UNUSED_40(0x40),
+    UNUSED_41(0x41),
+    UNUSED_42(0x42),
+    UNUSED_43(0x43),
+    AGET(0x44),
+    AGET_WIDE(0x45),
+    AGET_OBJECT(0x46),
+    AGET_BOOLEAN(0x47),
+    AGET_BYTE(0x48),
+    AGET_CHAR(0x49),
+    AGET_SHORT(0x4a),
+    APUT(0x4b),
+    APUT_WIDE(0x4c),
+    APUT_OBJECT(0x4d),
+    APUT_BOOLEAN(0x4e),
+    APUT_BYTE(0x4f),
+    APUT_CHAR(0x50),
+    APUT_SHORT(0x51),
+    IGET(0x52),
+    IGET_WIDE(0x53),
+    IGET_OBJECT(0x54),
+    IGET_BOOLEAN(0x55),
+    IGET_BYTE(0x56),
+    IGET_CHAR(0x57),
+    IGET_SHORT(0x58),
+    IPUT(0x59),
+    IPUT_WIDE(0x5a),
+    IPUT_OBJECT(0x5b),
+    IPUT_BOOLEAN(0x5c),
+    IPUT_BYTE(0x5d),
+    IPUT_CHAR(0x5e),
+    IPUT_SHORT(0x5f),
+    SGET(0x60),
+    SGET_WIDE(0x61),
+    SGET_OBJECT(0x62),
+    SGET_BOOLEAN(0x63),
+    SGET_BYTE(0x64),
+    SGET_CHAR(0x65),
+    SGET_SHORT(0x66),
+    SPUT(0x67),
+    SPUT_WIDE(0x68),
+    SPUT_OBJECT(0x69),
+    SPUT_BOOLEAN(0x6a),
+    SPUT_BYTE(0x6b),
+    SPUT_CHAR(0x6c),
+    SPUT_SHORT(0x6d),
+    INVOKE_VIRTUAL(0x6e),
+    INVOKE_SUPER(0x6f),
+    INVOKE_DIRECT(0x70),
+    INVOKE_STATIC(0x71),
+    INVOKE_INTERFACE(0x72),
+    UNUSED_73(0x73),
+    INVOKE_VIRTUAL_RANGE(0x74),
+    INVOKE_SUPER_RANGE(0x75),
+    INVOKE_DIRECT_RANGE(0x76),
+    INVOKE_STATIC_RANGE(0x77),
+    INVOKE_INTERFACE_RANGE(0x78),
+    UNUSED_79(0x79),
+    UNUSED_7A(0x7a),
+    NEG_INT(0x7b),
+    NOT_INT(0x7c),
+    NEG_LONG(0x7d),
+    NOT_LONG(0x7e),
+    NEG_FLOAT(0x7f),
+    NEG_DOUBLE(0x80),
+    INT_TO_LONG(0x81),
+    INT_TO_FLOAT(0x82),
+    INT_TO_DOUBLE(0x83),
+    LONG_TO_INT(0x84),
+    LONG_TO_FLOAT(0x85),
+    LONG_TO_DOUBLE(0x86),
+    FLOAT_TO_INT(0x87),
+    FLOAT_TO_LONG(0x88),
+    FLOAT_TO_DOUBLE(0x89),
+    DOUBLE_TO_INT(0x8a),
+    DOUBLE_TO_LONG(0x8b),
+    DOUBLE_TO_FLOAT(0x8c),
+    INT_TO_BYTE(0x8d),
+    INT_TO_CHAR(0x8e),
+    INT_TO_SHORT(0x8f),
+    ADD_INT(0x90),
+    SUB_INT(0x91),
+    MUL_INT(0x92),
+    DIV_INT(0x93),
+    REM_INT(0x94),
+    AND_INT(0x95),
+    OR_INT(0x96),
+    XOR_INT(0x97),
+    SHL_INT(0x98),
+    SHR_INT(0x99),
+    USHR_INT(0x9a),
+    ADD_LONG(0x9b),
+    SUB_LONG(0x9c),
+    MUL_LONG(0x9d),
+    DIV_LONG(0x9e),
+    REM_LONG(0x9f),
+    AND_LONG(0xa0),
+    OR_LONG(0xa1),
+    XOR_LONG(0xa2),
+    SHL_LONG(0xa3),
+    SHR_LONG(0xa4),
+    USHR_LONG(0xa5),
+    ADD_FLOAT(0xa6),
+    SUB_FLOAT(0xa7),
+    MUL_FLOAT(0xa8),
+    DIV_FLOAT(0xa9),
+    REM_FLOAT(0xaa),
+    ADD_DOUBLE(0xab),
+    SUB_DOUBLE(0xac),
+    MUL_DOUBLE(0xad),
+    DIV_DOUBLE(0xae),
+    REM_DOUBLE(0xaf),
+    ADD_INT_2ADDR(0xb0),
+    SUB_INT_2ADDR(0xb1),
+    MUL_INT_2ADDR(0xb2),
+    DIV_INT_2ADDR(0xb3),
+    REM_INT_2ADDR(0xb4),
+    AND_INT_2ADDR(0xb5),
+    OR_INT_2ADDR(0xb6),
+    XOR_INT_2ADDR(0xb7),
+    SHL_INT_2ADDR(0xb8),
+    SHR_INT_2ADDR(0xb9),
+    USHR_INT_2ADDR(0xba),
+    ADD_LONG_2ADDR(0xbb),
+    SUB_LONG_2ADDR(0xbc),
+    MUL_LONG_2ADDR(0xbd),
+    DIV_LONG_2ADDR(0xbe),
+    REM_LONG_2ADDR(0xbf),
+    AND_LONG_2ADDR(0xc0),
+    OR_LONG_2ADDR(0xc1),
+    XOR_LONG_2ADDR(0xc2),
+    SHL_LONG_2ADDR(0xc3),
+    SHR_LONG_2ADDR(0xc4),
+    USHR_LONG_2ADDR(0xc5),
+    ADD_FLOAT_2ADDR(0xc6),
+    SUB_FLOAT_2ADDR(0xc7),
+    MUL_FLOAT_2ADDR(0xc8),
+    DIV_FLOAT_2ADDR(0xc9),
+    REM_FLOAT_2ADDR(0xca),
+    ADD_DOUBLE_2ADDR(0xcb),
+    SUB_DOUBLE_2ADDR(0xcc),
+    MUL_DOUBLE_2ADDR(0xcd),
+    DIV_DOUBLE_2ADDR(0xce),
+    REM_DOUBLE_2ADDR(0xcf),
+    ADD_INT_LIT16(0xd0),
+    RSUB_INT(0xd1),
+    MUL_INT_LIT16(0xd2),
+    DIV_INT_LIT16(0xd3),
+    REM_INT_LIT16(0xd4),
+    AND_INT_LIT16(0xd5),
+    OR_INT_LIT16(0xd6),
+    XOR_INT_LIT16(0xd7),
+    ADD_INT_LIT8(0xd8),
+    RSUB_INT_LIT8(0xd9),
+    MUL_INT_LIT8(0xda),
+    DIV_INT_LIT8(0xdb),
+    REM_INT_LIT8(0xdc),
+    AND_INT_LIT8(0xdd),
+    OR_INT_LIT8(0xde),
+    XOR_INT_LIT8(0xdf),
+    SHL_INT_LIT8(0xe0),
+    SHR_INT_LIT8(0xe1),
+    USHR_INT_LIT8(0xe2),
+    IGET_VOLATILE(0xe3),
+    IPUT_VOLATILE(0xe4),
+    SGET_VOLATILE(0xe5),
+    SPUT_VOLATILE(0xe6),
+    IGET_OBJECT_VOLATILE(0xe7),
+    IGET_WIDE_VOLATILE(0xe8),
+    IPUT_WIDE_VOLATILE(0xe9),
+    SGET_WIDE_VOLATILE(0xea),
+    SPUT_WIDE_VOLATILE(0xeb),
+    UNUSED_EC(0xec),
+    UNUSED_ED(0xed),
+    EXECUTE_INLINE(0xee),
+    EXECUTE_INLINE_RANGE(0xef),
+    INVOKE_DIRECT_EMPTY(0xf0),
+    IGET_QUICK(0xf2),
+    IGET_WIDE_QUICK(0xf3),
+    IGET_OBJECT_QUICK(0xf4),
+    IPUT_QUICK(0xf5),
+    IPUT_WIDE_QUICK(0xf6),
+    IPUT_OBJECT_QUICK(0xf7),
+    INVOKE_VIRTUAL_QUICK(0xf8),
+    INVOKE_VIRTUAL_QUICK_RANGE(0xf9),
+    INVOKE_SUPER_QUICK(0xfa),
+    INVOKE_SUPER_QUICK_RANGE(0xfb),
+    IPUT_OBJECT_VOLATILE(0xfc),
+    SGET_OBJECT_VOLATILE(0xfd),
+    SPUT_OBJECT_VOLATILE(0xfe),
+    UNUSED_FF(0xff);
+
+    private final static Opcode[] OPCODES = Opcode.values();
+
+    public static Opcode getOpcode(int opcode) {
+        return OPCODES[opcode];
+    }
+
+    private final int op;
+
+    private Opcode(int op) {
+        this.op = op;
+    }
+
+    @Override
+    public String toString() {
+        return name() + '(' + op + ')';
+    }
+}