Add some documentation.
[hs-java.git] / JVM / Assembler.hs
1 {-# LANGUAGE TypeFamilies, StandaloneDeriving, FlexibleInstances,
2    FlexibleContexts, UndecidableInstances, RecordWildCards, OverloadedStrings,
3    TypeSynonymInstances, MultiParamTypeClasses #-}
4 -- | This module declares data type for JVM instructions, and BinaryState
5 -- instances to read/write them.
6 module JVM.Assembler 
7   (Instruction (..),
8    ArrayType (..),
9    Code (..),
10    IMM (..),
11    CMP (..)
12   )
13   where
14
15 import Control.Monad
16 import Control.Applicative
17 import Data.Ix (inRange)
18 import Data.List (intercalate)
19 import Data.Word
20 import Data.Bits
21 import qualified Data.Binary as Binary
22 import qualified Data.Binary.Get as Get
23 import Data.Char
24 import qualified Data.ByteString.Lazy as B
25 import Data.Array
26 import qualified Data.Set as S
27 import qualified Data.Map as M
28
29 import Data.BinaryState
30 import JVM.ClassFile
31 import JVM.Types
32
33 -- | Immediate constant. Corresponding value will be added to base opcode.
34 data IMM =
35     I0     -- ^ 0
36   | I1     -- ^ 1
37   | I2     -- ^ 2
38   | I3     -- ^ 3
39   deriving (Eq, Ord, Enum, Show)
40
41 -- | Comparation operation type. Not all CMP instructions support all operations.
42 data CMP =
43     C_EQ
44   | C_NE
45   | C_LT
46   | C_GE
47   | C_GT
48   | C_LE
49   deriving (Eq, Ord, Enum, Show)
50
51 -- | Format of Code method attribute.
52 data Code = Code {
53     codeStackSize :: Word16,
54     codeMaxLocals :: Word16,
55     codeLength :: Word32,
56     codeInstructions :: [Instruction],
57     codeExceptionsN :: Word16,
58     codeExceptions :: [CodeException],
59     codeAttrsN :: Word16,
60     codeAttributes :: [AttributeInfo] }
61   deriving (Eq, Show)
62
63 -- | Exception descriptor
64 data CodeException = CodeException {
65     eStartPC :: Word16,
66     eEndPC :: Word16,
67     eHandlerPC :: Word16,
68     eCatchType :: Word16 }
69   deriving (Eq, Show)
70
71 instance BinaryState Integer CodeException where
72   put (CodeException {..}) = do
73     put eStartPC
74     put eEndPC
75     put eHandlerPC
76     put eCatchType
77
78   get = CodeException <$> get <*> get <*> get <*> get
79
80 instance BinaryState Integer AttributeInfo where
81   put a = do
82     let sz = 6 + attributeLength a      -- full size of AttributeInfo structure
83     liftOffset (fromIntegral sz) Binary.put a
84
85   get = getZ
86
87 instance BinaryState Integer Code where
88   put (Code {..}) = do
89     put codeStackSize
90     put codeMaxLocals
91     put codeLength
92     forM_ codeInstructions put
93     put codeExceptionsN
94     forM_ codeExceptions put
95     put codeAttrsN
96     forM_ codeAttributes put
97
98   get = do
99     stackSz <- get
100     locals <- get
101     len <- get
102     bytes <- replicateM (fromIntegral len) get
103     let bytecode = B.pack bytes
104         code = decodeWith readInstructions 0 bytecode
105     excn <- get
106     excs <- replicateM (fromIntegral excn) get
107     nAttrs <- get
108     attrs <- replicateM (fromIntegral nAttrs) get
109     return $ Code stackSz locals len code excn excs nAttrs attrs
110
111 -- | Read sequence of instructions (to end of stream)
112 readInstructions :: GetState Integer [Instruction]
113 readInstructions = do
114    end <- isEmpty
115    if end
116      then return []
117      else do
118           x <- get
119           next <- readInstructions
120           return (x: next)
121
122 -- | JVM instruction set
123 data Instruction =
124     NOP            -- ^ 0
125   | ACONST_NULL    -- ^ 1
126   | ICONST_M1      -- ^ 2
127   | ICONST_0       -- ^ 3
128   | ICONST_1       -- ^ 4
129   | ICONST_2       -- ^ 5
130   | ICONST_3       -- ^ 6
131   | ICONST_4       -- ^ 7
132   | ICONST_5       -- ^ 8
133   | LCONST_0       -- ^ 9
134   | LCONST_1       -- ^ 10
135   | FCONST_0       -- ^ 11
136   | FCONST_1       -- ^ 12
137   | FCONST_2       -- ^ 13
138   | DCONST_0       -- ^ 14
139   | DCONST_1       -- ^ 15
140   | BIPUSH Word8   -- ^ 16
141   | SIPUSH Word16  -- ^ 17
142   | LDC1 Word8     -- ^ 18
143   | LDC2 Word16    -- ^ 19
144   | LDC2W Word16   -- ^ 20
145   | ILOAD Word8    -- ^ 21
146   | LLOAD Word8    -- ^ 22
147   | FLOAD Word8    -- ^ 23
148   | DLOAD Word8    -- ^ 24
149   | ALOAD Word8    -- ^ 25
150   | ILOAD_ IMM     -- ^ 26, 27, 28, 29
151   | LLOAD_ IMM     -- ^ 30, 31, 32, 33
152   | FLOAD_ IMM     -- ^ 34, 35, 36, 37
153   | DLOAD_ IMM     -- ^ 38, 39, 40, 41
154   | ALOAD_ IMM     -- ^ 42, 43, 44, 45
155   | IALOAD         -- ^ 46
156   | LALOAD         -- ^ 47
157   | FALOAD         -- ^ 48
158   | DALOAD         -- ^ 49
159   | AALOAD         -- ^ 50
160   | BALOAD         -- ^ 51
161   | CALOAD         -- ^ 52
162   | SALOAD         -- ^ 53
163   | ISTORE Word8   -- ^ 54
164   | LSTORE Word8   -- ^ 55
165   | FSTORE Word8   -- ^ 56
166   | DSTORE Word8   -- ^ 57
167   | ASTORE Word8   -- ^ 58
168   | ISTORE_ IMM    -- ^ 59, 60, 61, 62
169   | LSTORE_ IMM    -- ^ 63, 64, 65, 66
170   | FSTORE_ IMM    -- ^ 67, 68, 69, 70
171   | DSTORE_ IMM    -- ^ 71, 72, 73, 74
172   | ASTORE_ IMM    -- ^ 75, 76, 77, 78
173   | IASTORE        -- ^ 79
174   | LASTORE        -- ^ 80
175   | FASTORE        -- ^ 81
176   | DASTORE        -- ^ 82
177   | AASTORE        -- ^ 83
178   | BASTORE        -- ^ 84
179   | CASTORE        -- ^ 85
180   | SASTORE        -- ^ 86
181   | POP            -- ^ 87
182   | POP2           -- ^ 88
183   | DUP            -- ^ 89
184   | DUP_X1         -- ^ 90
185   | DUP_X2         -- ^ 91
186   | DUP2           -- ^ 92
187   | DUP2_X1        -- ^ 93 
188   | DUP2_X2        -- ^ 94
189   | SWAP           -- ^ 95
190   | IADD           -- ^ 96
191   | LADD           -- ^ 97
192   | FADD           -- ^ 98
193   | DADD           -- ^ 99
194   | ISUB           -- ^ 100
195   | LSUB           -- ^ 101
196   | FSUB           -- ^ 102
197   | DSUB           -- ^ 103
198   | IMUL           -- ^ 104
199   | LMUL           -- ^ 105
200   | FMUL           -- ^ 106
201   | DMUL           -- ^ 107
202   | IDIV           -- ^ 108
203   | LDIV           -- ^ 109
204   | FDIV           -- ^ 110
205   | DDIV           -- ^ 111
206   | IREM           -- ^ 112
207   | LREM           -- ^ 113
208   | FREM           -- ^ 114
209   | DREM           -- ^ 115
210   | INEG           -- ^ 116
211   | LNEG           -- ^ 117
212   | FNEG           -- ^ 118
213   | DNEG           -- ^ 119
214   | ISHL           -- ^ 120
215   | LSHL           -- ^ 121
216   | ISHR           -- ^ 122
217   | LSHR           -- ^ 123
218   | IUSHR          -- ^ 124
219   | LUSHR          -- ^ 125
220   | IAND           -- ^ 126
221   | LAND           -- ^ 127
222   | IOR            -- ^ 128
223   | LOR            -- ^ 129
224   | IXOR           -- ^ 130
225   | LXOR           -- ^ 131
226   | IINC Word8 Word8       -- ^ 132
227   | I2L                    -- ^ 133
228   | I2F                    -- ^ 134
229   | I2D                    -- ^ 135
230   | L2I                    -- ^ 136
231   | L2F                    -- ^ 137
232   | L2D                    -- ^ 138
233   | F2I                    -- ^ 139
234   | F2L                    -- ^ 140
235   | F2D                    -- ^ 141
236   | D2I                    -- ^ 142
237   | D2L                    -- ^ 143
238   | D2F                    -- ^ 144
239   | I2B                    -- ^ 145
240   | I2C                    -- ^ 146
241   | I2S                    -- ^ 147
242   | LCMP                   -- ^ 148
243   | FCMP CMP               -- ^ 149, 150
244   | DCMP CMP               -- ^ 151, 152
245   | IF CMP                 -- ^ 153, 154, 155, 156, 157, 158
246   | IF_ICMP CMP Word16     -- ^ 159, 160, 161, 162, 163, 164
247   | IF_ACMP CMP Word16     -- ^ 165, 166
248   | GOTO                   -- ^ 167
249   | JSR Word16             -- ^ 168
250   | RET                    -- ^ 169
251   | TABLESWITCH Word32 Word32 Word32 [Word32]     -- ^ 170
252   | LOOKUPSWITCH Word32 Word32 [(Word32, Word32)] -- ^ 171
253   | IRETURN                -- ^ 172
254   | LRETURN                -- ^ 173
255   | FRETURN                -- ^ 174
256   | DRETURN                -- ^ 175
257   | RETURN                 -- ^ 177
258   | GETSTATIC Word16       -- ^ 178
259   | PUTSTATIC Word16       -- ^ 179
260   | GETFIELD Word16        -- ^ 180
261   | PUTFIELD Word16        -- ^ 181
262   | INVOKEVIRTUAL Word16   -- ^ 182
263   | INVOKESPECIAL Word16   -- ^ 183
264   | INVOKESTATIC Word16    -- ^ 184
265   | INVOKEINTERFACE Word16 Word8 -- ^ 185
266   | NEW Word16             -- ^ 187
267   | NEWARRAY Word8         -- ^ 188, see @ArrayType@
268   | ANEWARRAY Word16       -- ^ 189
269   | ARRAYLENGTH            -- ^ 190
270   | ATHROW                 -- ^ 191
271   | CHECKCAST Word16       -- ^ 192
272   | INSTANCEOF Word16      -- ^ 193
273   | MONITORENTER           -- ^ 194
274   | MONITOREXIT            -- ^ 195
275   | WIDE Word8 Instruction -- ^ 196
276   | MULTINANEWARRAY Word16 Word8 -- ^ 197
277   | IFNULL Word16          -- ^ 198
278   | IFNONNULL Word16       -- ^ 199
279   | GOTO_W Word32          -- ^ 200
280   | JSR_W Word32           -- ^ 201
281   deriving (Eq, Show)
282
283 -- ^ JVM array type (primitive types)
284 data ArrayType =
285     T_BOOLEAN  -- ^ 4
286   | T_CHAR     -- ^ 5
287   | T_FLOAT    -- ^ 6
288   | T_DOUBLE   -- ^ 7
289   | T_BYTE     -- ^ 8
290   | T_SHORT    -- ^ 9
291   | T_INT      -- ^ 10
292   | T_LONG     -- ^ 11
293   deriving (Eq, Show, Enum)
294
295 -- ^ Parse opcode with immediate constant
296 imm :: Word8                   -- ^ Base opcode
297     -> (IMM -> Instruction)    -- ^ Instruction constructor
298     -> Word8                   -- ^ Opcode to parse
299     -> GetState s Instruction
300 imm base constr x = return $ constr $ toEnum $ fromIntegral (x-base)
301
302 -- ^ Put opcode with immediate constant
303 putImm :: Word8                -- ^ Base opcode
304        -> IMM                  -- ^ Constant to add to opcode
305        -> PutState Integer ()
306 putImm base i = putByte $ base + (fromIntegral $ fromEnum i)
307
308 atype2byte :: ArrayType -> Word8
309 atype2byte T_BOOLEAN  = 4
310 atype2byte T_CHAR     = 5
311 atype2byte T_FLOAT    = 6
312 atype2byte T_DOUBLE   = 7
313 atype2byte T_BYTE     = 8
314 atype2byte T_SHORT    = 9
315 atype2byte T_INT      = 10
316 atype2byte T_LONG     = 11
317
318 byte2atype :: Word8 -> GetState s ArrayType
319 byte2atype 4  = return T_BOOLEAN
320 byte2atype 5  = return T_CHAR
321 byte2atype 6  = return T_FLOAT
322 byte2atype 7  = return T_DOUBLE
323 byte2atype 8  = return T_BYTE
324 byte2atype 9  = return T_SHORT
325 byte2atype 10 = return T_INT
326 byte2atype 11 = return T_LONG
327 byte2atype x  = fail $ "Unknown array type byte: " ++ show x
328
329 instance BinaryState Integer ArrayType where
330   get = do
331     x <- getByte
332     byte2atype x
333
334   put t = putByte (atype2byte t)
335
336 -- ^ Put opcode with one argument
337 put1 :: (BinaryState Integer a)
338       => Word8                  -- ^ Opcode
339       -> a                      -- ^ First argument
340       -> PutState Integer ()
341 put1 code x = do
342   putByte code
343   put x
344
345 put2 :: (BinaryState Integer a, BinaryState Integer b)
346      => Word8                   -- ^ Opcode
347      -> a                       -- ^ First argument
348      -> b                       -- ^ Second argument
349      -> PutState Integer ()
350 put2 code x y = do
351   putByte code
352   put x
353   put y
354
355 instance BinaryState Integer Instruction where
356   put  NOP         = putByte 0
357   put  ACONST_NULL = putByte 1
358   put  ICONST_M1   = putByte 2
359   put  ICONST_0    = putByte 3
360   put  ICONST_1    = putByte 4
361   put  ICONST_2    = putByte 5
362   put  ICONST_3    = putByte 6
363   put  ICONST_4    = putByte 7
364   put  ICONST_5    = putByte 8
365   put  LCONST_0    = putByte 9
366   put  LCONST_1    = putByte 10
367   put  FCONST_0    = putByte 11
368   put  FCONST_1    = putByte 12
369   put  FCONST_2    = putByte 13
370   put  DCONST_0    = putByte 14
371   put  DCONST_1    = putByte 15
372   put (BIPUSH x)   = put1 16 x
373   put (SIPUSH x)   = put1 17 x
374   put (LDC1 x)     = put1 18 x
375   put (LDC2 x)     = put1 19 x
376   put (LDC2W x)    = put1 20 x
377   put (ILOAD x)    = put1 21 x
378   put (LLOAD x)    = put1 22 x
379   put (FLOAD x)    = put1 23 x
380   put (DLOAD x)    = put1 24 x
381   put (ALOAD x)    = put1 25 x
382   put (ILOAD_ i)   = putImm 26 i
383   put (LLOAD_ i)   = putImm 30 i
384   put (FLOAD_ i)   = putImm 34 i
385   put (DLOAD_ i)   = putImm 38 i
386   put (ALOAD_ i)   = putImm 42 i
387   put  IALOAD      = putByte 46
388   put  LALOAD      = putByte 47
389   put  FALOAD      = putByte 48
390   put  DALOAD      = putByte 49
391   put  AALOAD      = putByte 50
392   put  BALOAD      = putByte 51
393   put  CALOAD      = putByte 52
394   put  SALOAD      = putByte 53
395   put (ISTORE x)   = put1  54 x
396   put (LSTORE x)   = put1  55 x
397   put (FSTORE x)   = put1  56 x
398   put (DSTORE x)   = put1  57 x
399   put (ASTORE x)   = put1  58 x
400   put (ISTORE_ i)  = putImm 59 i
401   put (LSTORE_ i)  = putImm 63 i
402   put (FSTORE_ i)  = putImm 67 i
403   put (DSTORE_ i)  = putImm 71 i
404   put (ASTORE_ i)  = putImm 75 i
405   put  IASTORE     = putByte 79
406   put  LASTORE     = putByte 80
407   put  FASTORE     = putByte 81
408   put  DASTORE     = putByte 82
409   put  AASTORE     = putByte 83
410   put  BASTORE     = putByte 84
411   put  CASTORE     = putByte 85
412   put  SASTORE     = putByte 86
413   put  POP         = putByte 87
414   put  POP2        = putByte 88
415   put  DUP         = putByte 89
416   put  DUP_X1      = putByte 90
417   put  DUP_X2      = putByte 91
418   put  DUP2        = putByte 92
419   put  DUP2_X1     = putByte 93 
420   put  DUP2_X2     = putByte 94
421   put  SWAP        = putByte 95
422   put  IADD        = putByte 96
423   put  LADD        = putByte 97
424   put  FADD        = putByte 98
425   put  DADD        = putByte 99
426   put  ISUB        = putByte 100
427   put  LSUB        = putByte 101
428   put  FSUB        = putByte 102
429   put  DSUB        = putByte 103
430   put  IMUL        = putByte 104
431   put  LMUL        = putByte 105
432   put  FMUL        = putByte 106
433   put  DMUL        = putByte 107
434   put  IDIV        = putByte 108
435   put  LDIV        = putByte 109
436   put  FDIV        = putByte 110
437   put  DDIV        = putByte 111
438   put  IREM        = putByte 112
439   put  LREM        = putByte 113
440   put  FREM        = putByte 114
441   put  DREM        = putByte 115
442   put  INEG        = putByte 116
443   put  LNEG        = putByte 117
444   put  FNEG        = putByte 118
445   put  DNEG        = putByte 119
446   put  ISHL        = putByte 120
447   put  LSHL        = putByte 121
448   put  ISHR        = putByte 122
449   put  LSHR        = putByte 123
450   put  IUSHR       = putByte 124
451   put  LUSHR       = putByte 125
452   put  IAND        = putByte 126
453   put  LAND        = putByte 127
454   put  IOR         = putByte 128
455   put  LOR         = putByte 129
456   put  IXOR        = putByte 130
457   put  LXOR        = putByte 131
458   put (IINC x y)      = put2 132 x y
459   put  I2L            = putByte 133
460   put  I2F            = putByte 134
461   put  I2D            = putByte 135
462   put  L2I            = putByte 136
463   put  L2F            = putByte 137
464   put  L2D            = putByte 138
465   put  F2I            = putByte 139
466   put  F2L            = putByte 140
467   put  F2D            = putByte 141
468   put  D2I            = putByte 142
469   put  D2L            = putByte 143
470   put  D2F            = putByte 144
471   put  I2B            = putByte 145
472   put  I2C            = putByte 146
473   put  I2S            = putByte 147
474   put  LCMP           = putByte 148
475   put (FCMP C_LT)     = putByte 149
476   put (FCMP C_GT)     = putByte 150
477   put (FCMP c)        = fail $ "No such instruction: FCMP " ++ show c
478   put (DCMP C_LT)     = putByte 151
479   put (DCMP C_GT)     = putByte 152
480   put (DCMP c)        = fail $ "No such instruction: DCMP " ++ show c
481   put (IF c)          = putByte (fromIntegral $ 153 + fromEnum c)
482   put (IF_ACMP C_EQ x) = put1 165 x
483   put (IF_ACMP C_NE x) = put1 166 x
484   put (IF_ACMP c _)   = fail $ "No such instruction: IF_ACMP " ++ show c
485   put (IF_ICMP c x)   = putByte (fromIntegral $ 159 + fromEnum c) >> put x
486   put  GOTO           = putByte 167
487   put (JSR x)         = put1 168 x
488   put  RET            = putByte 169
489   put (TABLESWITCH def low high offs) = do
490                                    putByte 170
491                                    offset <- getOffset
492                                    let pads = 4 - (offset `mod` 4)
493                                    replicateM (fromIntegral pads) (putByte 0)
494                                    put low
495                                    put high
496                                    forM_ offs put
497   put (LOOKUPSWITCH def n pairs) = do
498                                    putByte 171
499                                    offset <- getOffset
500                                    let pads = 4 - (offset `mod` 4)
501                                    replicateM (fromIntegral pads) (putByte 0)
502                                    put def
503                                    put n
504                                    forM_ pairs put
505   put  IRETURN        = putByte 172
506   put  LRETURN        = putByte 173
507   put  FRETURN        = putByte 174
508   put  DRETURN        = putByte 175
509   put  RETURN         = putByte 177
510   put (GETSTATIC x)   = put1 178 x
511   put (PUTSTATIC x)   = put1 179 x
512   put (GETFIELD x)    = put1 180 x
513   put (PUTFIELD x)    = put1 181 x
514   put (INVOKEVIRTUAL x)     = put1 182 x
515   put (INVOKESPECIAL x)     = put1 183 x
516   put (INVOKESTATIC x)      = put1 184 x
517   put (INVOKEINTERFACE x c) = put2 185 x c >> putByte 0
518   put (NEW x)         = put1 187 x
519   put (NEWARRAY x)    = put1 188 x
520   put (ANEWARRAY x)   = put1 189 x
521   put  ARRAYLENGTH    = putByte 190
522   put  ATHROW         = putByte 191
523   put (CHECKCAST x)   = put1 192 x
524   put (INSTANCEOF x)  = put1 193 x
525   put  MONITORENTER   = putByte 194
526   put  MONITOREXIT    = putByte 195
527   put (WIDE x inst)   = put2 196 x inst
528   put (MULTINANEWARRAY x y) = put2 197 x y
529   put (IFNULL x)      = put1 198 x
530   put (IFNONNULL x)   = put1 199 x
531   put (GOTO_W x)      = put1 200 x
532   put (JSR_W x)       = put1 201 x
533
534   get = do
535     c <- getByte
536     case c of
537       0 -> return NOP
538       1 -> return ACONST_NULL
539       2 -> return ICONST_M1
540       3 -> return ICONST_0
541       4 -> return ICONST_1
542       5 -> return ICONST_2
543       6 -> return ICONST_3
544       7 -> return ICONST_4
545       8 -> return ICONST_5
546       9 -> return LCONST_0
547       10 -> return LCONST_1
548       11 -> return FCONST_0
549       12 -> return FCONST_1
550       13 -> return FCONST_2
551       14 -> return DCONST_0
552       15 -> return DCONST_1
553       16 -> BIPUSH <$> get
554       17 -> SIPUSH <$> get
555       18 -> LDC1 <$> get
556       19 -> LDC2 <$> get
557       20 -> LDC2W <$> get
558       21 -> ILOAD <$> get
559       22 -> LLOAD <$> get
560       23 -> FLOAD <$> get
561       24 -> DLOAD <$> get
562       25 -> ALOAD <$> get
563       46 -> return IALOAD
564       47 -> return LALOAD
565       48 -> return FALOAD
566       49 -> return DALOAD
567       50 -> return AALOAD
568       51 -> return BALOAD
569       52 -> return CALOAD
570       53 -> return SALOAD
571       54 -> ISTORE <$> get
572       55 -> LSTORE <$> get
573       56 -> FSTORE <$> get
574       57 -> DSTORE <$> get
575       58 -> ASTORE <$> get
576       79 -> return IASTORE
577       80 -> return LASTORE
578       81 -> return FASTORE
579       82 -> return DASTORE
580       83 -> return AASTORE
581       84 -> return BASTORE
582       85 -> return CASTORE
583       86 -> return SASTORE
584       87 -> return POP
585       88 -> return POP2
586       89 -> return DUP
587       90 -> return DUP_X1
588       91 -> return DUP_X2
589       92 -> return DUP2
590       93 -> return DUP2_X1 
591       94 -> return DUP2_X2
592       95 -> return SWAP
593       96 -> return IADD
594       97 -> return LADD
595       98 -> return FADD
596       99 -> return DADD
597       100 -> return ISUB
598       101 -> return LSUB
599       102 -> return FSUB
600       103 -> return DSUB
601       104 -> return IMUL
602       105 -> return LMUL
603       106 -> return FMUL
604       107 -> return DMUL
605       108 -> return IDIV
606       109 -> return LDIV
607       110 -> return FDIV
608       111 -> return DDIV
609       112 -> return IREM
610       113 -> return LREM
611       114 -> return FREM
612       115 -> return DREM
613       116 -> return INEG
614       117 -> return LNEG
615       118 -> return FNEG
616       119 -> return DNEG
617       120 -> return ISHL
618       121 -> return LSHL
619       122 -> return ISHR
620       123 -> return LSHR
621       124 -> return IUSHR
622       125 -> return LUSHR
623       126 -> return IAND
624       127 -> return LAND
625       128 -> return IOR
626       129 -> return LOR
627       130 -> return IXOR
628       131 -> return LXOR
629       132 -> IINC <$> get <*> get
630       133 -> return I2L
631       134 -> return I2F
632       135 -> return I2D
633       136 -> return L2I
634       137 -> return L2F
635       138 -> return L2D
636       139 -> return F2I
637       140 -> return F2L
638       141 -> return F2D
639       142 -> return D2I
640       143 -> return D2L
641       144 -> return D2F
642       145 -> return I2B
643       146 -> return I2C
644       147 -> return I2S
645       148 -> return LCMP
646       149 -> return $ FCMP C_LT
647       150 -> return $ FCMP C_GT
648       151 -> return $ DCMP C_LT
649       152 -> return $ DCMP C_GT
650       165 -> IF_ACMP C_EQ <$> get
651       166 -> IF_ACMP C_NE <$> get
652       167 -> return GOTO
653       168 -> JSR <$> get
654       169 -> return RET
655       170 -> do
656              offset <- bytesRead
657              let pads = 4 - (offset `mod` 4)
658              skip (fromIntegral pads)
659              def <- get
660              low <- get
661              high <- get
662              offs <- replicateM (fromIntegral $ high - low + 1) get
663              return $ TABLESWITCH def low high offs
664       171 -> do
665              offset <- bytesRead
666              let pads = 4 - (offset `mod` 4)
667              skip (fromIntegral pads)
668              def <- get
669              n <- get
670              pairs <- replicateM (fromIntegral n) get
671              return $ LOOKUPSWITCH def n pairs
672       172 -> return IRETURN
673       173 -> return LRETURN
674       174 -> return FRETURN
675       175 -> return DRETURN
676       177 -> return RETURN
677       178 -> GETSTATIC <$> get
678       179 -> PUTSTATIC <$> get
679       180 -> GETFIELD <$> get
680       181 -> PUTFIELD <$> get
681       182 -> INVOKEVIRTUAL <$> get
682       183 -> INVOKESPECIAL <$> get
683       184 -> INVOKESTATIC <$> get
684       185 -> (INVOKEINTERFACE <$> get <*> get) <* skip 1
685       187 -> NEW <$> get
686       188 -> NEWARRAY <$> get
687       189 -> ANEWARRAY <$> get
688       190 -> return ARRAYLENGTH
689       191 -> return ATHROW
690       192 -> CHECKCAST <$> get
691       193 -> INSTANCEOF <$> get
692       194 -> return MONITORENTER
693       195 -> return MONITOREXIT
694       196 -> WIDE <$> get <*> get
695       197 -> MULTINANEWARRAY <$> get <*> get
696       198 -> IFNULL <$> get
697       199 -> IFNONNULL <$> get
698       200 -> GOTO_W <$> get
699       201 -> JSR_W <$> get
700       _ | inRange (59, 62) c -> imm 59 ISTORE_ c
701         | inRange (63, 66) c -> imm 63 LSTORE_ c
702         | inRange (67, 70) c -> imm 67 FSTORE_ c
703         | inRange (71, 74) c -> imm 71 DSTORE_ c
704         | inRange (75, 78) c -> imm 75 ASTORE_ c
705         | inRange (26, 29) c -> imm 26 ILOAD_ c
706         | inRange (30, 33) c -> imm 30 LLOAD_ c
707         | inRange (34, 37) c -> imm 34 FLOAD_ c
708         | inRange (38, 41) c -> imm 38 DLOAD_ c
709         | inRange (42, 45) c -> imm 42 ALOAD_ c
710         | inRange (153, 158) c -> return $ IF (toEnum $ fromIntegral $ c-153)
711         | inRange (159, 164) c -> IF_ICMP (toEnum $ fromIntegral $ c-159) <$> get
712         | otherwise -> fail $ "Unknown instruction byte code: " ++ show c
713