1 /*
2  * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 package org.graalvm.compiler.bytecode;
26 
27 import static org.graalvm.compiler.bytecode.Bytecodes.Flags.ASSOCIATIVE;
28 import static org.graalvm.compiler.bytecode.Bytecodes.Flags.BRANCH;
29 import static org.graalvm.compiler.bytecode.Bytecodes.Flags.COMMUTATIVE;
30 import static org.graalvm.compiler.bytecode.Bytecodes.Flags.FALL_THROUGH;
31 import static org.graalvm.compiler.bytecode.Bytecodes.Flags.FIELD_READ;
32 import static org.graalvm.compiler.bytecode.Bytecodes.Flags.FIELD_WRITE;
33 import static org.graalvm.compiler.bytecode.Bytecodes.Flags.INVOKE;
34 import static org.graalvm.compiler.bytecode.Bytecodes.Flags.LOAD;
35 import static org.graalvm.compiler.bytecode.Bytecodes.Flags.STOP;
36 import static org.graalvm.compiler.bytecode.Bytecodes.Flags.STORE;
37 import static org.graalvm.compiler.bytecode.Bytecodes.Flags.TRAP;
38 
39 import java.lang.reflect.Field;
40 import java.lang.reflect.Modifier;
41 
42 /**
43  * Definitions of the standard Java bytecodes defined by
44  * <a href= "http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html"> Java
45  * Virtual Machine Specification</a>.
46  */
47 public class Bytecodes {
48 
49     // @formatter:off
50     public static final int NOP                  =   0; // 0x00
51     public static final int ACONST_NULL          =   1; // 0x01
52     public static final int ICONST_M1            =   2; // 0x02
53     public static final int ICONST_0             =   3; // 0x03
54     public static final int ICONST_1             =   4; // 0x04
55     public static final int ICONST_2             =   5; // 0x05
56     public static final int ICONST_3             =   6; // 0x06
57     public static final int ICONST_4             =   7; // 0x07
58     public static final int ICONST_5             =   8; // 0x08
59     public static final int LCONST_0             =   9; // 0x09
60     public static final int LCONST_1             =  10; // 0x0A
61     public static final int FCONST_0             =  11; // 0x0B
62     public static final int FCONST_1             =  12; // 0x0C
63     public static final int FCONST_2             =  13; // 0x0D
64     public static final int DCONST_0             =  14; // 0x0E
65     public static final int DCONST_1             =  15; // 0x0F
66     public static final int BIPUSH               =  16; // 0x10
67     public static final int SIPUSH               =  17; // 0x11
68     public static final int LDC                  =  18; // 0x12
69     public static final int LDC_W                =  19; // 0x13
70     public static final int LDC2_W               =  20; // 0x14
71     public static final int ILOAD                =  21; // 0x15
72     public static final int LLOAD                =  22; // 0x16
73     public static final int FLOAD                =  23; // 0x17
74     public static final int DLOAD                =  24; // 0x18
75     public static final int ALOAD                =  25; // 0x19
76     public static final int ILOAD_0              =  26; // 0x1A
77     public static final int ILOAD_1              =  27; // 0x1B
78     public static final int ILOAD_2              =  28; // 0x1C
79     public static final int ILOAD_3              =  29; // 0x1D
80     public static final int LLOAD_0              =  30; // 0x1E
81     public static final int LLOAD_1              =  31; // 0x1F
82     public static final int LLOAD_2              =  32; // 0x20
83     public static final int LLOAD_3              =  33; // 0x21
84     public static final int FLOAD_0              =  34; // 0x22
85     public static final int FLOAD_1              =  35; // 0x23
86     public static final int FLOAD_2              =  36; // 0x24
87     public static final int FLOAD_3              =  37; // 0x25
88     public static final int DLOAD_0              =  38; // 0x26
89     public static final int DLOAD_1              =  39; // 0x27
90     public static final int DLOAD_2              =  40; // 0x28
91     public static final int DLOAD_3              =  41; // 0x29
92     public static final int ALOAD_0              =  42; // 0x2A
93     public static final int ALOAD_1              =  43; // 0x2B
94     public static final int ALOAD_2              =  44; // 0x2C
95     public static final int ALOAD_3              =  45; // 0x2D
96     public static final int IALOAD               =  46; // 0x2E
97     public static final int LALOAD               =  47; // 0x2F
98     public static final int FALOAD               =  48; // 0x30
99     public static final int DALOAD               =  49; // 0x31
100     public static final int AALOAD               =  50; // 0x32
101     public static final int BALOAD               =  51; // 0x33
102     public static final int CALOAD               =  52; // 0x34
103     public static final int SALOAD               =  53; // 0x35
104     public static final int ISTORE               =  54; // 0x36
105     public static final int LSTORE               =  55; // 0x37
106     public static final int FSTORE               =  56; // 0x38
107     public static final int DSTORE               =  57; // 0x39
108     public static final int ASTORE               =  58; // 0x3A
109     public static final int ISTORE_0             =  59; // 0x3B
110     public static final int ISTORE_1             =  60; // 0x3C
111     public static final int ISTORE_2             =  61; // 0x3D
112     public static final int ISTORE_3             =  62; // 0x3E
113     public static final int LSTORE_0             =  63; // 0x3F
114     public static final int LSTORE_1             =  64; // 0x40
115     public static final int LSTORE_2             =  65; // 0x41
116     public static final int LSTORE_3             =  66; // 0x42
117     public static final int FSTORE_0             =  67; // 0x43
118     public static final int FSTORE_1             =  68; // 0x44
119     public static final int FSTORE_2             =  69; // 0x45
120     public static final int FSTORE_3             =  70; // 0x46
121     public static final int DSTORE_0             =  71; // 0x47
122     public static final int DSTORE_1             =  72; // 0x48
123     public static final int DSTORE_2             =  73; // 0x49
124     public static final int DSTORE_3             =  74; // 0x4A
125     public static final int ASTORE_0             =  75; // 0x4B
126     public static final int ASTORE_1             =  76; // 0x4C
127     public static final int ASTORE_2             =  77; // 0x4D
128     public static final int ASTORE_3             =  78; // 0x4E
129     public static final int IASTORE              =  79; // 0x4F
130     public static final int LASTORE              =  80; // 0x50
131     public static final int FASTORE              =  81; // 0x51
132     public static final int DASTORE              =  82; // 0x52
133     public static final int AASTORE              =  83; // 0x53
134     public static final int BASTORE              =  84; // 0x54
135     public static final int CASTORE              =  85; // 0x55
136     public static final int SASTORE              =  86; // 0x56
137     public static final int POP                  =  87; // 0x57
138     public static final int POP2                 =  88; // 0x58
139     public static final int DUP                  =  89; // 0x59
140     public static final int DUP_X1               =  90; // 0x5A
141     public static final int DUP_X2               =  91; // 0x5B
142     public static final int DUP2                 =  92; // 0x5C
143     public static final int DUP2_X1              =  93; // 0x5D
144     public static final int DUP2_X2              =  94; // 0x5E
145     public static final int SWAP                 =  95; // 0x5F
146     public static final int IADD                 =  96; // 0x60
147     public static final int LADD                 =  97; // 0x61
148     public static final int FADD                 =  98; // 0x62
149     public static final int DADD                 =  99; // 0x63
150     public static final int ISUB                 = 100; // 0x64
151     public static final int LSUB                 = 101; // 0x65
152     public static final int FSUB                 = 102; // 0x66
153     public static final int DSUB                 = 103; // 0x67
154     public static final int IMUL                 = 104; // 0x68
155     public static final int LMUL                 = 105; // 0x69
156     public static final int FMUL                 = 106; // 0x6A
157     public static final int DMUL                 = 107; // 0x6B
158     public static final int IDIV                 = 108; // 0x6C
159     public static final int LDIV                 = 109; // 0x6D
160     public static final int FDIV                 = 110; // 0x6E
161     public static final int DDIV                 = 111; // 0x6F
162     public static final int IREM                 = 112; // 0x70
163     public static final int LREM                 = 113; // 0x71
164     public static final int FREM                 = 114; // 0x72
165     public static final int DREM                 = 115; // 0x73
166     public static final int INEG                 = 116; // 0x74
167     public static final int LNEG                 = 117; // 0x75
168     public static final int FNEG                 = 118; // 0x76
169     public static final int DNEG                 = 119; // 0x77
170     public static final int ISHL                 = 120; // 0x78
171     public static final int LSHL                 = 121; // 0x79
172     public static final int ISHR                 = 122; // 0x7A
173     public static final int LSHR                 = 123; // 0x7B
174     public static final int IUSHR                = 124; // 0x7C
175     public static final int LUSHR                = 125; // 0x7D
176     public static final int IAND                 = 126; // 0x7E
177     public static final int LAND                 = 127; // 0x7F
178     public static final int IOR                  = 128; // 0x80
179     public static final int LOR                  = 129; // 0x81
180     public static final int IXOR                 = 130; // 0x82
181     public static final int LXOR                 = 131; // 0x83
182     public static final int IINC                 = 132; // 0x84
183     public static final int I2L                  = 133; // 0x85
184     public static final int I2F                  = 134; // 0x86
185     public static final int I2D                  = 135; // 0x87
186     public static final int L2I                  = 136; // 0x88
187     public static final int L2F                  = 137; // 0x89
188     public static final int L2D                  = 138; // 0x8A
189     public static final int F2I                  = 139; // 0x8B
190     public static final int F2L                  = 140; // 0x8C
191     public static final int F2D                  = 141; // 0x8D
192     public static final int D2I                  = 142; // 0x8E
193     public static final int D2L                  = 143; // 0x8F
194     public static final int D2F                  = 144; // 0x90
195     public static final int I2B                  = 145; // 0x91
196     public static final int I2C                  = 146; // 0x92
197     public static final int I2S                  = 147; // 0x93
198     public static final int LCMP                 = 148; // 0x94
199     public static final int FCMPL                = 149; // 0x95
200     public static final int FCMPG                = 150; // 0x96
201     public static final int DCMPL                = 151; // 0x97
202     public static final int DCMPG                = 152; // 0x98
203     public static final int IFEQ                 = 153; // 0x99
204     public static final int IFNE                 = 154; // 0x9A
205     public static final int IFLT                 = 155; // 0x9B
206     public static final int IFGE                 = 156; // 0x9C
207     public static final int IFGT                 = 157; // 0x9D
208     public static final int IFLE                 = 158; // 0x9E
209     public static final int IF_ICMPEQ            = 159; // 0x9F
210     public static final int IF_ICMPNE            = 160; // 0xA0
211     public static final int IF_ICMPLT            = 161; // 0xA1
212     public static final int IF_ICMPGE            = 162; // 0xA2
213     public static final int IF_ICMPGT            = 163; // 0xA3
214     public static final int IF_ICMPLE            = 164; // 0xA4
215     public static final int IF_ACMPEQ            = 165; // 0xA5
216     public static final int IF_ACMPNE            = 166; // 0xA6
217     public static final int GOTO                 = 167; // 0xA7
218     public static final int JSR                  = 168; // 0xA8
219     public static final int RET                  = 169; // 0xA9
220     public static final int TABLESWITCH          = 170; // 0xAA
221     public static final int LOOKUPSWITCH         = 171; // 0xAB
222     public static final int IRETURN              = 172; // 0xAC
223     public static final int LRETURN              = 173; // 0xAD
224     public static final int FRETURN              = 174; // 0xAE
225     public static final int DRETURN              = 175; // 0xAF
226     public static final int ARETURN              = 176; // 0xB0
227     public static final int RETURN               = 177; // 0xB1
228     public static final int GETSTATIC            = 178; // 0xB2
229     public static final int PUTSTATIC            = 179; // 0xB3
230     public static final int GETFIELD             = 180; // 0xB4
231     public static final int PUTFIELD             = 181; // 0xB5
232     public static final int INVOKEVIRTUAL        = 182; // 0xB6
233     public static final int INVOKESPECIAL        = 183; // 0xB7
234     public static final int INVOKESTATIC         = 184; // 0xB8
235     public static final int INVOKEINTERFACE      = 185; // 0xB9
236     public static final int INVOKEDYNAMIC        = 186; // 0xBA
237     public static final int NEW                  = 187; // 0xBB
238     public static final int NEWARRAY             = 188; // 0xBC
239     public static final int ANEWARRAY            = 189; // 0xBD
240     public static final int ARRAYLENGTH          = 190; // 0xBE
241     public static final int ATHROW               = 191; // 0xBF
242     public static final int CHECKCAST            = 192; // 0xC0
243     public static final int INSTANCEOF           = 193; // 0xC1
244     public static final int MONITORENTER         = 194; // 0xC2
245     public static final int MONITOREXIT          = 195; // 0xC3
246     public static final int WIDE                 = 196; // 0xC4
247     public static final int MULTIANEWARRAY       = 197; // 0xC5
248     public static final int IFNULL               = 198; // 0xC6
249     public static final int IFNONNULL            = 199; // 0xC7
250     public static final int GOTO_W               = 200; // 0xC8
251     public static final int JSR_W                = 201; // 0xC9
252     public static final int BREAKPOINT           = 202; // 0xCA
253 
254     public static final int ILLEGAL = 255;
255     public static final int END = 256;
256     // @formatter:on
257 
258     /**
259      * The last opcode defined by the JVM specification. To iterate over all JVM bytecodes:
260      *
261      * <pre>
262      * for (int opcode = 0; opcode &lt;= Bytecodes.LAST_JVM_OPCODE; ++opcode) {
263      *     //
264      * }
265      * </pre>
266      */
267     public static final int LAST_JVM_OPCODE = JSR_W;
268 
269     /**
270      * A collection of flags describing various bytecode attributes.
271      */
272     static class Flags {
273 
274         /**
275          * Denotes an instruction that ends a basic block and does not let control flow fall through
276          * to its lexical successor.
277          */
278         static final int STOP = 0x00000001;
279 
280         /**
281          * Denotes an instruction that ends a basic block and may let control flow fall through to
282          * its lexical successor. In practice this means it is a conditional branch.
283          */
284         static final int FALL_THROUGH = 0x00000002;
285 
286         /**
287          * Denotes an instruction that has a 2 or 4 byte operand that is an offset to another
288          * instruction in the same method. This does not include the {@link Bytecodes#TABLESWITCH}
289          * or {@link Bytecodes#LOOKUPSWITCH} instructions.
290          */
291         static final int BRANCH = 0x00000004;
292 
293         /**
294          * Denotes an instruction that reads the value of a static or instance field.
295          */
296         static final int FIELD_READ = 0x00000008;
297 
298         /**
299          * Denotes an instruction that writes the value of a static or instance field.
300          */
301         static final int FIELD_WRITE = 0x00000010;
302 
303         /**
304          * Denotes an instruction that can cause a trap.
305          */
306         static final int TRAP = 0x00000080;
307         /**
308          * Denotes an instruction that is commutative.
309          */
310         static final int COMMUTATIVE = 0x00000100;
311         /**
312          * Denotes an instruction that is associative.
313          */
314         static final int ASSOCIATIVE = 0x00000200;
315         /**
316          * Denotes an instruction that loads an operand.
317          */
318         static final int LOAD = 0x00000400;
319         /**
320          * Denotes an instruction that stores an operand.
321          */
322         static final int STORE = 0x00000800;
323         /**
324          * Denotes the 4 INVOKE* instructions.
325          */
326         static final int INVOKE = 0x00001000;
327     }
328 
329     // Performs a sanity check that none of the flags overlap.
330     static {
331         int allFlags = 0;
332         try {
333             for (Field field : Flags.class.getDeclaredFields()) {
334                 int flagsFilter = Modifier.FINAL | Modifier.STATIC;
335                 if ((field.getModifiers() & flagsFilter) == flagsFilter && !field.isSynthetic()) {
336                     assert field.getType() == int.class : "Field is not int : " + field;
337                     final int flag = field.getInt(null);
338                     assert flag != 0;
field.getName()339                     assert (flag & allFlags) == 0 : field.getName() + " has a value conflicting with another flag";
340                     allFlags |= flag;
341                 }
342             }
343         } catch (Exception e) {
344             throw new InternalError(e.toString());
345         }
346     }
347 
348     /**
349      * An array that maps from a bytecode value to a {@link String} for the corresponding
350      * instruction mnemonic.
351      */
352     private static final String[] nameArray = new String[256];
353 
354     /**
355      * An array that maps from a bytecode value to the set of {@link Flags} for the corresponding
356      * instruction.
357      */
358     private static final int[] flagsArray = new int[256];
359 
360     /**
361      * An array that maps from a bytecode value to the length in bytes for the corresponding
362      * instruction.
363      */
364     private static final int[] lengthArray = new int[256];
365 
366     /**
367      * An array that maps from a bytecode value to the number of slots pushed on the stack by the
368      * corresponding instruction.
369      */
370     private static final int[] stackEffectArray = new int[256];
371 
372     // Checkstyle: stop
373     // @formatter:off
374     static {
def(NOP , R , R , 0)375         def(NOP                 , "nop"             , "b"    ,  0);
def(ACONST_NULL , R , R , 1)376         def(ACONST_NULL         , "aconst_null"     , "b"    ,  1);
def(ICONST_M1 , R , R , 1)377         def(ICONST_M1           , "iconst_m1"       , "b"    ,  1);
def(ICONST_0 , R , R , 1)378         def(ICONST_0            , "iconst_0"        , "b"    ,  1);
def(ICONST_1 , R , R , 1)379         def(ICONST_1            , "iconst_1"        , "b"    ,  1);
def(ICONST_2 , R , R , 1)380         def(ICONST_2            , "iconst_2"        , "b"    ,  1);
def(ICONST_3 , R , R , 1)381         def(ICONST_3            , "iconst_3"        , "b"    ,  1);
def(ICONST_4 , R , R , 1)382         def(ICONST_4            , "iconst_4"        , "b"    ,  1);
def(ICONST_5 , R , R , 1)383         def(ICONST_5            , "iconst_5"        , "b"    ,  1);
def(LCONST_0 , R , R , 2)384         def(LCONST_0            , "lconst_0"        , "b"    ,  2);
def(LCONST_1 , R , R , 2)385         def(LCONST_1            , "lconst_1"        , "b"    ,  2);
def(FCONST_0 , R , R , 1)386         def(FCONST_0            , "fconst_0"        , "b"    ,  1);
def(FCONST_1 , R , R , 1)387         def(FCONST_1            , "fconst_1"        , "b"    ,  1);
def(FCONST_2 , R , R , 1)388         def(FCONST_2            , "fconst_2"        , "b"    ,  1);
def(DCONST_0 , R , R , 2)389         def(DCONST_0            , "dconst_0"        , "b"    ,  2);
def(DCONST_1 , R , R , 2)390         def(DCONST_1            , "dconst_1"        , "b"    ,  2);
def(BIPUSH , R , R , 1)391         def(BIPUSH              , "bipush"          , "bc"   ,  1);
def(SIPUSH , R , R , 1)392         def(SIPUSH              , "sipush"          , "bcc"  ,  1);
def(LDC , R , R , 1, TRAP)393         def(LDC                 , "ldc"             , "bi"   ,  1, TRAP);
def(LDC_W , R , R , 1, TRAP)394         def(LDC_W               , "ldc_w"           , "bii"  ,  1, TRAP);
def(LDC2_W , R , R , 2, TRAP)395         def(LDC2_W              , "ldc2_w"          , "bii"  ,  2, TRAP);
def(ILOAD , R , R , 1, LOAD)396         def(ILOAD               , "iload"           , "bi"   ,  1, LOAD);
def(LLOAD , R , R , 2, LOAD)397         def(LLOAD               , "lload"           , "bi"   ,  2, LOAD);
def(FLOAD , R , R , 1, LOAD)398         def(FLOAD               , "fload"           , "bi"   ,  1, LOAD);
def(DLOAD , R , R , 2, LOAD)399         def(DLOAD               , "dload"           , "bi"   ,  2, LOAD);
def(ALOAD , R , R , 1, LOAD)400         def(ALOAD               , "aload"           , "bi"   ,  1, LOAD);
def(ILOAD_0 , R , R , 1, LOAD)401         def(ILOAD_0             , "iload_0"         , "b"    ,  1, LOAD);
def(ILOAD_1 , R , R , 1, LOAD)402         def(ILOAD_1             , "iload_1"         , "b"    ,  1, LOAD);
def(ILOAD_2 , R , R , 1, LOAD)403         def(ILOAD_2             , "iload_2"         , "b"    ,  1, LOAD);
def(ILOAD_3 , R , R , 1, LOAD)404         def(ILOAD_3             , "iload_3"         , "b"    ,  1, LOAD);
def(LLOAD_0 , R , R , 2, LOAD)405         def(LLOAD_0             , "lload_0"         , "b"    ,  2, LOAD);
def(LLOAD_1 , R , R , 2, LOAD)406         def(LLOAD_1             , "lload_1"         , "b"    ,  2, LOAD);
def(LLOAD_2 , R , R , 2, LOAD)407         def(LLOAD_2             , "lload_2"         , "b"    ,  2, LOAD);
def(LLOAD_3 , R , R , 2, LOAD)408         def(LLOAD_3             , "lload_3"         , "b"    ,  2, LOAD);
def(FLOAD_0 , R , R , 1, LOAD)409         def(FLOAD_0             , "fload_0"         , "b"    ,  1, LOAD);
def(FLOAD_1 , R , R , 1, LOAD)410         def(FLOAD_1             , "fload_1"         , "b"    ,  1, LOAD);
def(FLOAD_2 , R , R , 1, LOAD)411         def(FLOAD_2             , "fload_2"         , "b"    ,  1, LOAD);
def(FLOAD_3 , R , R , 1, LOAD)412         def(FLOAD_3             , "fload_3"         , "b"    ,  1, LOAD);
def(DLOAD_0 , R , R , 2, LOAD)413         def(DLOAD_0             , "dload_0"         , "b"    ,  2, LOAD);
def(DLOAD_1 , R , R , 2, LOAD)414         def(DLOAD_1             , "dload_1"         , "b"    ,  2, LOAD);
def(DLOAD_2 , R , R , 2, LOAD)415         def(DLOAD_2             , "dload_2"         , "b"    ,  2, LOAD);
def(DLOAD_3 , R , R , 2, LOAD)416         def(DLOAD_3             , "dload_3"         , "b"    ,  2, LOAD);
def(ALOAD_0 , R , R , 1, LOAD)417         def(ALOAD_0             , "aload_0"         , "b"    ,  1, LOAD);
def(ALOAD_1 , R , R , 1, LOAD)418         def(ALOAD_1             , "aload_1"         , "b"    ,  1, LOAD);
def(ALOAD_2 , R , R , 1, LOAD)419         def(ALOAD_2             , "aload_2"         , "b"    ,  1, LOAD);
def(ALOAD_3 , R , R , 1, LOAD)420         def(ALOAD_3             , "aload_3"         , "b"    ,  1, LOAD);
def(IALOAD , R , R , -1, TRAP)421         def(IALOAD              , "iaload"          , "b"    , -1, TRAP);
def(LALOAD , R , R , 0, TRAP)422         def(LALOAD              , "laload"          , "b"    ,  0, TRAP);
def(FALOAD , R , R , -1, TRAP)423         def(FALOAD              , "faload"          , "b"    , -1, TRAP);
def(DALOAD , R , R , 0, TRAP)424         def(DALOAD              , "daload"          , "b"    ,  0, TRAP);
def(AALOAD , R , R , -1, TRAP)425         def(AALOAD              , "aaload"          , "b"    , -1, TRAP);
def(BALOAD , R , R , -1, TRAP)426         def(BALOAD              , "baload"          , "b"    , -1, TRAP);
def(CALOAD , R , R , -1, TRAP)427         def(CALOAD              , "caload"          , "b"    , -1, TRAP);
def(SALOAD , R , R , -1, TRAP)428         def(SALOAD              , "saload"          , "b"    , -1, TRAP);
def(ISTORE , R , R , -1, STORE)429         def(ISTORE              , "istore"          , "bi"   , -1, STORE);
def(LSTORE , R , R , -2, STORE)430         def(LSTORE              , "lstore"          , "bi"   , -2, STORE);
def(FSTORE , R , R , -1, STORE)431         def(FSTORE              , "fstore"          , "bi"   , -1, STORE);
def(DSTORE , R , R , -2, STORE)432         def(DSTORE              , "dstore"          , "bi"   , -2, STORE);
def(ASTORE , R , R , -1, STORE)433         def(ASTORE              , "astore"          , "bi"   , -1, STORE);
def(ISTORE_0 , R , R , -1, STORE)434         def(ISTORE_0            , "istore_0"        , "b"    , -1, STORE);
def(ISTORE_1 , R , R , -1, STORE)435         def(ISTORE_1            , "istore_1"        , "b"    , -1, STORE);
def(ISTORE_2 , R , R , -1, STORE)436         def(ISTORE_2            , "istore_2"        , "b"    , -1, STORE);
def(ISTORE_3 , R , R , -1, STORE)437         def(ISTORE_3            , "istore_3"        , "b"    , -1, STORE);
def(LSTORE_0 , R , R , -2, STORE)438         def(LSTORE_0            , "lstore_0"        , "b"    , -2, STORE);
def(LSTORE_1 , R , R , -2, STORE)439         def(LSTORE_1            , "lstore_1"        , "b"    , -2, STORE);
def(LSTORE_2 , R , R , -2, STORE)440         def(LSTORE_2            , "lstore_2"        , "b"    , -2, STORE);
def(LSTORE_3 , R , R , -2, STORE)441         def(LSTORE_3            , "lstore_3"        , "b"    , -2, STORE);
def(FSTORE_0 , R , R , -1, STORE)442         def(FSTORE_0            , "fstore_0"        , "b"    , -1, STORE);
def(FSTORE_1 , R , R , -1, STORE)443         def(FSTORE_1            , "fstore_1"        , "b"    , -1, STORE);
def(FSTORE_2 , R , R , -1, STORE)444         def(FSTORE_2            , "fstore_2"        , "b"    , -1, STORE);
def(FSTORE_3 , R , R , -1, STORE)445         def(FSTORE_3            , "fstore_3"        , "b"    , -1, STORE);
def(DSTORE_0 , R , R , -2, STORE)446         def(DSTORE_0            , "dstore_0"        , "b"    , -2, STORE);
def(DSTORE_1 , R , R , -2, STORE)447         def(DSTORE_1            , "dstore_1"        , "b"    , -2, STORE);
def(DSTORE_2 , R , R , -2, STORE)448         def(DSTORE_2            , "dstore_2"        , "b"    , -2, STORE);
def(DSTORE_3 , R , R , -2, STORE)449         def(DSTORE_3            , "dstore_3"        , "b"    , -2, STORE);
def(ASTORE_0 , R , R , -1, STORE)450         def(ASTORE_0            , "astore_0"        , "b"    , -1, STORE);
def(ASTORE_1 , R , R , -1, STORE)451         def(ASTORE_1            , "astore_1"        , "b"    , -1, STORE);
def(ASTORE_2 , R , R , -1, STORE)452         def(ASTORE_2            , "astore_2"        , "b"    , -1, STORE);
def(ASTORE_3 , R , R , -1, STORE)453         def(ASTORE_3            , "astore_3"        , "b"    , -1, STORE);
def(IASTORE , R , R , -3, TRAP)454         def(IASTORE             , "iastore"         , "b"    , -3, TRAP);
def(LASTORE , R , R , -4, TRAP)455         def(LASTORE             , "lastore"         , "b"    , -4, TRAP);
def(FASTORE , R , R , -3, TRAP)456         def(FASTORE             , "fastore"         , "b"    , -3, TRAP);
def(DASTORE , R , R , -4, TRAP)457         def(DASTORE             , "dastore"         , "b"    , -4, TRAP);
def(AASTORE , R , R , -3, TRAP)458         def(AASTORE             , "aastore"         , "b"    , -3, TRAP);
def(BASTORE , R , R , -3, TRAP)459         def(BASTORE             , "bastore"         , "b"    , -3, TRAP);
def(CASTORE , R , R , -3, TRAP)460         def(CASTORE             , "castore"         , "b"    , -3, TRAP);
def(SASTORE , R , R , -3, TRAP)461         def(SASTORE             , "sastore"         , "b"    , -3, TRAP);
def(POP , R , R , -1)462         def(POP                 , "pop"             , "b"    , -1);
def(POP2 , R , R , -2)463         def(POP2                , "pop2"            , "b"    , -2);
def(DUP , R , R , 1)464         def(DUP                 , "dup"             , "b"    ,  1);
def(DUP_X1 , R , R , 1)465         def(DUP_X1              , "dup_x1"          , "b"    ,  1);
def(DUP_X2 , R , R , 1)466         def(DUP_X2              , "dup_x2"          , "b"    ,  1);
def(DUP2 , R , R , 2)467         def(DUP2                , "dup2"            , "b"    ,  2);
def(DUP2_X1 , R , R , 2)468         def(DUP2_X1             , "dup2_x1"         , "b"    ,  2);
def(DUP2_X2 , R , R , 2)469         def(DUP2_X2             , "dup2_x2"         , "b"    ,  2);
def(SWAP , R , R , 0)470         def(SWAP                , "swap"            , "b"    ,  0);
def(IADD , R , R , -1, COMMUTATIVE | ASSOCIATIVE)471         def(IADD                , "iadd"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
def(LADD , R , R , -2, COMMUTATIVE | ASSOCIATIVE)472         def(LADD                , "ladd"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
def(FADD , R , R , -1, COMMUTATIVE | ASSOCIATIVE)473         def(FADD                , "fadd"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
def(DADD , R , R , -2, COMMUTATIVE | ASSOCIATIVE)474         def(DADD                , "dadd"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
def(ISUB , R , R , -1)475         def(ISUB                , "isub"            , "b"    , -1);
def(LSUB , R , R , -2)476         def(LSUB                , "lsub"            , "b"    , -2);
def(FSUB , R , R , -1)477         def(FSUB                , "fsub"            , "b"    , -1);
def(DSUB , R , R , -2)478         def(DSUB                , "dsub"            , "b"    , -2);
def(IMUL , R , R , -1, COMMUTATIVE | ASSOCIATIVE)479         def(IMUL                , "imul"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
def(LMUL , R , R , -2, COMMUTATIVE | ASSOCIATIVE)480         def(LMUL                , "lmul"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
def(FMUL , R , R , -1, COMMUTATIVE | ASSOCIATIVE)481         def(FMUL                , "fmul"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
def(DMUL , R , R , -2, COMMUTATIVE | ASSOCIATIVE)482         def(DMUL                , "dmul"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
def(IDIV , R , R , -1, TRAP)483         def(IDIV                , "idiv"            , "b"    , -1, TRAP);
def(LDIV , R , R , -2, TRAP)484         def(LDIV                , "ldiv"            , "b"    , -2, TRAP);
def(FDIV , R , R , -1)485         def(FDIV                , "fdiv"            , "b"    , -1);
def(DDIV , R , R , -2)486         def(DDIV                , "ddiv"            , "b"    , -2);
def(IREM , R , R , -1, TRAP)487         def(IREM                , "irem"            , "b"    , -1, TRAP);
def(LREM , R , R , -2, TRAP)488         def(LREM                , "lrem"            , "b"    , -2, TRAP);
def(FREM , R , R , -1)489         def(FREM                , "frem"            , "b"    , -1);
def(DREM , R , R , -2)490         def(DREM                , "drem"            , "b"    , -2);
def(INEG , R , R , 0)491         def(INEG                , "ineg"            , "b"    ,  0);
def(LNEG , R , R , 0)492         def(LNEG                , "lneg"            , "b"    ,  0);
def(FNEG , R , R , 0)493         def(FNEG                , "fneg"            , "b"    ,  0);
def(DNEG , R , R , 0)494         def(DNEG                , "dneg"            , "b"    ,  0);
def(ISHL , R , R , -1)495         def(ISHL                , "ishl"            , "b"    , -1);
def(LSHL , R , R , -1)496         def(LSHL                , "lshl"            , "b"    , -1);
def(ISHR , R , R , -1)497         def(ISHR                , "ishr"            , "b"    , -1);
def(LSHR , R , R , -1)498         def(LSHR                , "lshr"            , "b"    , -1);
def(IUSHR , R , R , -1)499         def(IUSHR               , "iushr"           , "b"    , -1);
def(LUSHR , R , R , -1)500         def(LUSHR               , "lushr"           , "b"    , -1);
def(IAND , R , R , -1, COMMUTATIVE | ASSOCIATIVE)501         def(IAND                , "iand"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
def(LAND , R , R , -2, COMMUTATIVE | ASSOCIATIVE)502         def(LAND                , "land"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
def(IOR , R , R , -1, COMMUTATIVE | ASSOCIATIVE)503         def(IOR                 , "ior"             , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
def(LOR , R , R , -2, COMMUTATIVE | ASSOCIATIVE)504         def(LOR                 , "lor"             , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
def(IXOR , R , R , -1, COMMUTATIVE | ASSOCIATIVE)505         def(IXOR                , "ixor"            , "b"    , -1, COMMUTATIVE | ASSOCIATIVE);
def(LXOR , R , R , -2, COMMUTATIVE | ASSOCIATIVE)506         def(LXOR                , "lxor"            , "b"    , -2, COMMUTATIVE | ASSOCIATIVE);
def(IINC , R , R , 0, LOAD | STORE)507         def(IINC                , "iinc"            , "bic"  ,  0, LOAD | STORE);
def(I2L , R , R , 1)508         def(I2L                 , "i2l"             , "b"    ,  1);
def(I2F , R , R , 0)509         def(I2F                 , "i2f"             , "b"    ,  0);
def(I2D , R , R , 1)510         def(I2D                 , "i2d"             , "b"    ,  1);
def(L2I , R , R , -1)511         def(L2I                 , "l2i"             , "b"    , -1);
def(L2F , R , R , -1)512         def(L2F                 , "l2f"             , "b"    , -1);
def(L2D , R , R , 0)513         def(L2D                 , "l2d"             , "b"    ,  0);
def(F2I , R , R , 0)514         def(F2I                 , "f2i"             , "b"    ,  0);
def(F2L , R , R , 1)515         def(F2L                 , "f2l"             , "b"    ,  1);
def(F2D , R , R , 1)516         def(F2D                 , "f2d"             , "b"    ,  1);
def(D2I , R , R , -1)517         def(D2I                 , "d2i"             , "b"    , -1);
def(D2L , R , R , 0)518         def(D2L                 , "d2l"             , "b"    ,  0);
def(D2F , R , R , -1)519         def(D2F                 , "d2f"             , "b"    , -1);
def(I2B , R , R , 0)520         def(I2B                 , "i2b"             , "b"    ,  0);
def(I2C , R , R , 0)521         def(I2C                 , "i2c"             , "b"    ,  0);
def(I2S , R , R , 0)522         def(I2S                 , "i2s"             , "b"    ,  0);
def(LCMP , R , R , -3)523         def(LCMP                , "lcmp"            , "b"    , -3);
def(FCMPL , R , R , -1)524         def(FCMPL               , "fcmpl"           , "b"    , -1);
def(FCMPG , R , R , -1)525         def(FCMPG               , "fcmpg"           , "b"    , -1);
def(DCMPL , R , R , -3)526         def(DCMPL               , "dcmpl"           , "b"    , -3);
def(DCMPG , R , R , -3)527         def(DCMPG               , "dcmpg"           , "b"    , -3);
def(IFEQ , R , R , -1, FALL_THROUGH | BRANCH)528         def(IFEQ                , "ifeq"            , "boo"  , -1, FALL_THROUGH | BRANCH);
def(IFNE , R , R , -1, FALL_THROUGH | BRANCH)529         def(IFNE                , "ifne"            , "boo"  , -1, FALL_THROUGH | BRANCH);
def(IFLT , R , R , -1, FALL_THROUGH | BRANCH)530         def(IFLT                , "iflt"            , "boo"  , -1, FALL_THROUGH | BRANCH);
def(IFGE , R , R , -1, FALL_THROUGH | BRANCH)531         def(IFGE                , "ifge"            , "boo"  , -1, FALL_THROUGH | BRANCH);
def(IFGT , R , R , -1, FALL_THROUGH | BRANCH)532         def(IFGT                , "ifgt"            , "boo"  , -1, FALL_THROUGH | BRANCH);
def(IFLE , R , R , -1, FALL_THROUGH | BRANCH)533         def(IFLE                , "ifle"            , "boo"  , -1, FALL_THROUGH | BRANCH);
def(IF_ICMPEQ , R , R , -2, COMMUTATIVE | FALL_THROUGH | BRANCH)534         def(IF_ICMPEQ           , "if_icmpeq"       , "boo"  , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
def(IF_ICMPNE , R , R , -2, COMMUTATIVE | FALL_THROUGH | BRANCH)535         def(IF_ICMPNE           , "if_icmpne"       , "boo"  , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
def(IF_ICMPLT , R , R , -2, FALL_THROUGH | BRANCH)536         def(IF_ICMPLT           , "if_icmplt"       , "boo"  , -2, FALL_THROUGH | BRANCH);
def(IF_ICMPGE , R , R , -2, FALL_THROUGH | BRANCH)537         def(IF_ICMPGE           , "if_icmpge"       , "boo"  , -2, FALL_THROUGH | BRANCH);
def(IF_ICMPGT , R , R , -2, FALL_THROUGH | BRANCH)538         def(IF_ICMPGT           , "if_icmpgt"       , "boo"  , -2, FALL_THROUGH | BRANCH);
def(IF_ICMPLE , R , R , -2, FALL_THROUGH | BRANCH)539         def(IF_ICMPLE           , "if_icmple"       , "boo"  , -2, FALL_THROUGH | BRANCH);
def(IF_ACMPEQ , R , R , -2, COMMUTATIVE | FALL_THROUGH | BRANCH)540         def(IF_ACMPEQ           , "if_acmpeq"       , "boo"  , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
def(IF_ACMPNE , R , R , -2, COMMUTATIVE | FALL_THROUGH | BRANCH)541         def(IF_ACMPNE           , "if_acmpne"       , "boo"  , -2, COMMUTATIVE | FALL_THROUGH | BRANCH);
def(GOTO , R , R , 0, STOP | BRANCH)542         def(GOTO                , "goto"            , "boo"  ,  0, STOP | BRANCH);
def(JSR , R , R , 0, STOP | BRANCH)543         def(JSR                 , "jsr"             , "boo"  ,  0, STOP | BRANCH);
def(RET , R , R , 0, STOP)544         def(RET                 , "ret"             , "bi"   ,  0, STOP);
def(TABLESWITCH , R , R , -1, STOP)545         def(TABLESWITCH         , "tableswitch"     , ""     , -1, STOP);
def(LOOKUPSWITCH , R , R , -1, STOP)546         def(LOOKUPSWITCH        , "lookupswitch"    , ""     , -1, STOP);
def(IRETURN , R , R , -1, TRAP | STOP)547         def(IRETURN             , "ireturn"         , "b"    , -1, TRAP | STOP);
def(LRETURN , R , R , -2, TRAP | STOP)548         def(LRETURN             , "lreturn"         , "b"    , -2, TRAP | STOP);
def(FRETURN , R , R , -1, TRAP | STOP)549         def(FRETURN             , "freturn"         , "b"    , -1, TRAP | STOP);
def(DRETURN , R , R , -2, TRAP | STOP)550         def(DRETURN             , "dreturn"         , "b"    , -2, TRAP | STOP);
def(ARETURN , R , R , -1, TRAP | STOP)551         def(ARETURN             , "areturn"         , "b"    , -1, TRAP | STOP);
def(RETURN , R , R , 0, TRAP | STOP)552         def(RETURN              , "return"          , "b"    ,  0, TRAP | STOP);
def(GETSTATIC , R , R , 1, TRAP | FIELD_READ)553         def(GETSTATIC           , "getstatic"       , "bjj"  ,  1, TRAP | FIELD_READ);
def(PUTSTATIC , R , R , -1, TRAP | FIELD_WRITE)554         def(PUTSTATIC           , "putstatic"       , "bjj"  , -1, TRAP | FIELD_WRITE);
def(GETFIELD , R , R , 0, TRAP | FIELD_READ)555         def(GETFIELD            , "getfield"        , "bjj"  ,  0, TRAP | FIELD_READ);
def(PUTFIELD , R , R , -2, TRAP | FIELD_WRITE)556         def(PUTFIELD            , "putfield"        , "bjj"  , -2, TRAP | FIELD_WRITE);
def(INVOKEVIRTUAL , R , R , -1, TRAP | INVOKE)557         def(INVOKEVIRTUAL       , "invokevirtual"   , "bjj"  , -1, TRAP | INVOKE);
def(INVOKESPECIAL , R , R , -1, TRAP | INVOKE)558         def(INVOKESPECIAL       , "invokespecial"   , "bjj"  , -1, TRAP | INVOKE);
def(INVOKESTATIC , R , R , 0, TRAP | INVOKE)559         def(INVOKESTATIC        , "invokestatic"    , "bjj"  ,  0, TRAP | INVOKE);
def(INVOKEINTERFACE , R , R, -1, TRAP | INVOKE)560         def(INVOKEINTERFACE     , "invokeinterface" , "bjja_", -1, TRAP | INVOKE);
def(INVOKEDYNAMIC , R , R, 0, TRAP | INVOKE)561         def(INVOKEDYNAMIC       , "invokedynamic"   , "bjjjj",  0, TRAP | INVOKE);
def(NEW , R , R , 1, TRAP)562         def(NEW                 , "new"             , "bii"  ,  1, TRAP);
def(NEWARRAY , R , R , 0, TRAP)563         def(NEWARRAY            , "newarray"        , "bc"   ,  0, TRAP);
def(ANEWARRAY , R , R , 0, TRAP)564         def(ANEWARRAY           , "anewarray"       , "bii"  ,  0, TRAP);
def(ARRAYLENGTH , R , R , 0, TRAP)565         def(ARRAYLENGTH         , "arraylength"     , "b"    ,  0, TRAP);
def(ATHROW , R , R , -1, TRAP | STOP)566         def(ATHROW              , "athrow"          , "b"    , -1, TRAP | STOP);
def(CHECKCAST , R , R , 0, TRAP)567         def(CHECKCAST           , "checkcast"       , "bii"  ,  0, TRAP);
def(INSTANCEOF , R , R , 0, TRAP)568         def(INSTANCEOF          , "instanceof"      , "bii"  ,  0, TRAP);
def(MONITORENTER , R , R , -1, TRAP)569         def(MONITORENTER        , "monitorenter"    , "b"    , -1, TRAP);
def(MONITOREXIT , R , R , -1, TRAP)570         def(MONITOREXIT         , "monitorexit"     , "b"    , -1, TRAP);
def(WIDE , R , R , 0)571         def(WIDE                , "wide"            , ""     ,  0);
def(MULTIANEWARRAY , R , R , 1, TRAP)572         def(MULTIANEWARRAY      , "multianewarray"  , "biic" ,  1, TRAP);
def(IFNULL , R , R , -1, FALL_THROUGH | BRANCH)573         def(IFNULL              , "ifnull"          , "boo"  , -1, FALL_THROUGH | BRANCH);
def(IFNONNULL , R , R , -1, FALL_THROUGH | BRANCH)574         def(IFNONNULL           , "ifnonnull"       , "boo"  , -1, FALL_THROUGH | BRANCH);
def(GOTO_W , R , R, 0, STOP | BRANCH)575         def(GOTO_W              , "goto_w"          , "boooo",  0, STOP | BRANCH);
def(JSR_W , R , R, 0, STOP | BRANCH)576         def(JSR_W               , "jsr_w"           , "boooo",  0, STOP | BRANCH);
def(BREAKPOINT , R , R , 0, TRAP)577         def(BREAKPOINT          , "breakpoint"      , "b"    ,  0, TRAP);
578     }
579     // @formatter:on
580     // Checkstyle: resume
581 
582     /**
583      * Determines if an opcode is commutative.
584      *
585      * @param opcode the opcode to check
586      * @return {@code true} iff commutative
587      */
isCommutative(int opcode)588     public static boolean isCommutative(int opcode) {
589         return (flagsArray[opcode & 0xff] & COMMUTATIVE) != 0;
590     }
591 
592     /**
593      * Gets the length of an instruction denoted by a given opcode.
594      *
595      * @param opcode an instruction opcode
596      * @return the length of the instruction denoted by {@code opcode}. If {@code opcode} is an
597      *         illegal instruction or denotes a variable length instruction (e.g.
598      *         {@link #TABLESWITCH}), then 0 is returned.
599      */
lengthOf(int opcode)600     public static int lengthOf(int opcode) {
601         return lengthArray[opcode & 0xff];
602     }
603 
604     /**
605      * Gets the effect on the depth of the expression stack of an instruction denoted by a given
606      * opcode.
607      *
608      * @param opcode an instruction opcode
609      * @return the change in the stack caused by the instruction denoted by {@code opcode}. If
610      *         {@code opcode} is an illegal instruction then 0 is returned. Note that invoke
611      *         instructions may pop more arguments so this value is a minimum stack effect.
612      */
stackEffectOf(int opcode)613     public static int stackEffectOf(int opcode) {
614         return stackEffectArray[opcode & 0xff];
615     }
616 
617     /**
618      * Gets the lower-case mnemonic for a given opcode.
619      *
620      * @param opcode an opcode
621      * @return the mnemonic for {@code opcode} or {@code "<illegal opcode: " + opcode + ">"} if
622      *         {@code opcode} is not a legal opcode
623      */
nameOf(int opcode)624     public static String nameOf(int opcode) throws IllegalArgumentException {
625         String name = nameArray[opcode & 0xff];
626         if (name == null) {
627             return "<illegal opcode: " + opcode + ">";
628         }
629         return name;
630     }
631 
632     /**
633      * Allocation-free version of {@linkplain #nameOf(int)}.
634      *
635      * @param opcode an opcode.
636      * @return the mnemonic for {@code opcode} or {@code "<illegal opcode>"} if {@code opcode} is
637      *         not a legal opcode.
638      */
baseNameOf(int opcode)639     public static String baseNameOf(int opcode) {
640         String name = nameArray[opcode & 0xff];
641         if (name == null) {
642             return "<illegal opcode>";
643         }
644         return name;
645     }
646 
647     /**
648      * Gets the opcode corresponding to a given mnemonic.
649      *
650      * @param name an opcode mnemonic
651      * @return the opcode corresponding to {@code mnemonic}
652      * @throws IllegalArgumentException if {@code name} does not denote a valid opcode
653      */
valueOf(String name)654     public static int valueOf(String name) {
655         for (int opcode = 0; opcode < nameArray.length; ++opcode) {
656             if (name.equalsIgnoreCase(nameArray[opcode])) {
657                 return opcode;
658             }
659         }
660         throw new IllegalArgumentException("No opcode for " + name);
661     }
662 
663     /**
664      * Determines if a given opcode denotes an instruction that can cause an implicit exception.
665      *
666      * @param opcode an opcode to test
667      * @return {@code true} iff {@code opcode} can cause an implicit exception, {@code false}
668      *         otherwise
669      */
canTrap(int opcode)670     public static boolean canTrap(int opcode) {
671         return (flagsArray[opcode & 0xff] & TRAP) != 0;
672     }
673 
674     /**
675      * Determines if a given opcode denotes an instruction that loads a local variable to the
676      * operand stack.
677      *
678      * @param opcode an opcode to test
679      * @return {@code true} iff {@code opcode} loads a local variable to the operand stack,
680      *         {@code false} otherwise
681      */
isLoad(int opcode)682     public static boolean isLoad(int opcode) {
683         return (flagsArray[opcode & 0xff] & LOAD) != 0;
684     }
685 
686     /**
687      * Determines if a given opcode denotes an instruction that ends a basic block and does not let
688      * control flow fall through to its lexical successor.
689      *
690      * @param opcode an opcode to test
691      * @return {@code true} iff {@code opcode} properly ends a basic block
692      */
isStop(int opcode)693     public static boolean isStop(int opcode) {
694         return (flagsArray[opcode & 0xff] & STOP) != 0;
695     }
696 
697     /**
698      * Determines if a given opcode denotes an instruction that stores a value to a local variable
699      * after popping it from the operand stack.
700      *
701      * @param opcode an opcode to test
702      * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false}
703      *         otherwise
704      */
isInvoke(int opcode)705     public static boolean isInvoke(int opcode) {
706         return (flagsArray[opcode & 0xff] & INVOKE) != 0;
707     }
708 
709     /**
710      * Determines if a given opcode denotes an instruction that stores a value to a local variable
711      * after popping it from the operand stack.
712      *
713      * @param opcode an opcode to test
714      * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false}
715      *         otherwise
716      */
isStore(int opcode)717     public static boolean isStore(int opcode) {
718         return (flagsArray[opcode & 0xff] & STORE) != 0;
719     }
720 
721     /**
722      * Determines if a given opcode is an instruction that delimits a basic block.
723      *
724      * @param opcode an opcode to test
725      * @return {@code true} iff {@code opcode} delimits a basic block
726      */
isBlockEnd(int opcode)727     public static boolean isBlockEnd(int opcode) {
728         return (flagsArray[opcode & 0xff] & (STOP | FALL_THROUGH)) != 0;
729     }
730 
731     /**
732      * Determines if a given opcode is an instruction that has a 2 or 4 byte operand that is an
733      * offset to another instruction in the same method. This does not include the
734      * {@linkplain #TABLESWITCH switch} instructions.
735      *
736      * @param opcode an opcode to test
737      * @return {@code true} iff {@code opcode} is a branch instruction with a single operand
738      */
isBranch(int opcode)739     public static boolean isBranch(int opcode) {
740         return (flagsArray[opcode & 0xff] & BRANCH) != 0;
741     }
742 
743     /**
744      * Determines if a given opcode denotes a conditional branch.
745      *
746      * @param opcode
747      * @return {@code true} iff {@code opcode} is a conditional branch
748      */
isConditionalBranch(int opcode)749     public static boolean isConditionalBranch(int opcode) {
750         return (flagsArray[opcode & 0xff] & FALL_THROUGH) != 0;
751     }
752 
753     /**
754      * Gets the arithmetic operator name for a given opcode. If {@code opcode} does not denote an
755      * arithmetic instruction, then the {@linkplain #nameOf(int) name} of the opcode is returned
756      * instead.
757      *
758      * @param op an opcode
759      * @return the arithmetic operator name
760      */
operator(int op)761     public static String operator(int op) {
762         // Checkstyle: stop
763         switch (op) {
764             // arithmetic ops
765             case IADD: // fall through
766             case LADD: // fall through
767             case FADD: // fall through
768             case DADD:
769                 return "+";
770             case ISUB: // fall through
771             case LSUB: // fall through
772             case FSUB: // fall through
773             case DSUB:
774                 return "-";
775             case IMUL: // fall through
776             case LMUL: // fall through
777             case FMUL: // fall through
778             case DMUL:
779                 return "*";
780             case IDIV: // fall through
781             case LDIV: // fall through
782             case FDIV: // fall through
783             case DDIV:
784                 return "/";
785             case IREM: // fall through
786             case LREM: // fall through
787             case FREM: // fall through
788             case DREM:
789                 return "%";
790             // shift ops
791             case ISHL: // fall through
792             case LSHL:
793                 return "<<";
794             case ISHR: // fall through
795             case LSHR:
796                 return ">>";
797             case IUSHR: // fall through
798             case LUSHR:
799                 return ">>>";
800             // logic ops
801             case IAND: // fall through
802             case LAND:
803                 return "&";
804             case IOR: // fall through
805             case LOR:
806                 return "|";
807             case IXOR: // fall through
808             case LXOR:
809                 return "^";
810         }
811         // Checkstyle: resume
812         return nameOf(op);
813     }
814 
815     /**
816      * Defines a bytecode by entering it into the arrays that record its name, length and flags.
817      *
818      * @param name instruction name (should be lower case)
819      * @param format encodes the length of the instruction
820      */
def(int opcode, String name, String format, int stackEffect)821     private static void def(int opcode, String name, String format, int stackEffect) {
822         def(opcode, name, format, stackEffect, 0);
823     }
824 
825     /**
826      * Defines a bytecode by entering it into the arrays that record its name, length and flags.
827      *
828      * @param name instruction name (lower case)
829      * @param format encodes the length of the instruction
830      * @param flags the set of {@link Flags} associated with the instruction
831      */
def(int opcode, String name, String format, int stackEffect, int flags)832     private static void def(int opcode, String name, String format, int stackEffect, int flags) {
833         assert nameArray[opcode] == null : "opcode " + opcode + " is already bound to name " + nameArray[opcode];
834         nameArray[opcode] = name;
835         int instructionLength = format.length();
836         lengthArray[opcode] = instructionLength;
837         stackEffectArray[opcode] = stackEffect;
838         Bytecodes.flagsArray[opcode] = flags;
839 
840         assert !isConditionalBranch(opcode) || isBranch(opcode) : "a conditional branch must also be a branch";
841     }
842 
isIfBytecode(int bytecode)843     public static boolean isIfBytecode(int bytecode) {
844         switch (bytecode) {
845             case IFEQ:
846             case IFNE:
847             case IFLT:
848             case IFGE:
849             case IFGT:
850             case IFLE:
851             case IF_ICMPEQ:
852             case IF_ICMPNE:
853             case IF_ICMPLT:
854             case IF_ICMPGE:
855             case IF_ICMPGT:
856             case IF_ICMPLE:
857             case IF_ACMPEQ:
858             case IF_ACMPNE:
859             case IFNULL:
860             case IFNONNULL:
861                 return true;
862         }
863         return false;
864     }
865 }
866