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