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
17package com.android.dx.cf.code;
18
19import com.android.dx.util.Hex;
20
21/**
22 * Constants and utility methods for dealing with bytecode arrays at an
23 * opcode level.
24 */
25public 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 NEW = 0xbb;
214    public static final int NEWARRAY = 0xbc;
215    public static final int ANEWARRAY = 0xbd;
216    public static final int ARRAYLENGTH = 0xbe;
217    public static final int ATHROW = 0xbf;
218    public static final int CHECKCAST = 0xc0;
219    public static final int INSTANCEOF = 0xc1;
220    public static final int MONITORENTER = 0xc2;
221    public static final int MONITOREXIT = 0xc3;
222    public static final int WIDE = 0xc4;
223    public static final int MULTIANEWARRAY = 0xc5;
224    public static final int IFNULL = 0xc6;
225    public static final int IFNONNULL = 0xc7;
226    public static final int GOTO_W = 0xc8;
227    public static final int JSR_W = 0xc9;
228
229    // a constant for each valid argument to "newarray"
230
231    public static final int NEWARRAY_BOOLEAN = 4;
232    public static final int NEWARRAY_CHAR = 5;
233    public static final int NEWARRAY_FLOAT = 6;
234    public static final int NEWARRAY_DOUBLE = 7;
235    public static final int NEWARRAY_BYTE = 8;
236    public static final int NEWARRAY_SHORT = 9;
237    public static final int NEWARRAY_INT = 10;
238    public static final int NEWARRAY_LONG = 11;
239
240    // a constant for each possible instruction format
241
242    /** invalid */
243    public static final int FMT_INVALID = 0;
244
245    /** "-": {@code op} */
246    public static final int FMT_NO_ARGS = 1;
247
248    /** "0": {@code op}; implies {@code max_locals >= 1} */
249    public static final int FMT_NO_ARGS_LOCALS_1 = 2;
250
251    /** "1": {@code op}; implies {@code max_locals >= 2} */
252    public static final int FMT_NO_ARGS_LOCALS_2 = 3;
253
254    /** "2": {@code op}; implies {@code max_locals >= 3} */
255    public static final int FMT_NO_ARGS_LOCALS_3 = 4;
256
257    /** "3": {@code op}; implies {@code max_locals >= 4} */
258    public static final int FMT_NO_ARGS_LOCALS_4 = 5;
259
260    /** "4": {@code op}; implies {@code max_locals >= 5} */
261    public static final int FMT_NO_ARGS_LOCALS_5 = 6;
262
263    /** "b": {@code op target target} */
264    public static final int FMT_BRANCH = 7;
265
266    /** "c": {@code op target target target target} */
267    public static final int FMT_WIDE_BRANCH = 8;
268
269    /** "p": {@code op #cpi #cpi}; constant restricted as specified */
270    public static final int FMT_CPI = 9;
271
272    /**
273     * "l": {@code op local}; category-1 local; implies
274     * {@code max_locals} is at least two more than the given
275     * local number
276     */
277    public static final int FMT_LOCAL_1 = 10;
278
279    /**
280     * "m": {@code op local}; category-2 local; implies
281     * {@code max_locals} is at least two more than the given
282     * local number
283     */
284    public static final int FMT_LOCAL_2 = 11;
285
286    /**
287     * "y": {@code op #byte} ({@code bipush} and
288     * {@code newarray})
289     */
290    public static final int FMT_LITERAL_BYTE = 12;
291
292    /** "I": {@code invokeinterface cpi cpi count 0} */
293    public static final int FMT_INVOKEINTERFACE = 13;
294
295    /** "L": {@code ldc #cpi}; constant restricted as specified */
296    public static final int FMT_LDC = 14;
297
298    /** "S": {@code sipush #byte #byte} */
299    public static final int FMT_SIPUSH = 15;
300
301    /** "T": {@code tableswitch ...} */
302    public static final int FMT_TABLESWITCH = 16;
303
304    /** "U": {@code lookupswitch ...} */
305    public static final int FMT_LOOKUPSWITCH = 17;
306
307    /** "M": {@code multianewarray cpi cpi dims} */
308    public static final int FMT_MULTIANEWARRAY = 18;
309
310    /** "W": {@code wide ...} */
311    public static final int FMT_WIDE = 19;
312
313    /** mask for the bits representing the opcode format */
314    public static final int FMT_MASK = 0x1f;
315
316    /** "I": flag bit for valid cp type for {@code Integer} */
317    public static final int CPOK_Integer = 0x20;
318
319    /** "F": flag bit for valid cp type for {@code Float} */
320    public static final int CPOK_Float = 0x40;
321
322    /** "J": flag bit for valid cp type for {@code Long} */
323    public static final int CPOK_Long = 0x80;
324
325    /** "D": flag bit for valid cp type for {@code Double} */
326    public static final int CPOK_Double = 0x100;
327
328    /** "c": flag bit for valid cp type for {@code Class} */
329    public static final int CPOK_Class = 0x200;
330
331    /** "s": flag bit for valid cp type for {@code String} */
332    public static final int CPOK_String = 0x400;
333
334    /** "f": flag bit for valid cp type for {@code Fieldref} */
335    public static final int CPOK_Fieldref = 0x800;
336
337    /** "m": flag bit for valid cp type for {@code Methodref} */
338    public static final int CPOK_Methodref = 0x1000;
339
340    /** "i": flag bit for valid cp type for {@code InterfaceMethodref} */
341    public static final int CPOK_InterfaceMethodref = 0x2000;
342
343    /**
344     * {@code non-null;} map from opcodes to format or'ed with allowed constant
345     * pool types
346     */
347    private static final int[] OPCODE_INFO = new int[256];
348
349    /** {@code non-null;} map from opcodes to their names */
350    private static final String[] OPCODE_NAMES = new String[256];
351
352    /** {@code non-null;} bigass string describing all the opcodes */
353    private static final String OPCODE_DETAILS =
354        "00 - nop;" +
355        "01 - aconst_null;" +
356        "02 - iconst_m1;" +
357        "03 - iconst_0;" +
358        "04 - iconst_1;" +
359        "05 - iconst_2;" +
360        "06 - iconst_3;" +
361        "07 - iconst_4;" +
362        "08 - iconst_5;" +
363        "09 - lconst_0;" +
364        "0a - lconst_1;" +
365        "0b - fconst_0;" +
366        "0c - fconst_1;" +
367        "0d - fconst_2;" +
368        "0e - dconst_0;" +
369        "0f - dconst_1;" +
370        "10 y bipush;" +
371        "11 S sipush;" +
372        "12 L:IFcs ldc;" +
373        "13 p:IFcs ldc_w;" +
374        "14 p:DJ ldc2_w;" +
375        "15 l iload;" +
376        "16 m lload;" +
377        "17 l fload;" +
378        "18 m dload;" +
379        "19 l aload;" +
380        "1a 0 iload_0;" +
381        "1b 1 iload_1;" +
382        "1c 2 iload_2;" +
383        "1d 3 iload_3;" +
384        "1e 1 lload_0;" +
385        "1f 2 lload_1;" +
386        "20 3 lload_2;" +
387        "21 4 lload_3;" +
388        "22 0 fload_0;" +
389        "23 1 fload_1;" +
390        "24 2 fload_2;" +
391        "25 3 fload_3;" +
392        "26 1 dload_0;" +
393        "27 2 dload_1;" +
394        "28 3 dload_2;" +
395        "29 4 dload_3;" +
396        "2a 0 aload_0;" +
397        "2b 1 aload_1;" +
398        "2c 2 aload_2;" +
399        "2d 3 aload_3;" +
400        "2e - iaload;" +
401        "2f - laload;" +
402        "30 - faload;" +
403        "31 - daload;" +
404        "32 - aaload;" +
405        "33 - baload;" +
406        "34 - caload;" +
407        "35 - saload;" +
408        "36 - istore;" +
409        "37 - lstore;" +
410        "38 - fstore;" +
411        "39 - dstore;" +
412        "3a - astore;" +
413        "3b 0 istore_0;" +
414        "3c 1 istore_1;" +
415        "3d 2 istore_2;" +
416        "3e 3 istore_3;" +
417        "3f 1 lstore_0;" +
418        "40 2 lstore_1;" +
419        "41 3 lstore_2;" +
420        "42 4 lstore_3;" +
421        "43 0 fstore_0;" +
422        "44 1 fstore_1;" +
423        "45 2 fstore_2;" +
424        "46 3 fstore_3;" +
425        "47 1 dstore_0;" +
426        "48 2 dstore_1;" +
427        "49 3 dstore_2;" +
428        "4a 4 dstore_3;" +
429        "4b 0 astore_0;" +
430        "4c 1 astore_1;" +
431        "4d 2 astore_2;" +
432        "4e 3 astore_3;" +
433        "4f - iastore;" +
434        "50 - lastore;" +
435        "51 - fastore;" +
436        "52 - dastore;" +
437        "53 - aastore;" +
438        "54 - bastore;" +
439        "55 - castore;" +
440        "56 - sastore;" +
441        "57 - pop;" +
442        "58 - pop2;" +
443        "59 - dup;" +
444        "5a - dup_x1;" +
445        "5b - dup_x2;" +
446        "5c - dup2;" +
447        "5d - dup2_x1;" +
448        "5e - dup2_x2;" +
449        "5f - swap;" +
450        "60 - iadd;" +
451        "61 - ladd;" +
452        "62 - fadd;" +
453        "63 - dadd;" +
454        "64 - isub;" +
455        "65 - lsub;" +
456        "66 - fsub;" +
457        "67 - dsub;" +
458        "68 - imul;" +
459        "69 - lmul;" +
460        "6a - fmul;" +
461        "6b - dmul;" +
462        "6c - idiv;" +
463        "6d - ldiv;" +
464        "6e - fdiv;" +
465        "6f - ddiv;" +
466        "70 - irem;" +
467        "71 - lrem;" +
468        "72 - frem;" +
469        "73 - drem;" +
470        "74 - ineg;" +
471        "75 - lneg;" +
472        "76 - fneg;" +
473        "77 - dneg;" +
474        "78 - ishl;" +
475        "79 - lshl;" +
476        "7a - ishr;" +
477        "7b - lshr;" +
478        "7c - iushr;" +
479        "7d - lushr;" +
480        "7e - iand;" +
481        "7f - land;" +
482        "80 - ior;" +
483        "81 - lor;" +
484        "82 - ixor;" +
485        "83 - lxor;" +
486        "84 l iinc;" +
487        "85 - i2l;" +
488        "86 - i2f;" +
489        "87 - i2d;" +
490        "88 - l2i;" +
491        "89 - l2f;" +
492        "8a - l2d;" +
493        "8b - f2i;" +
494        "8c - f2l;" +
495        "8d - f2d;" +
496        "8e - d2i;" +
497        "8f - d2l;" +
498        "90 - d2f;" +
499        "91 - i2b;" +
500        "92 - i2c;" +
501        "93 - i2s;" +
502        "94 - lcmp;" +
503        "95 - fcmpl;" +
504        "96 - fcmpg;" +
505        "97 - dcmpl;" +
506        "98 - dcmpg;" +
507        "99 b ifeq;" +
508        "9a b ifne;" +
509        "9b b iflt;" +
510        "9c b ifge;" +
511        "9d b ifgt;" +
512        "9e b ifle;" +
513        "9f b if_icmpeq;" +
514        "a0 b if_icmpne;" +
515        "a1 b if_icmplt;" +
516        "a2 b if_icmpge;" +
517        "a3 b if_icmpgt;" +
518        "a4 b if_icmple;" +
519        "a5 b if_acmpeq;" +
520        "a6 b if_acmpne;" +
521        "a7 b goto;" +
522        "a8 b jsr;" +
523        "a9 l ret;" +
524        "aa T tableswitch;" +
525        "ab U lookupswitch;" +
526        "ac - ireturn;" +
527        "ad - lreturn;" +
528        "ae - freturn;" +
529        "af - dreturn;" +
530        "b0 - areturn;" +
531        "b1 - return;" +
532        "b2 p:f getstatic;" +
533        "b3 p:f putstatic;" +
534        "b4 p:f getfield;" +
535        "b5 p:f putfield;" +
536        "b6 p:m invokevirtual;" +
537        "b7 p:m invokespecial;" +
538        "b8 p:m invokestatic;" +
539        "b9 I:i invokeinterface;" +
540        "bb p:c new;" +
541        "bc y newarray;" +
542        "bd p:c anewarray;" +
543        "be - arraylength;" +
544        "bf - athrow;" +
545        "c0 p:c checkcast;" +
546        "c1 p:c instanceof;" +
547        "c2 - monitorenter;" +
548        "c3 - monitorexit;" +
549        "c4 W wide;" +
550        "c5 M:c multianewarray;" +
551        "c6 b ifnull;" +
552        "c7 b ifnonnull;" +
553        "c8 c goto_w;" +
554        "c9 c jsr_w;";
555
556    static {
557        // Set up OPCODE_INFO and OPCODE_NAMES.
558        String s = OPCODE_DETAILS;
559        int len = s.length();
560
561        for (int i = 0; i < len; /*i*/) {
562            int idx = (Character.digit(s.charAt(i), 16) << 4) |
563                Character.digit(s.charAt(i + 1), 16);
564            int info;
565            switch (s.charAt(i + 3)) {
566                case '-': info = FMT_NO_ARGS; break;
567                case '0': info = FMT_NO_ARGS_LOCALS_1; break;
568                case '1': info = FMT_NO_ARGS_LOCALS_2; break;
569                case '2': info = FMT_NO_ARGS_LOCALS_3; break;
570                case '3': info = FMT_NO_ARGS_LOCALS_4; break;
571                case '4': info = FMT_NO_ARGS_LOCALS_5; break;
572                case 'b': info = FMT_BRANCH; break;
573                case 'c': info = FMT_WIDE_BRANCH; break;
574                case 'p': info = FMT_CPI; break;
575                case 'l': info = FMT_LOCAL_1; break;
576                case 'm': info = FMT_LOCAL_2; break;
577                case 'y': info = FMT_LITERAL_BYTE; break;
578                case 'I': info = FMT_INVOKEINTERFACE; break;
579                case 'L': info = FMT_LDC; break;
580                case 'S': info = FMT_SIPUSH; break;
581                case 'T': info = FMT_TABLESWITCH; break;
582                case 'U': info = FMT_LOOKUPSWITCH; break;
583                case 'M': info = FMT_MULTIANEWARRAY; break;
584                case 'W': info = FMT_WIDE; break;
585                default: info = FMT_INVALID; break;
586            }
587
588            i += 5;
589            if (s.charAt(i - 1) == ':') {
590                inner:
591                for (;;) {
592                    switch (s.charAt(i)) {
593                        case 'I': info |= CPOK_Integer; break;
594                        case 'F': info |= CPOK_Float; break;
595                        case 'J': info |= CPOK_Long; break;
596                        case 'D': info |= CPOK_Double; break;
597                        case 'c': info |= CPOK_Class; break;
598                        case 's': info |= CPOK_String; break;
599                        case 'f': info |= CPOK_Fieldref; break;
600                        case 'm': info |= CPOK_Methodref; break;
601                        case 'i': info |= CPOK_InterfaceMethodref; break;
602                        default: break inner;
603                    }
604                    i++;
605                }
606                i++;
607            }
608
609            int endAt = s.indexOf(';', i);
610            OPCODE_INFO[idx] = info;
611            OPCODE_NAMES[idx] = s.substring(i, endAt);
612            i = endAt + 1;
613        }
614    }
615
616    /**
617     * This class is uninstantiable.
618     */
619    private ByteOps() {
620        // This space intentionally left blank.
621    }
622
623    /**
624     * Gets the name of the given opcode.
625     *
626     * @param opcode {@code >= 0, <= 255;} the opcode
627     * @return {@code non-null;} its name
628     */
629    public static String opName(int opcode) {
630        String result = OPCODE_NAMES[opcode];
631
632        if (result == null) {
633            result = "unused_" + Hex.u1(opcode);
634            OPCODE_NAMES[opcode] = result;
635        }
636
637        return result;
638    }
639
640    /**
641     * Gets the format and allowed cp types of the given opcode.
642     *
643     * @param opcode {@code >= 0, <= 255;} the opcode
644     * @return its format and allowed cp types
645     */
646    public static int opInfo(int opcode) {
647        return OPCODE_INFO[opcode];
648    }
649}
650