use num_enum::TryFromPrimitive;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
#[repr(u8)]
pub enum Opcode {
Aaload = 0x32,
Aastore = 0x53,
AconstNull = 0x01,
Aload = 0x19,
Aload0 = 0x2A,
Aload1 = 0x2B,
Aload2 = 0x2C,
Aload3 = 0x2D,
Anewarray = 0xBD,
Areturn = 0xB0,
ArrayLength = 0xBE,
Astore = 0x3A,
Astore0 = 0x4B,
Astore1 = 0x4C,
Astore2 = 0x4D,
Astore3 = 0x4E,
Athrow = 0xBF,
Baload = 0x33,
Bastore = 0x54,
Bipush = 0x10,
Breakpoint = 0xCA,
Caload = 0x34,
Castore = 0x55,
Checkcast = 0xC0,
D2f = 0x90,
D2i = 0x8E,
D2l = 0x8F,
Dadd = 0x63,
Daload = 0x31,
Dastore = 0x52,
Dcmpg = 0x98,
Dcmpl = 0x97,
Dconst0 = 0x0E,
Dconst1 = 0x0F,
Ddiv = 0x6F,
Dload = 0x18,
Dload0 = 0x26,
Dload1 = 0x27,
Dload2 = 0x28,
Dload3 = 0x29,
Dmul = 0x6B,
Dneg = 0x77,
Drem = 0x73,
Dreturn = 0xAF,
Dstore = 0x39,
Dstore0 = 0x47,
Dstore1 = 0x48,
Dstore2 = 0x49,
Dstore3 = 0x4A,
Dsub = 0x67,
Dup = 0x59,
DupX1 = 0x5A,
DupX2 = 0x5B,
Dup2 = 0x5C,
Dup2X1 = 0x5D,
Dup2X2 = 0x5E,
F2d = 0x8D,
F2i = 0x8B,
F2l = 0x8C,
Fadd = 0x62,
Faload = 0x30,
Fastore = 0x51,
Fcmpg = 0x96,
Fcmpl = 0x95,
Fconst0 = 0x0B,
Fconst1 = 0x0C,
Fconst2 = 0x0D,
Fdiv = 0x6E,
Fload = 0x17,
Fload0 = 0x22,
Fload1 = 0x23,
Fload2 = 0x24,
Fload3 = 0x25,
Fmul = 0x6A,
Fneg = 0x76,
Frem = 0x72,
Freturn = 0xAE,
Fstore = 0x38,
Fstore0 = 0x43,
Fstore1 = 0x44,
Fstore2 = 0x45,
Fstore3 = 0x46,
Fsub = 0x66,
Getfield = 0xB4,
Getstatic = 0xB2,
Goto = 0xA7,
GotoW = 0xC8,
I2b = 0x91,
I2c = 0x92,
I2d = 0x87,
I2f = 0x86,
I2l = 0x85,
I2s = 0x93,
Iadd = 0x60,
Iaload = 0x2E,
Iand = 0x7E,
Iastore = 0x4F,
IconstM1 = 0x02,
Iconst0 = 0x03,
Iconst1 = 0x04,
Iconst2 = 0x05,
Iconst3 = 0x06,
Iconst4 = 0x07,
Iconst5 = 0x08,
Idiv = 0x6C,
IfAcmpEq = 0xA5,
IfAcmpNe = 0xA6,
IfIcmpeq = 0x9F,
IfIcmpge = 0xA2,
IfIcmpgt = 0xA3,
IfIcmple = 0xA4,
IfIcmplt = 0xA1,
IfIcmpne = 0xA0,
IfEq = 0x99,
IfGe = 0x9C,
IfGt = 0x9D,
IfLe = 0x9E,
IfLt = 0x9B,
IfNe = 0x9A,
Ifnonnull = 0xC7,
Ifnull = 0xC6,
Iinc = 0x84,
Iload = 0x15,
Iload0 = 0x1A,
Iload1 = 0x1B,
Iload2 = 0x1C,
Iload3 = 0x1D,
Imul = 0x68,
Ineg = 0x74,
Instanceof = 0xC1,
InvokeDynamic = 0xBA,
InvokeInterface = 0xB9,
InvokeSpecial = 0xB7,
InvokeStatic = 0xB8,
InvokeVirtual = 0xB6,
Ior = 0x80,
Irem = 0x70,
Ireturn = 0xAC,
Ishl = 0x78,
Ishr = 0x7A,
Istore = 0x36,
Istore0 = 0x3B,
Istore1 = 0x3C,
Istore2 = 0x3D,
Istore3 = 0x3E,
Isub = 0x64,
Iushr = 0x7C,
Ixor = 0x82,
Jsr = 0xA8,
JsrW = 0xC9,
L2d = 0x8A,
L2f = 0x89,
L2i = 0x88,
Ladd = 0x61,
Laload = 0x2F,
Land = 0x7F,
Lastore = 0x50,
Lcmp = 0x94,
Lconst0 = 0x09,
Lconst1 = 0x0A,
Ldc = 0x12,
LdcW = 0x13,
Ldc2W = 0x14,
Ldiv = 0x6D,
Lload = 0x16,
Lload0 = 0x1E,
Lload1 = 0x1F,
Lload2 = 0x20,
Lload3 = 0x21,
Lmul = 0x69,
Lneg = 0x75,
Lookupswitch = 0xAB,
Lor = 0x81,
Lrem = 0x71,
Lreturn = 0xAD,
Lshl = 0x79,
Lshr = 0x7B,
Lstore = 0x37,
Lstore0 = 0x3F,
Lstore1 = 0x40,
Lstore2 = 0x41,
Lstore3 = 0x42,
Lsub = 0x65,
Lushr = 0x7D,
Lxor = 0x83,
Monitorenter = 0xC2,
Monitorexit = 0xC3,
Multianewarray = 0xC5,
New = 0xBB,
Newarray = 0xBC,
Nop = 0x00,
Pop = 0x57,
Pop2 = 0x58,
Putfield = 0xB5,
Putstatic = 0xB3,
Ret = 0xA9,
Return = 0xB1,
Saload = 0x35,
Sastore = 0x56,
Sipush = 0x11,
Swap = 0x5F,
TableSwitch = 0xAA,
}
impl Opcode {
pub const fn as_str(self) -> &'static str {
match self {
Self::Aaload => "aaload",
Self::Aastore => "aastore",
Self::AconstNull => "aconst_null",
Self::Aload => "aload",
Self::Aload0 => "aload_0",
Self::Aload1 => "aload_1",
Self::Aload2 => "aload_2",
Self::Aload3 => "aload_3",
Self::Anewarray => "anewarray",
Self::Areturn => "areturn",
Self::ArrayLength => "arraylength",
Self::Astore => "astore",
Self::Astore0 => "astore_0",
Self::Astore1 => "astore_1",
Self::Astore2 => "astore_2",
Self::Astore3 => "astore_3",
Self::Athrow => "athrow",
Self::Baload => "baload",
Self::Bastore => "bastore",
Self::Bipush => "bipush",
Self::Breakpoint => "breakpoint",
Self::Caload => "caload",
Self::Castore => "castore",
Self::Checkcast => "checkcast",
Self::D2f => "d2f",
Self::D2i => "d2i",
Self::D2l => "d2l",
Self::Dadd => "dadd",
Self::Daload => "daload",
Self::Dastore => "dastore",
Self::Dcmpg => "dcmpg",
Self::Dcmpl => "dcmpl",
Self::Dconst0 => "dconst_0",
Self::Dconst1 => "dconst_1",
Self::Ddiv => "ddiv",
Self::Dload => "dload",
Self::Dload0 => "dload_0",
Self::Dload1 => "dload_1",
Self::Dload2 => "dload_2",
Self::Dload3 => "dload_3",
Self::Dmul => "dmul",
Self::Dneg => "dneg",
Self::Drem => "drem",
Self::Dreturn => "dreturn",
Self::Dstore => "dstore",
Self::Dstore0 => "dstore_0",
Self::Dstore1 => "dstore_1",
Self::Dstore2 => "dstore_2",
Self::Dstore3 => "dstore_3",
Self::Dsub => "dsub",
Self::Dup => "dup",
Self::DupX1 => "dup_x1",
Self::DupX2 => "dup_x2",
Self::Dup2 => "dup2",
Self::Dup2X1 => "dup2_x1",
Self::Dup2X2 => "dup2_x2",
Self::F2d => "f2d",
Self::F2i => "f2i",
Self::F2l => "f2l",
Self::Fadd => "fadd",
Self::Faload => "faload",
Self::Fastore => "fastore",
Self::Fcmpg => "fcmpg",
Self::Fcmpl => "fcmpl",
Self::Fconst0 => "fconst_0",
Self::Fconst1 => "fconst_1",
Self::Fconst2 => "fconst_2",
Self::Fdiv => "fdiv",
Self::Fload => "fload",
Self::Fload0 => "fload_0",
Self::Fload1 => "fload_1",
Self::Fload2 => "fload_2",
Self::Fload3 => "fload_3",
Self::Fmul => "fmul",
Self::Fneg => "fneg",
Self::Frem => "frem",
Self::Freturn => "freturn",
Self::Fstore => "fstore",
Self::Fstore0 => "fstore_0",
Self::Fstore1 => "fstore_1",
Self::Fstore2 => "fstore_2",
Self::Fstore3 => "fstore_3",
Self::Fsub => "fsub",
Self::Getfield => "getfield",
Self::Getstatic => "getstatic",
Self::Goto => "goto",
Self::GotoW => "goto_w",
Self::I2b => "i2b",
Self::I2c => "i2c",
Self::I2d => "i2d",
Self::I2f => "i2f",
Self::I2l => "i2l",
Self::I2s => "i2s",
Self::Iadd => "iadd",
Self::Iaload => "iaload",
Self::Iand => "iand",
Self::Iastore => "iastore",
Self::IconstM1 => "iconst_m1",
Self::Iconst0 => "iconst_0",
Self::Iconst1 => "iconst_1",
Self::Iconst2 => "iconst_2",
Self::Iconst3 => "iconst_3",
Self::Iconst4 => "iconst_4",
Self::Iconst5 => "iconst_5",
Self::Idiv => "idiv",
Self::IfAcmpEq => "if_acmpeq",
Self::IfAcmpNe => "if_acmpne",
Self::IfIcmpeq => "if_icmpeq",
Self::IfIcmpge => "if_icmpge",
Self::IfIcmpgt => "if_icmpgt",
Self::IfIcmple => "if_icmple",
Self::IfIcmplt => "if_icmplt",
Self::IfIcmpne => "if_icmpne",
Self::IfEq => "ifeq",
Self::IfGe => "ifge",
Self::IfGt => "ifgt",
Self::IfLe => "ifle",
Self::IfLt => "iflt",
Self::IfNe => "ifne",
Self::Ifnonnull => "ifnonnull",
Self::Ifnull => "ifnull",
Self::Iinc => "iinc",
Self::Iload => "iload",
Self::Iload0 => "iload_0",
Self::Iload1 => "iload_1",
Self::Iload2 => "iload_2",
Self::Iload3 => "iload_3",
Self::Imul => "imul",
Self::Ineg => "ineg",
Self::Instanceof => "instanceof",
Self::InvokeDynamic => "invokedynamic",
Self::InvokeInterface => "invokeinterface",
Self::InvokeSpecial => "invokespecial",
Self::InvokeStatic => "invokestatic",
Self::InvokeVirtual => "invokevirtual",
Self::Ior => "ior",
Self::Irem => "irem",
Self::Ireturn => "ireturn",
Self::Ishl => "ishl",
Self::Ishr => "ishr",
Self::Istore => "istore",
Self::Istore0 => "istore_0",
Self::Istore1 => "istore_1",
Self::Istore2 => "istore_2",
Self::Istore3 => "istore_3",
Self::Isub => "isub",
Self::Iushr => "iushr",
Self::Ixor => "ixor",
Self::Jsr => "jsr",
Self::JsrW => "jsr_w",
Self::L2d => "l2d",
Self::L2f => "l2f",
Self::L2i => "l2i",
Self::Ladd => "ladd",
Self::Laload => "laload",
Self::Land => "land",
Self::Lastore => "lastore",
Self::Lcmp => "lcmp",
Self::Lconst0 => "lconst_0",
Self::Lconst1 => "lconst_1",
Self::Ldc => "ldc",
Self::LdcW => "ldc_w",
Self::Ldc2W => "ldc2_w",
Self::Ldiv => "ldiv",
Self::Lload => "lload",
Self::Lload0 => "lload_0",
Self::Lload1 => "lload_1",
Self::Lload2 => "lload_2",
Self::Lload3 => "lload_3",
Self::Lmul => "lmul",
Self::Lneg => "lneg",
Self::Lookupswitch => "lookupswitch",
Self::Lor => "lor",
Self::Lrem => "lrem",
Self::Lreturn => "lreturn",
Self::Lshl => "lshl",
Self::Lshr => "lshr",
Self::Lstore => "lstore",
Self::Lstore0 => "lstore_0",
Self::Lstore1 => "lstore_1",
Self::Lstore2 => "lstore_2",
Self::Lstore3 => "lstore_3",
Self::Lsub => "lsub",
Self::Lushr => "lushr",
Self::Lxor => "lxor",
Self::Monitorenter => "monitorenter",
Self::Monitorexit => "monitorexit",
Self::Multianewarray => "multianewarray",
Self::New => "new",
Self::Newarray => "newarray",
Self::Nop => "nop",
Self::Pop => "pop",
Self::Pop2 => "pop2",
Self::Putfield => "putfield",
Self::Putstatic => "putstatic",
Self::Ret => "ret",
Self::Return => "return",
Self::Saload => "saload",
Self::Sastore => "sastore",
Self::Sipush => "sipush",
Self::Swap => "swap",
Self::TableSwitch => "tableswitch",
}
}
}
impl Opcode {
pub const fn operand_size(self) -> u8 {
match self {
Self::GotoW | Self::JsrW | Self::InvokeDynamic | Self::InvokeInterface => 4,
Self::Multianewarray => 3,
Self::Anewarray
| Self::Checkcast
| Self::Getfield
| Self::Getstatic
| Self::Goto
| Self::IfAcmpEq
| Self::IfAcmpNe
| Self::IfEq
| Self::IfGe
| Self::IfGt
| Self::IfLe
| Self::IfLt
| Self::IfNe
| Self::Ifnonnull
| Self::Ifnull
| Self::IfIcmpeq
| Self::IfIcmpge
| Self::IfIcmpgt
| Self::IfIcmple
| Self::IfIcmplt
| Self::IfIcmpne
| Self::Iinc
| Self::Instanceof
| Self::InvokeSpecial
| Self::InvokeStatic
| Self::InvokeVirtual
| Self::Ldc2W
| Self::LdcW
| Self::New
| Self::Putfield
| Self::Putstatic
| Self::Sipush
| Self::Jsr => 2,
Self::Aload
| Self::Astore
| Self::Bipush
| Self::Dload
| Self::Dstore
| Self::Fload
| Self::Fstore
| Self::Iload
| Self::Istore
| Self::Ldc
| Self::Lload
| Self::Lstore
| Self::Newarray
| Self::Ret => 1,
_ => 0,
}
}
pub const fn pc_size(self) -> Option<u8> {
match self {
Self::Lookupswitch | Self::TableSwitch => None,
_ => Some(1 + self.operand_size()),
}
}
}
impl std::fmt::Display for Opcode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}