1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.dx.cf.code;
18 
19 import com.android.dx.util.Hex;
20 
21 /**
22  * Constants and utility methods for dealing with bytecode arrays at an
23  * opcode level.
24  */
25 public class ByteOps {
26     // one constant per opcode
27     public static final int NOP = 0x00;
28     public static final int ACONST_NULL = 0x01;
29     public static final int ICONST_M1 = 0x02;
30     public static final int ICONST_0 = 0x03;
31     public static final int ICONST_1 = 0x04;
32     public static final int ICONST_2 = 0x05;
33     public static final int ICONST_3 = 0x06;
34     public static final int ICONST_4 = 0x07;
35     public static final int ICONST_5 = 0x08;
36     public static final int LCONST_0 = 0x09;
37     public static final int LCONST_1 = 0x0a;
38     public static final int FCONST_0 = 0x0b;
39     public static final int FCONST_1 = 0x0c;
40     public static final int FCONST_2 = 0x0d;
41     public static final int DCONST_0 = 0x0e;
42     public static final int DCONST_1 = 0x0f;
43     public static final int BIPUSH = 0x10;
44     public static final int SIPUSH = 0x11;
45     public static final int LDC = 0x12;
46     public static final int LDC_W = 0x13;
47     public static final int LDC2_W = 0x14;
48     public static final int ILOAD = 0x15;
49     public static final int LLOAD = 0x16;
50     public static final int FLOAD = 0x17;
51     public static final int DLOAD = 0x18;
52     public static final int ALOAD = 0x19;
53     public static final int ILOAD_0 = 0x1a;
54     public static final int ILOAD_1 = 0x1b;
55     public static final int ILOAD_2 = 0x1c;
56     public static final int ILOAD_3 = 0x1d;
57     public static final int LLOAD_0 = 0x1e;
58     public static final int LLOAD_1 = 0x1f;
59     public static final int LLOAD_2 = 0x20;
60     public static final int LLOAD_3 = 0x21;
61     public static final int FLOAD_0 = 0x22;
62     public static final int FLOAD_1 = 0x23;
63     public static final int FLOAD_2 = 0x24;
64     public static final int FLOAD_3 = 0x25;
65     public static final int DLOAD_0 = 0x26;
66     public static final int DLOAD_1 = 0x27;
67     public static final int DLOAD_2 = 0x28;
68     public static final int DLOAD_3 = 0x29;
69     public static final int ALOAD_0 = 0x2a;
70     public static final int ALOAD_1 = 0x2b;
71     public static final int ALOAD_2 = 0x2c;
72     public static final int ALOAD_3 = 0x2d;
73     public static final int IALOAD = 0x2e;
74     public static final int LALOAD = 0x2f;
75     public static final int FALOAD = 0x30;
76     public static final int DALOAD = 0x31;
77     public static final int AALOAD = 0x32;
78     public static final int BALOAD = 0x33;
79     public static final int CALOAD = 0x34;
80     public static final int SALOAD = 0x35;
81     public static final int ISTORE = 0x36;
82     public static final int LSTORE = 0x37;
83     public static final int FSTORE = 0x38;
84     public static final int DSTORE = 0x39;
85     public static final int ASTORE = 0x3a;
86     public static final int ISTORE_0 = 0x3b;
87     public static final int ISTORE_1 = 0x3c;
88     public static final int ISTORE_2 = 0x3d;
89     public static final int ISTORE_3 = 0x3e;
90     public static final int LSTORE_0 = 0x3f;
91     public static final int LSTORE_1 = 0x40;
92     public static final int LSTORE_2 = 0x41;
93     public static final int LSTORE_3 = 0x42;
94     public static final int FSTORE_0 = 0x43;
95     public static final int FSTORE_1 = 0x44;
96     public static final int FSTORE_2 = 0x45;
97     public static final int FSTORE_3 = 0x46;
98     public static final int DSTORE_0 = 0x47;
99     public static final int DSTORE_1 = 0x48;
100     public static final int DSTORE_2 = 0x49;
101     public static final int DSTORE_3 = 0x4a;
102     public static final int ASTORE_0 = 0x4b;
103     public static final int ASTORE_1 = 0x4c;
104     public static final int ASTORE_2 = 0x4d;
105     public static final int ASTORE_3 = 0x4e;
106     public static final int IASTORE = 0x4f;
107     public static final int LASTORE = 0x50;
108     public static final int FASTORE = 0x51;
109     public static final int DASTORE = 0x52;
110     public static final int AASTORE = 0x53;
111     public static final int BASTORE = 0x54;
112     public static final int CASTORE = 0x55;
113     public static final int SASTORE = 0x56;
114     public static final int POP = 0x57;
115     public static final int POP2 = 0x58;
116     public static final int DUP = 0x59;
117     public static final int DUP_X1 = 0x5a;
118     public static final int DUP_X2 = 0x5b;
119     public static final int DUP2 = 0x5c;
120     public static final int DUP2_X1 = 0x5d;
121     public static final int DUP2_X2 = 0x5e;
122     public static final int SWAP = 0x5f;
123     public static final int IADD = 0x60;
124     public static final int LADD = 0x61;
125     public static final int FADD = 0x62;
126     public static final int DADD = 0x63;
127     public static final int ISUB = 0x64;
128     public static final int LSUB = 0x65;
129     public static final int FSUB = 0x66;
130     public static final int DSUB = 0x67;
131     public static final int IMUL = 0x68;
132     public static final int LMUL = 0x69;
133     public static final int FMUL = 0x6a;
134     public static final int DMUL = 0x6b;
135     public static final int IDIV = 0x6c;
136     public static final int LDIV = 0x6d;
137     public static final int FDIV = 0x6e;
138     public static final int DDIV = 0x6f;
139     public static final int IREM = 0x70;
140     public static final int LREM = 0x71;
141     public static final int FREM = 0x72;
142     public static final int DREM = 0x73;
143     public static final int INEG = 0x74;
144     public static final int LNEG = 0x75;
145     public static final int FNEG = 0x76;
146     public static final int DNEG = 0x77;
147     public static final int ISHL = 0x78;
148     public static final int LSHL = 0x79;
149     public static final int ISHR = 0x7a;
150     public static final int LSHR = 0x7b;
151     public static final int IUSHR = 0x7c;
152     public static final int LUSHR = 0x7d;
153     public static final int IAND = 0x7e;
154     public static final int LAND = 0x7f;
155     public static final int IOR = 0x80;
156     public static final int LOR = 0x81;
157     public static final int IXOR = 0x82;
158     public static final int LXOR = 0x83;
159     public static final int IINC = 0x84;
160     public static final int I2L = 0x85;
161     public static final int I2F = 0x86;
162     public static final int I2D = 0x87;
163     public static final int L2I = 0x88;
164     public static final int L2F = 0x89;
165     public static final int L2D = 0x8a;
166     public static final int F2I = 0x8b;
167     public static final int F2L = 0x8c;
168     public static final int F2D = 0x8d;
169     public static final int D2I = 0x8e;
170     public static final int D2L = 0x8f;
171     public static final int D2F = 0x90;
172     public static final int I2B = 0x91;
173     public static final int I2C = 0x92;
174     public static final int I2S = 0x93;
175     public static final int LCMP = 0x94;
176     public static final int FCMPL = 0x95;
177     public static final int FCMPG = 0x96;
178     public static final int DCMPL = 0x97;
179     public static final int DCMPG = 0x98;
180     public static final int IFEQ = 0x99;
181     public static final int IFNE = 0x9a;
182     public static final int IFLT = 0x9b;
183     public static final int IFGE = 0x9c;
184     public static final int IFGT = 0x9d;
185     public static final int IFLE = 0x9e;
186     public static final int IF_ICMPEQ = 0x9f;
187     public static final int IF_ICMPNE = 0xa0;
188     public static final int IF_ICMPLT = 0xa1;
189     public static final int IF_ICMPGE = 0xa2;
190     public static final int IF_ICMPGT = 0xa3;
191     public static final int IF_ICMPLE = 0xa4;
192     public static final int IF_ACMPEQ = 0xa5;
193     public static final int IF_ACMPNE = 0xa6;
194     public static final int GOTO = 0xa7;
195     public static final int JSR = 0xa8;
196     public static final int RET = 0xa9;
197     public static final int TABLESWITCH = 0xaa;
198     public static final int LOOKUPSWITCH = 0xab;
199     public static final int IRETURN = 0xac;
200     public static final int LRETURN = 0xad;
201     public static final int FRETURN = 0xae;
202     public static final int DRETURN = 0xaf;
203     public static final int ARETURN = 0xb0;
204     public static final int RETURN = 0xb1;
205     public static final int GETSTATIC = 0xb2;
206     public static final int PUTSTATIC = 0xb3;
207     public static final int GETFIELD = 0xb4;
208     public static final int PUTFIELD = 0xb5;
209     public static final int INVOKEVIRTUAL = 0xb6;
210     public static final int INVOKESPECIAL = 0xb7;
211     public static final int INVOKESTATIC = 0xb8;
212     public static final int INVOKEINTERFACE = 0xb9;
213     public static final int INVOKEDYNAMIC = 0xba;
214     public static final int NEW = 0xbb;
215     public static final int NEWARRAY = 0xbc;
216     public static final int ANEWARRAY = 0xbd;
217     public static final int ARRAYLENGTH = 0xbe;
218     public static final int ATHROW = 0xbf;
219     public static final int CHECKCAST = 0xc0;
220     public static final int INSTANCEOF = 0xc1;
221     public static final int MONITORENTER = 0xc2;
222     public static final int MONITOREXIT = 0xc3;
223     public static final int WIDE = 0xc4;
224     public static final int MULTIANEWARRAY = 0xc5;
225     public static final int IFNULL = 0xc6;
226     public static final int IFNONNULL = 0xc7;
227     public static final int GOTO_W = 0xc8;
228     public static final int JSR_W = 0xc9;
229 
230     // a constant for each valid argument to "newarray"
231 
232     public static final int NEWARRAY_BOOLEAN = 4;
233     public static final int NEWARRAY_CHAR = 5;
234     public static final int NEWARRAY_FLOAT = 6;
235     public static final int NEWARRAY_DOUBLE = 7;
236     public static final int NEWARRAY_BYTE = 8;
237     public static final int NEWARRAY_SHORT = 9;
238     public static final int NEWARRAY_INT = 10;
239     public static final int NEWARRAY_LONG = 11;
240 
241     // a constant for each possible instruction format
242 
243     /** invalid */
244     public static final int FMT_INVALID = 0;
245 
246     /** "-": {@code op} */
247     public static final int FMT_NO_ARGS = 1;
248 
249     /** "0": {@code op}; implies {@code max_locals >= 1} */
250     public static final int FMT_NO_ARGS_LOCALS_1 = 2;
251 
252     /** "1": {@code op}; implies {@code max_locals >= 2} */
253     public static final int FMT_NO_ARGS_LOCALS_2 = 3;
254 
255     /** "2": {@code op}; implies {@code max_locals >= 3} */
256     public static final int FMT_NO_ARGS_LOCALS_3 = 4;
257 
258     /** "3": {@code op}; implies {@code max_locals >= 4} */
259     public static final int FMT_NO_ARGS_LOCALS_4 = 5;
260 
261     /** "4": {@code op}; implies {@code max_locals >= 5} */
262     public static final int FMT_NO_ARGS_LOCALS_5 = 6;
263 
264     /** "b": {@code op target target} */
265     public static final int FMT_BRANCH = 7;
266 
267     /** "c": {@code op target target target target} */
268     public static final int FMT_WIDE_BRANCH = 8;
269 
270     /** "p": {@code op #cpi #cpi}; constant restricted as specified */
271     public static final int FMT_CPI = 9;
272 
273     /**
274      * "l": {@code op local}; category-1 local; implies
275      * {@code max_locals} is at least two more than the given
276      * local number
277      */
278     public static final int FMT_LOCAL_1 = 10;
279 
280     /**
281      * "m": {@code op local}; category-2 local; implies
282      * {@code max_locals} is at least two more than the given
283      * local number
284      */
285     public static final int FMT_LOCAL_2 = 11;
286 
287     /**
288      * "y": {@code op #byte} ({@code bipush} and
289      * {@code newarray})
290      */
291     public static final int FMT_LITERAL_BYTE = 12;
292 
293     /** "I": {@code invokeinterface cpi cpi count 0} */
294     public static final int FMT_INVOKEINTERFACE = 13;
295 
296     /** "L": {@code ldc #cpi}; constant restricted as specified */
297     public static final int FMT_LDC = 14;
298 
299     /** "S": {@code sipush #byte #byte} */
300     public static final int FMT_SIPUSH = 15;
301 
302     /** "T": {@code tableswitch ...} */
303     public static final int FMT_TABLESWITCH = 16;
304 
305     /** "U": {@code lookupswitch ...} */
306     public static final int FMT_LOOKUPSWITCH = 17;
307 
308     /** "M": {@code multianewarray cpi cpi dims} */
309     public static final int FMT_MULTIANEWARRAY = 18;
310 
311     /** "W": {@code wide ...} */
312     public static final int FMT_WIDE = 19;
313 
314     /** mask for the bits representing the opcode format */
315     public static final int FMT_MASK = 0x1f;
316 
317     /** "I": flag bit for valid cp type for {@code Integer} */
318     public static final int CPOK_Integer = 0x20;
319 
320     /** "F": flag bit for valid cp type for {@code Float} */
321     public static final int CPOK_Float = 0x40;
322 
323     /** "J": flag bit for valid cp type for {@code Long} */
324     public static final int CPOK_Long = 0x80;
325 
326     /** "D": flag bit for valid cp type for {@code Double} */
327     public static final int CPOK_Double = 0x100;
328 
329     /** "c": flag bit for valid cp type for {@code Class} */
330     public static final int CPOK_Class = 0x200;
331 
332     /** "s": flag bit for valid cp type for {@code String} */
333     public static final int CPOK_String = 0x400;
334 
335     /** "f": flag bit for valid cp type for {@code Fieldref} */
336     public static final int CPOK_Fieldref = 0x800;
337 
338     /** "m": flag bit for valid cp type for {@code Methodref} */
339     public static final int CPOK_Methodref = 0x1000;
340 
341     /** "i": flag bit for valid cp type for {@code InterfaceMethodref} */
342     public static final int CPOK_InterfaceMethodref = 0x2000;
343 
344     /**
345      * {@code non-null;} map from opcodes to format or'ed with allowed constant
346      * pool types
347      */
348     private static final int[] OPCODE_INFO = new int[256];
349 
350     /** {@code non-null;} map from opcodes to their names */
351     private static final String[] OPCODE_NAMES = new String[256];
352 
353     /** {@code non-null;} bigass string describing all the opcodes */
354     private static final String OPCODE_DETAILS =
355         "00 - nop;" +
356         "01 - aconst_null;" +
357         "02 - iconst_m1;" +
358         "03 - iconst_0;" +
359         "04 - iconst_1;" +
360         "05 - iconst_2;" +
361         "06 - iconst_3;" +
362         "07 - iconst_4;" +
363         "08 - iconst_5;" +
364         "09 - lconst_0;" +
365         "0a - lconst_1;" +
366         "0b - fconst_0;" +
367         "0c - fconst_1;" +
368         "0d - fconst_2;" +
369         "0e - dconst_0;" +
370         "0f - dconst_1;" +
371         "10 y bipush;" +
372         "11 S sipush;" +
373         "12 L:IFcs ldc;" +
374         "13 p:IFcs ldc_w;" +
375         "14 p:DJ ldc2_w;" +
376         "15 l iload;" +
377         "16 m lload;" +
378         "17 l fload;" +
379         "18 m dload;" +
380         "19 l aload;" +
381         "1a 0 iload_0;" +
382         "1b 1 iload_1;" +
383         "1c 2 iload_2;" +
384         "1d 3 iload_3;" +
385         "1e 1 lload_0;" +
386         "1f 2 lload_1;" +
387         "20 3 lload_2;" +
388         "21 4 lload_3;" +
389         "22 0 fload_0;" +
390         "23 1 fload_1;" +
391         "24 2 fload_2;" +
392         "25 3 fload_3;" +
393         "26 1 dload_0;" +
394         "27 2 dload_1;" +
395         "28 3 dload_2;" +
396         "29 4 dload_3;" +
397         "2a 0 aload_0;" +
398         "2b 1 aload_1;" +
399         "2c 2 aload_2;" +
400         "2d 3 aload_3;" +
401         "2e - iaload;" +
402         "2f - laload;" +
403         "30 - faload;" +
404         "31 - daload;" +
405         "32 - aaload;" +
406         "33 - baload;" +
407         "34 - caload;" +
408         "35 - saload;" +
409         "36 - istore;" +
410         "37 - lstore;" +
411         "38 - fstore;" +
412         "39 - dstore;" +
413         "3a - astore;" +
414         "3b 0 istore_0;" +
415         "3c 1 istore_1;" +
416         "3d 2 istore_2;" +
417         "3e 3 istore_3;" +
418         "3f 1 lstore_0;" +
419         "40 2 lstore_1;" +
420         "41 3 lstore_2;" +
421         "42 4 lstore_3;" +
422         "43 0 fstore_0;" +
423         "44 1 fstore_1;" +
424         "45 2 fstore_2;" +
425         "46 3 fstore_3;" +
426         "47 1 dstore_0;" +
427         "48 2 dstore_1;" +
428         "49 3 dstore_2;" +
429         "4a 4 dstore_3;" +
430         "4b 0 astore_0;" +
431         "4c 1 astore_1;" +
432         "4d 2 astore_2;" +
433         "4e 3 astore_3;" +
434         "4f - iastore;" +
435         "50 - lastore;" +
436         "51 - fastore;" +
437         "52 - dastore;" +
438         "53 - aastore;" +
439         "54 - bastore;" +
440         "55 - castore;" +
441         "56 - sastore;" +
442         "57 - pop;" +
443         "58 - pop2;" +
444         "59 - dup;" +
445         "5a - dup_x1;" +
446         "5b - dup_x2;" +
447         "5c - dup2;" +
448         "5d - dup2_x1;" +
449         "5e - dup2_x2;" +
450         "5f - swap;" +
451         "60 - iadd;" +
452         "61 - ladd;" +
453         "62 - fadd;" +
454         "63 - dadd;" +
455         "64 - isub;" +
456         "65 - lsub;" +
457         "66 - fsub;" +
458         "67 - dsub;" +
459         "68 - imul;" +
460         "69 - lmul;" +
461         "6a - fmul;" +
462         "6b - dmul;" +
463         "6c - idiv;" +
464         "6d - ldiv;" +
465         "6e - fdiv;" +
466         "6f - ddiv;" +
467         "70 - irem;" +
468         "71 - lrem;" +
469         "72 - frem;" +
470         "73 - drem;" +
471         "74 - ineg;" +
472         "75 - lneg;" +
473         "76 - fneg;" +
474         "77 - dneg;" +
475         "78 - ishl;" +
476         "79 - lshl;" +
477         "7a - ishr;" +
478         "7b - lshr;" +
479         "7c - iushr;" +
480         "7d - lushr;" +
481         "7e - iand;" +
482         "7f - land;" +
483         "80 - ior;" +
484         "81 - lor;" +
485         "82 - ixor;" +
486         "83 - lxor;" +
487         "84 l iinc;" +
488         "85 - i2l;" +
489         "86 - i2f;" +
490         "87 - i2d;" +
491         "88 - l2i;" +
492         "89 - l2f;" +
493         "8a - l2d;" +
494         "8b - f2i;" +
495         "8c - f2l;" +
496         "8d - f2d;" +
497         "8e - d2i;" +
498         "8f - d2l;" +
499         "90 - d2f;" +
500         "91 - i2b;" +
501         "92 - i2c;" +
502         "93 - i2s;" +
503         "94 - lcmp;" +
504         "95 - fcmpl;" +
505         "96 - fcmpg;" +
506         "97 - dcmpl;" +
507         "98 - dcmpg;" +
508         "99 b ifeq;" +
509         "9a b ifne;" +
510         "9b b iflt;" +
511         "9c b ifge;" +
512         "9d b ifgt;" +
513         "9e b ifle;" +
514         "9f b if_icmpeq;" +
515         "a0 b if_icmpne;" +
516         "a1 b if_icmplt;" +
517         "a2 b if_icmpge;" +
518         "a3 b if_icmpgt;" +
519         "a4 b if_icmple;" +
520         "a5 b if_acmpeq;" +
521         "a6 b if_acmpne;" +
522         "a7 b goto;" +
523         "a8 b jsr;" +
524         "a9 l ret;" +
525         "aa T tableswitch;" +
526         "ab U lookupswitch;" +
527         "ac - ireturn;" +
528         "ad - lreturn;" +
529         "ae - freturn;" +
530         "af - dreturn;" +
531         "b0 - areturn;" +
532         "b1 - return;" +
533         "b2 p:f getstatic;" +
534         "b3 p:f putstatic;" +
535         "b4 p:f getfield;" +
536         "b5 p:f putfield;" +
537         "b6 p:m invokevirtual;" +
538         "b7 p:m invokespecial;" +
539         "b8 p:m invokestatic;" +
540         "b9 I:i invokeinterface;" +
541         "bb p:c new;" +
542         "bc y newarray;" +
543         "bd p:c anewarray;" +
544         "be - arraylength;" +
545         "bf - athrow;" +
546         "c0 p:c checkcast;" +
547         "c1 p:c instanceof;" +
548         "c2 - monitorenter;" +
549         "c3 - monitorexit;" +
550         "c4 W wide;" +
551         "c5 M:c multianewarray;" +
552         "c6 b ifnull;" +
553         "c7 b ifnonnull;" +
554         "c8 c goto_w;" +
555         "c9 c jsr_w;";
556 
557     static {
558         // Set up OPCODE_INFO and OPCODE_NAMES.
559         String s = OPCODE_DETAILS;
560         int len = s.length();
561 
562         for (int i = 0; i < len; /*i*/) {
563             int idx = (Character.digit(s.charAt(i), 16) << 4) |
564                 Character.digit(s.charAt(i + 1), 16);
565             int info;
566             switch (s.charAt(i + 3)) {
567                 case '-': info = FMT_NO_ARGS; break;
568                 case '0': info = FMT_NO_ARGS_LOCALS_1; break;
569                 case '1': info = FMT_NO_ARGS_LOCALS_2; break;
570                 case '2': info = FMT_NO_ARGS_LOCALS_3; break;
571                 case '3': info = FMT_NO_ARGS_LOCALS_4; break;
572                 case '4': info = FMT_NO_ARGS_LOCALS_5; break;
573                 case 'b': info = FMT_BRANCH; break;
574                 case 'c': info = FMT_WIDE_BRANCH; break;
575                 case 'p': info = FMT_CPI; break;
576                 case 'l': info = FMT_LOCAL_1; break;
577                 case 'm': info = FMT_LOCAL_2; break;
578                 case 'y': info = FMT_LITERAL_BYTE; break;
579                 case 'I': info = FMT_INVOKEINTERFACE; break;
580                 case 'L': info = FMT_LDC; break;
581                 case 'S': info = FMT_SIPUSH; break;
582                 case 'T': info = FMT_TABLESWITCH; break;
583                 case 'U': info = FMT_LOOKUPSWITCH; break;
584                 case 'M': info = FMT_MULTIANEWARRAY; break;
585                 case 'W': info = FMT_WIDE; break;
586                 default: info = FMT_INVALID; break;
587             }
588 
589             i += 5;
590             if (s.charAt(i - 1) == ':') {
591                 inner:
592                 for (;;) {
593                     switch (s.charAt(i)) {
594                         case 'I': info |= CPOK_Integer; break;
595                         case 'F': info |= CPOK_Float; break;
596                         case 'J': info |= CPOK_Long; break;
597                         case 'D': info |= CPOK_Double; break;
598                         case 'c': info |= CPOK_Class; break;
599                         case 's': info |= CPOK_String; break;
600                         case 'f': info |= CPOK_Fieldref; break;
601                         case 'm': info |= CPOK_Methodref; break;
602                         case 'i': info |= CPOK_InterfaceMethodref; break;
603                         default: break inner;
604                     }
605                     i++;
606                 }
607                 i++;
608             }
609 
610             int endAt = s.indexOf(';', i);
611             OPCODE_INFO[idx] = info;
612             OPCODE_NAMES[idx] = s.substring(i, endAt);
613             i = endAt + 1;
614         }
615     }
616 
617     /**
618      * This class is uninstantiable.
619      */
ByteOps()620     private ByteOps() {
621         // This space intentionally left blank.
622     }
623 
624     /**
625      * Gets the name of the given opcode.
626      *
627      * @param opcode {@code >= 0, <= 255;} the opcode
628      * @return {@code non-null;} its name
629      */
opName(int opcode)630     public static String opName(int opcode) {
631         String result = OPCODE_NAMES[opcode];
632 
633         if (result == null) {
634             result = "unused_" + Hex.u1(opcode);
635             OPCODE_NAMES[opcode] = result;
636         }
637 
638         return result;
639     }
640 
641     /**
642      * Gets the format and allowed cp types of the given opcode.
643      *
644      * @param opcode {@code >= 0, <= 255;} the opcode
645      * @return its format and allowed cp types
646      */
opInfo(int opcode)647     public static int opInfo(int opcode) {
648         return OPCODE_INFO[opcode];
649     }
650 }
651