{-# LANGUAGE LambdaCase #-}

module JVM.Data.Raw.Instruction where

import Data.Binary.Put
import Data.Binary.Write (WriteBinary (writeBinary))
import Data.Word
import JVM.Data.Raw.MagicNumbers qualified as MagicNumbers
import JVM.Data.Raw.Types

data Instruction
    = AALoad
    | AAStore
    | AConstNull
    | ALoad U1
    | ALoad0
    | ALoad1
    | ALoad2
    | ALoad3
    | ANewArray ConstantPoolIndex
    | AReturn
    | ArrayLength
    | AStore U1
    | AStore0
    | AStore1
    | AStore2
    | AStore3
    | AThrow
    | BALoad
    | BAStore
    | BIPush Word8
    | CALoad
    | CAStore
    | CheckCast ConstantPoolIndex
    | D2F
    | D2I
    | D2L
    | DAdd
    | DALoad
    | DAStore
    | DCmpG
    | DCmpL
    | DConst0
    | DConst1
    | DDiv
    | DLoad
    | DLoad0
    | DLoad1
    | DLoad2
    | DLoad3
    | DMul
    | DNeg
    | DRem
    | DReturn
    | DStore
    | DStore0
    | DStore1
    | DStore2
    | DStore3
    | DSub
    | Dup
    | DupX1
    | DupX2
    | Dup2
    | Dup2X1
    | Dup2X2
    | F2D
    | F2I
    | F2L
    | FAdd
    | FALoad
    | FAStore
    | FCmpG
    | FCmpL
    | FConst0
    | FConst1
    | FConst2
    | FDiv
    | FLoad
    | FLoad0
    | FLoad1
    | FLoad2
    | FLoad3
    | FMul
    | FNeg
    | FRem
    | FReturn
    | FStore
    | FStore0
    | FStore1
    | FStore2
    | FStore3
    | FSub
    | GetField ConstantPoolIndex
    | GetStatic ConstantPoolIndex
    | Goto Word16
    | GotoW Word32
    | I2B
    | I2C
    | I2D
    | I2F
    | I2L
    | I2S
    | IAdd
    | IALoad
    | IAnd
    | IAStore
    | IConstM1
    | IConst0
    | IConst1
    | IConst2
    | IConst3
    | IConst4
    | IConst5
    | IDiv
    | -- | if_acmpeq
      IfAcmpEq Word16
    | {- | if_acmpne
      Branch if int comparison succeeds
      -}
      IfAcmpNe Word16
    | IfIcmpEq Word16
    | IfIcmpNe Word16
    | IfIcmpLt Word16
    | IfIcmpGe Word16
    | IfIcmpGt Word16
    | IfIcmpLe Word16
    | IfEq Word16
    | IfNe Word16
    | IfLt Word16
    | IfGe Word16
    | IfGt Word16
    | IfLe Word16
    | IfNonNull Word16
    | IfNull Word16
    | IInc Word8 Word8
    | ILoad U1
    | ILoad0
    | ILoad1
    | ILoad2
    | ILoad3
    | IMul
    | INeg
    | Instanceof ConstantPoolIndex
    | InvokeDynamic ConstantPoolIndex
    | InvokeInterface ConstantPoolIndex Word8
    | InvokeSpecial ConstantPoolIndex
    | InvokeStatic ConstantPoolIndex
    | InvokeVirtual ConstantPoolIndex
    | IOr
    | IRem
    | IReturn
    | IShl
    | IShr
    | IStore0
    | IStore1
    | IStore2
    | IStore3
    | IStore U1
    | ISub
    | IUShr
    | IXor
    | JSR Word16
    | JSR_W Word32
    | L2D
    | L2F
    | L2I
    | LAdd
    | LALoad
    | LAnd
    | LCmp
    | LConst0
    | LConst1
    | LDC U1
    | LDC2_W ConstantPoolIndex
    | LDC_W ConstantPoolIndex
    | LDiv
    | LLoad
    | LLoad0
    | LLoad1
    | LLoad2
    | LLoad3
    | LMul
    | LNeg
    | LookupSwitch Word32 [(Word32, Word32)]
    | LOr
    | LRem
    | LReturn
    | LShl
    | LShr
    | LStore
    | LStore0
    | LStore1
    | LStore2
    | LStore3
    | LSub
    | LUShr
    | LXor
    | MonitorEnter
    | MonitorExit
    | MultiANewArray ConstantPoolIndex Word8
    | New ConstantPoolIndex
    | NewArray ArrayType
    | NOP
    | Pop
    | Pop2
    | PutField ConstantPoolIndex
    | PutStatic ConstantPoolIndex
    | Ret Word8
    | Return
    | SALoad
    | SAStore
    | SIPush Word16
    | Swap
    | TableSwitch Word32 Word32 Word32 [(Word32, Word32)]
    | Wide1 U1 U2
    | WideIInc U2 U2
    deriving (Instruction -> Instruction -> Bool
(Instruction -> Instruction -> Bool)
-> (Instruction -> Instruction -> Bool) -> Eq Instruction
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Instruction -> Instruction -> Bool
== :: Instruction -> Instruction -> Bool
$c/= :: Instruction -> Instruction -> Bool
/= :: Instruction -> Instruction -> Bool
Eq, Int -> Instruction -> ShowS
[Instruction] -> ShowS
Instruction -> String
(Int -> Instruction -> ShowS)
-> (Instruction -> String)
-> ([Instruction] -> ShowS)
-> Show Instruction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Instruction -> ShowS
showsPrec :: Int -> Instruction -> ShowS
$cshow :: Instruction -> String
show :: Instruction -> String
$cshowList :: [Instruction] -> ShowS
showList :: [Instruction] -> ShowS
Show)

putInstruction :: Instruction -> Put
putInstruction :: Instruction -> Put
putInstruction = \case
    Instruction
AALoad -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aaLoad
    Instruction
AAStore -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aaStore
    Instruction
AConstNull -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aConstNull
    ALoad Word8
n -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aLoad Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
n
    Instruction
ALoad0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aLoad0
    Instruction
ALoad1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aLoad1
    Instruction
ALoad2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aLoad2
    Instruction
ALoad3 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aLoad3
    (ANewArray ConstantPoolIndex
index) -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aNewArray Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    Instruction
AReturn -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aReturn
    Instruction
ArrayLength -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_arrayLength
    AStore Word8
n -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aStore Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
n
    Instruction
AStore0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aStore0
    Instruction
AStore1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aStore1
    Instruction
AStore2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aStore2
    Instruction
AStore3 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aStore3
    Instruction
AThrow -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_aThrow
    Instruction
BALoad -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_baLoad
    Instruction
BAStore -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_baStore
    (BIPush Word8
i) -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_biPush Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
i
    Instruction
CALoad -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_caLoad
    Instruction
CAStore -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_caStore
    (CheckCast ConstantPoolIndex
index) -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_checkCast Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    Instruction
D2F -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_d2f
    Instruction
D2I -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_d2i
    Instruction
D2L -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_d2l
    Instruction
DAdd -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dAdd
    Instruction
DALoad -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_daLoad
    Instruction
DAStore -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_daStore
    Instruction
DCmpG -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dCmpG
    Instruction
DCmpL -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dCmpL
    Instruction
DConst0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dConst0
    Instruction
DConst1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dConst1
    Instruction
DDiv -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dDiv
    Instruction
DLoad -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dLoad
    Instruction
DLoad0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dLoad0
    Instruction
DLoad1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dLoad1
    Instruction
DLoad2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dLoad2
    Instruction
DLoad3 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dLoad3
    Instruction
DMul -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dMul
    Instruction
DNeg -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dNeg
    Instruction
DRem -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dRem
    Instruction
DReturn -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dReturn
    Instruction
DStore -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dStore
    Instruction
DStore0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dStore0
    Instruction
DStore1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dStore1
    Instruction
DStore2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dStore2
    Instruction
DStore3 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dStore3
    Instruction
DSub -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dSub
    Instruction
Dup -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dup
    Instruction
DupX1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dupX1
    Instruction
DupX2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dupX2
    Instruction
Dup2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dup2
    Instruction
Dup2X1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dup2X1
    Instruction
Dup2X2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_dup2X2
    Instruction
F2D -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_f2d
    Instruction
F2I -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_f2i
    Instruction
F2L -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_f2l
    Instruction
FAdd -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fAdd
    Instruction
FALoad -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_faLoad
    Instruction
FAStore -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_faStore
    Instruction
FCmpG -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fCmpG
    Instruction
FCmpL -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fCmpL
    Instruction
FConst0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fConst0
    Instruction
FConst1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fConst1
    Instruction
FConst2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fConst2
    Instruction
FDiv -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fDiv
    Instruction
FLoad -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fLoad
    Instruction
FLoad0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fLoad0
    Instruction
FLoad1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fLoad1
    Instruction
FLoad2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fLoad2
    Instruction
FLoad3 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fLoad3
    Instruction
FMul -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fMul
    Instruction
FNeg -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fNeg
    Instruction
FRem -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fRem
    Instruction
FReturn -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fReturn
    Instruction
FStore -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fStore
    Instruction
FStore0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fStore0
    Instruction
FStore1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fStore1
    Instruction
FStore2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fStore2
    Instruction
FStore3 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fStore3
    Instruction
FSub -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_fSub
    GetField ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_getField Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    GetStatic ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_getStatic Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    Goto ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_goto Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    GotoW Word32
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_gotoW Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word32 -> Put
putWord32be Word32
offset
    Instruction
I2B -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_i2b
    Instruction
I2C -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_i2c
    Instruction
I2D -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_i2d
    Instruction
I2F -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_i2f
    Instruction
I2L -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_i2l
    Instruction
I2S -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_i2s
    Instruction
IAdd -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iAdd
    Instruction
IALoad -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iALoad
    Instruction
IAStore -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iAStore
    Instruction
IAnd -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iAnd
    Instruction
IConstM1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iConstM1
    Instruction
IConst0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iConst0
    Instruction
IConst1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iConst1
    Instruction
IConst2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iConst2
    Instruction
IConst3 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iConst3
    Instruction
IConst4 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iConst4
    Instruction
IConst5 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iConst5
    Instruction
IDiv -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iDiv
    IfAcmpEq ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifAcmpeq Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfAcmpNe ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifAcmpne Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfIcmpEq ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifIcmpeq Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfIcmpNe ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifIcmpne Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfIcmpLt ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifIcmplt Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfIcmpGe ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifIcmpge Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfIcmpGt ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifIcmpgt Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfIcmpLe ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifIcmple Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfEq ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifEq Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfNe ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifNe Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfLt ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifLt Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfGe ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifGe Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfGt ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifGt Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfLe ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifLe Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfNonNull ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifNonNull Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IfNull ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ifNull Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    IInc Word8
index Word8
increment -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iInc Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
index Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
increment
    ILoad Word8
n -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iLoad Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
n
    Instruction
ILoad0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iLoad0
    Instruction
ILoad1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iLoad1
    Instruction
ILoad2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iLoad2
    Instruction
ILoad3 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iLoad3
    Instruction
IMul -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iMul
    Instruction
INeg -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iNeg
    Instanceof ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_instanceOf Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    InvokeDynamic ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_invokeDynamic Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
0 Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
0
    InvokeInterface ConstantPoolIndex
index Word8
count -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_invokeInterface Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
count Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
0
    InvokeSpecial ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_invokeSpecial Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    InvokeStatic ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_invokeStatic Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    InvokeVirtual ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_invokeVirtual Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    Instruction
IOr -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iOr
    Instruction
IRem -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iRem
    Instruction
IReturn -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iReturn
    Instruction
IShl -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iShl
    Instruction
IShr -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iShr
    IStore Word8
n -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iStore Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
n
    Instruction
IStore0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iStore0
    Instruction
IStore1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iStore1
    Instruction
IStore2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iStore2
    Instruction
IStore3 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iStore3
    Instruction
ISub -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iSub
    Instruction
IUShr -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iUShr
    Instruction
IXor -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iXor
    JSR ConstantPoolIndex
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_jsr Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
offset
    JSR_W Word32
offset -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_jsrW Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word32 -> Put
putWord32be Word32
offset
    Instruction
L2D -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_l2d
    Instruction
L2F -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_l2f
    Instruction
L2I -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_l2i
    Instruction
LAdd -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lAdd
    Instruction
LALoad -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lALoad
    Instruction
LAnd -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lAnd
    Instruction
LCmp -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lCmp
    Instruction
LConst0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lConst0
    Instruction
LConst1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lConst1
    LDC Word8
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ldc Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
index
    LDC_W ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ldcW Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    LDC2_W ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ldc2W Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    Instruction
LDiv -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lDiv
    Instruction
LLoad -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lLoad
    Instruction
LLoad0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lLoad0
    Instruction
LLoad1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lLoad1
    Instruction
LLoad2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lLoad2
    Instruction
LLoad3 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lLoad3
    Instruction
LMul -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lMul
    Instruction
LNeg -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lNeg
    LookupSwitch{} -> Put
forall a. HasCallStack => a
undefined -- TODO: figure this out
    Instruction
LOr -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lOr
    Instruction
LRem -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lRem
    Instruction
LReturn -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lReturn
    Instruction
LShl -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lShl
    Instruction
LShr -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lShr
    Instruction
LSub -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lSub
    Instruction
LStore -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lStore
    Instruction
LStore0 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lStore0
    Instruction
LStore1 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lStore1
    Instruction
LStore2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lStore2
    Instruction
LStore3 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lStore3
    Instruction
LUShr -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lUShr
    Instruction
LXor -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_lXor
    Instruction
MonitorEnter -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_monitorEnter
    Instruction
MonitorExit -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_monitorExit
    MultiANewArray ConstantPoolIndex
index Word8
dimensions -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_multiANewArray Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
dimensions
    New ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_new Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    NewArray Word8
atype -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_newArray Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
atype
    Instruction
NOP -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_nop
    Instruction
Pop -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_pop
    Instruction
Pop2 -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_pop2
    PutField ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_putField Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    PutStatic ConstantPoolIndex
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_putStatic Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    Ret Word8
index -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_ret Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
index
    Instruction
Return -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_return
    Instruction
SALoad -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_sALoad
    Instruction
SAStore -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_sAStore
    SIPush ConstantPoolIndex
value -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_sIPush Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
value
    Instruction
Swap -> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_swap
    TableSwitch{} -> Put
forall a. HasCallStack => a
undefined -- TODO: figure this out
    Wide1 Word8
opcode ConstantPoolIndex
index ->
        Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_wide
            Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
opcode
            Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
    WideIInc ConstantPoolIndex
index ConstantPoolIndex
increment ->
        Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_wide
            Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Word8 -> Put
putWord8 Word8
MagicNumbers.instruction_iInc
            Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
index
            Put -> Put -> Put
forall a b. PutM a -> PutM b -> PutM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ConstantPoolIndex -> Put
putWord16be ConstantPoolIndex
increment

instance WriteBinary Instruction where
    writeBinary :: Instruction -> Put
writeBinary = Instruction -> Put
putInstruction