1/*
2 * Copyright (c) 1999, 2015, 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.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.tools.javac.jvm;
27
28import com.sun.tools.javac.code.*;
29import com.sun.tools.javac.code.Symbol.*;
30import com.sun.tools.javac.code.Types.UniqueType;
31import com.sun.tools.javac.resources.CompilerProperties.Errors;
32import com.sun.tools.javac.tree.JCTree;
33import com.sun.tools.javac.util.*;
34import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
35
36import static com.sun.tools.javac.code.TypeTag.BOT;
37import static com.sun.tools.javac.code.TypeTag.INT;
38import static com.sun.tools.javac.jvm.ByteCodes.*;
39import static com.sun.tools.javac.jvm.UninitializedType.*;
40import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
41
42/** An internal structure that corresponds to the code attribute of
43 *  methods in a classfile. The class also provides some utility operations to
44 *  generate bytecode instructions.
45 *
46 *  <p><b>This is NOT part of any supported API.
47 *  If you write code that depends on this, you do so at your own risk.
48 *  This code and its internal interfaces are subject to change or
49 *  deletion without notice.</b>
50 */
51public class Code {
52
53    public final boolean debugCode;
54    public final boolean needStackMap;
55
56    public enum StackMapFormat {
57        NONE,
58        CLDC {
59            Name getAttributeName(Names names) {
60                return names.StackMap;
61            }
62        },
63        JSR202 {
64            Name getAttributeName(Names names) {
65                return names.StackMapTable;
66            }
67        };
68        Name getAttributeName(Names names) {
69            return names.empty;
70        }
71    }
72
73    final Types types;
74    final Symtab syms;
75
76/*---------- classfile fields: --------------- */
77
78    /** The maximum stack size.
79     */
80    public int max_stack = 0;
81
82    /** The maximum number of local variable slots.
83     */
84    public int max_locals = 0;
85
86    /** The code buffer.
87     */
88    public byte[] code = new byte[64];
89
90    /** the current code pointer.
91     */
92    public int cp = 0;
93
94    /** Check the code against VM spec limits; if
95     *  problems report them and return true.
96     */
97    public boolean checkLimits(DiagnosticPosition pos, Log log) {
98        if (cp > ClassFile.MAX_CODE) {
99            log.error(pos, Errors.LimitCode);
100            return true;
101        }
102        if (max_locals > ClassFile.MAX_LOCALS) {
103            log.error(pos, Errors.LimitLocals);
104            return true;
105        }
106        if (max_stack > ClassFile.MAX_STACK) {
107            log.error(pos, Errors.LimitStack);
108            return true;
109        }
110        return false;
111    }
112
113    /** A buffer for expression catch data. Each enter is a vector
114     *  of four unsigned shorts.
115     */
116    ListBuffer<char[]> catchInfo = new ListBuffer<>();
117
118    /** A buffer for line number information. Each entry is a vector
119     *  of two unsigned shorts.
120     */
121    List<char[]> lineInfo = List.nil(); // handled in stack fashion
122
123    /** The CharacterRangeTable
124     */
125    public CRTable crt;
126
127/*---------- internal fields: --------------- */
128
129    /** Are we generating code with jumps &ge; 32K?
130     */
131    public boolean fatcode;
132
133    /** Code generation enabled?
134     */
135    private boolean alive = true;
136
137    /** The current machine state (registers and stack).
138     */
139    State state;
140
141    /** Is it forbidden to compactify code, because something is
142     *  pointing to current location?
143     */
144    private boolean fixedPc = false;
145
146    /** The next available register.
147     */
148    public int nextreg = 0;
149
150    /** A chain for jumps to be resolved before the next opcode is emitted.
151     *  We do this lazily to avoid jumps to jumps.
152     */
153    Chain pendingJumps = null;
154
155    /** The position of the currently statement, if we are at the
156     *  start of this statement, NOPOS otherwise.
157     *  We need this to emit line numbers lazily, which we need to do
158     *  because of jump-to-jump optimization.
159     */
160    int pendingStatPos = Position.NOPOS;
161
162    /** Set true when a stackMap is needed at the current PC. */
163    boolean pendingStackMap = false;
164
165    /** The stack map format to be generated. */
166    StackMapFormat stackMap;
167
168    /** Switch: emit variable debug info.
169     */
170    boolean varDebugInfo;
171
172    /** Switch: emit line number info.
173     */
174    boolean lineDebugInfo;
175
176    /** Emit line number info if map supplied
177     */
178    Position.LineMap lineMap;
179
180    /** The constant pool of the current class.
181     */
182    final Pool pool;
183
184    final MethodSymbol meth;
185
186    /** Construct a code object, given the settings of the fatcode,
187     *  debugging info switches and the CharacterRangeTable.
188     */
189    public Code(MethodSymbol meth,
190                boolean fatcode,
191                Position.LineMap lineMap,
192                boolean varDebugInfo,
193                StackMapFormat stackMap,
194                boolean debugCode,
195                CRTable crt,
196                Symtab syms,
197                Types types,
198                Pool pool) {
199        this.meth = meth;
200        this.fatcode = fatcode;
201        this.lineMap = lineMap;
202        this.lineDebugInfo = lineMap != null;
203        this.varDebugInfo = varDebugInfo;
204        this.crt = crt;
205        this.syms = syms;
206        this.types = types;
207        this.debugCode = debugCode;
208        this.stackMap = stackMap;
209        switch (stackMap) {
210        case CLDC:
211        case JSR202:
212            this.needStackMap = true;
213            break;
214        default:
215            this.needStackMap = false;
216        }
217        state = new State();
218        lvar = new LocalVar[20];
219        this.pool = pool;
220    }
221
222
223/* **************************************************************************
224 * Typecodes & related stuff
225 ****************************************************************************/
226
227    /** Given a type, return its type code (used implicitly in the
228     *  JVM architecture).
229     */
230    public static int typecode(Type type) {
231        switch (type.getTag()) {
232        case BYTE: return BYTEcode;
233        case SHORT: return SHORTcode;
234        case CHAR: return CHARcode;
235        case INT: return INTcode;
236        case LONG: return LONGcode;
237        case FLOAT: return FLOATcode;
238        case DOUBLE: return DOUBLEcode;
239        case BOOLEAN: return BYTEcode;
240        case VOID: return VOIDcode;
241        case CLASS:
242        case ARRAY:
243        case METHOD:
244        case BOT:
245        case TYPEVAR:
246        case UNINITIALIZED_THIS:
247        case UNINITIALIZED_OBJECT:
248            return OBJECTcode;
249        default: throw new AssertionError("typecode " + type.getTag());
250        }
251    }
252
253    /** Collapse type code for subtypes of int to INTcode.
254     */
255    public static int truncate(int tc) {
256        switch (tc) {
257        case BYTEcode: case SHORTcode: case CHARcode: return INTcode;
258        default: return tc;
259        }
260    }
261
262    /** The width in bytes of objects of the type.
263     */
264    public static int width(int typecode) {
265        switch (typecode) {
266        case LONGcode: case DOUBLEcode: return 2;
267        case VOIDcode: return 0;
268        default: return 1;
269        }
270    }
271
272    public static int width(Type type) {
273        return type == null ? 1 : width(typecode(type));
274    }
275
276    /** The total width taken up by a vector of objects.
277     */
278    public static int width(List<Type> types) {
279        int w = 0;
280        for (List<Type> l = types; l.nonEmpty(); l = l.tail)
281            w = w + width(l.head);
282        return w;
283    }
284
285    /** Given a type, return its code for allocating arrays of that type.
286     */
287    public static int arraycode(Type type) {
288        switch (type.getTag()) {
289        case BYTE: return 8;
290        case BOOLEAN: return 4;
291        case SHORT: return 9;
292        case CHAR: return 5;
293        case INT: return 10;
294        case LONG: return 11;
295        case FLOAT: return 6;
296        case DOUBLE: return 7;
297        case CLASS: return 0;
298        case ARRAY: return 1;
299        default: throw new AssertionError("arraycode " + type);
300        }
301    }
302
303
304/* **************************************************************************
305 * Emit code
306 ****************************************************************************/
307
308    /** The current output code pointer.
309     */
310    public int curCP() {
311        /*
312         * This method has side-effects because calling it can indirectly provoke
313         *  extra code generation, like goto instructions, depending on the context
314         *  where it's called.
315         *  Use with care or even better avoid using it.
316         */
317        if (pendingJumps != null) {
318            resolvePending();
319        }
320        if (pendingStatPos != Position.NOPOS) {
321            markStatBegin();
322        }
323        fixedPc = true;
324        return cp;
325    }
326
327    /** Emit a byte of code.
328     */
329    private  void emit1(int od) {
330        if (!alive) return;
331        code = ArrayUtils.ensureCapacity(code, cp);
332        code[cp++] = (byte)od;
333    }
334
335    /** Emit two bytes of code.
336     */
337    private void emit2(int od) {
338        if (!alive) return;
339        if (cp + 2 > code.length) {
340            emit1(od >> 8);
341            emit1(od);
342        } else {
343            code[cp++] = (byte)(od >> 8);
344            code[cp++] = (byte)od;
345        }
346    }
347
348    /** Emit four bytes of code.
349     */
350    public void emit4(int od) {
351        if (!alive) return;
352        if (cp + 4 > code.length) {
353            emit1(od >> 24);
354            emit1(od >> 16);
355            emit1(od >> 8);
356            emit1(od);
357        } else {
358            code[cp++] = (byte)(od >> 24);
359            code[cp++] = (byte)(od >> 16);
360            code[cp++] = (byte)(od >> 8);
361            code[cp++] = (byte)od;
362        }
363    }
364
365    /** Emit an opcode.
366     */
367    private void emitop(int op) {
368        if (pendingJumps != null) resolvePending();
369        if (alive) {
370            if (pendingStatPos != Position.NOPOS)
371                markStatBegin();
372            if (pendingStackMap) {
373                pendingStackMap = false;
374                emitStackMap();
375            }
376            if (debugCode)
377                System.err.println("emit@" + cp + " stack=" +
378                                   state.stacksize + ": " +
379                                   mnem(op));
380            emit1(op);
381        }
382    }
383
384    void postop() {
385        Assert.check(alive || state.stacksize == 0);
386    }
387
388    /** Emit a ldc (or ldc_w) instruction, taking into account operand size
389    */
390    public void emitLdc(int od) {
391        if (od <= 255) {
392            emitop1(ldc1, od);
393        }
394        else {
395            emitop2(ldc2, od);
396        }
397    }
398
399    /** Emit a multinewarray instruction.
400     */
401    public void emitMultianewarray(int ndims, int type, Type arrayType) {
402        emitop(multianewarray);
403        if (!alive) return;
404        emit2(type);
405        emit1(ndims);
406        state.pop(ndims);
407        state.push(arrayType);
408    }
409
410    /** Emit newarray.
411     */
412    public void emitNewarray(int elemcode, Type arrayType) {
413        emitop(newarray);
414        if (!alive) return;
415        emit1(elemcode);
416        state.pop(1); // count
417        state.push(arrayType);
418    }
419
420    /** Emit anewarray.
421     */
422    public void emitAnewarray(int od, Type arrayType) {
423        emitop(anewarray);
424        if (!alive) return;
425        emit2(od);
426        state.pop(1);
427        state.push(arrayType);
428    }
429
430    /** Emit an invokeinterface instruction.
431     */
432    public void emitInvokeinterface(int meth, Type mtype) {
433        int argsize = width(mtype.getParameterTypes());
434        emitop(invokeinterface);
435        if (!alive) return;
436        emit2(meth);
437        emit1(argsize + 1);
438        emit1(0);
439        state.pop(argsize + 1);
440        state.push(mtype.getReturnType());
441    }
442
443    /** Emit an invokespecial instruction.
444     */
445    public void emitInvokespecial(int meth, Type mtype) {
446        int argsize = width(mtype.getParameterTypes());
447        emitop(invokespecial);
448        if (!alive) return;
449        emit2(meth);
450        Symbol sym = (Symbol)pool.pool[meth];
451        state.pop(argsize);
452        if (sym.isConstructor())
453            state.markInitialized((UninitializedType)state.peek());
454        state.pop(1);
455        state.push(mtype.getReturnType());
456    }
457
458    /** Emit an invokestatic instruction.
459     */
460    public void emitInvokestatic(int meth, Type mtype) {
461        int argsize = width(mtype.getParameterTypes());
462        emitop(invokestatic);
463        if (!alive) return;
464        emit2(meth);
465        state.pop(argsize);
466        state.push(mtype.getReturnType());
467    }
468
469    /** Emit an invokevirtual instruction.
470     */
471    public void emitInvokevirtual(int meth, Type mtype) {
472        int argsize = width(mtype.getParameterTypes());
473        emitop(invokevirtual);
474        if (!alive) return;
475        emit2(meth);
476        state.pop(argsize + 1);
477        state.push(mtype.getReturnType());
478    }
479
480    /** Emit an invokedynamic instruction.
481     */
482    public void emitInvokedynamic(int desc, Type mtype) {
483        int argsize = width(mtype.getParameterTypes());
484        emitop(invokedynamic);
485        if (!alive) return;
486        emit2(desc);
487        emit2(0);
488        state.pop(argsize);
489        state.push(mtype.getReturnType());
490    }
491
492    /** Emit an opcode with no operand field.
493     */
494    public void emitop0(int op) {
495        emitop(op);
496        if (!alive) return;
497        switch (op) {
498        case aaload: {
499            state.pop(1);// index
500            Type a = state.stack[state.stacksize-1];
501            Assert.check(!a.hasTag(BOT)); // null type as is cannot be indexed.
502            state.pop(1);
503            state.push(types.erasure(types.elemtype(a))); }
504            break;
505        case goto_:
506            markDead();
507            break;
508        case nop:
509        case ineg:
510        case lneg:
511        case fneg:
512        case dneg:
513            break;
514        case aconst_null:
515            state.push(syms.botType);
516            break;
517        case iconst_m1:
518        case iconst_0:
519        case iconst_1:
520        case iconst_2:
521        case iconst_3:
522        case iconst_4:
523        case iconst_5:
524        case iload_0:
525        case iload_1:
526        case iload_2:
527        case iload_3:
528            state.push(syms.intType);
529            break;
530        case lconst_0:
531        case lconst_1:
532        case lload_0:
533        case lload_1:
534        case lload_2:
535        case lload_3:
536            state.push(syms.longType);
537            break;
538        case fconst_0:
539        case fconst_1:
540        case fconst_2:
541        case fload_0:
542        case fload_1:
543        case fload_2:
544        case fload_3:
545            state.push(syms.floatType);
546            break;
547        case dconst_0:
548        case dconst_1:
549        case dload_0:
550        case dload_1:
551        case dload_2:
552        case dload_3:
553            state.push(syms.doubleType);
554            break;
555        case aload_0:
556            state.push(lvar[0].sym.type);
557            break;
558        case aload_1:
559            state.push(lvar[1].sym.type);
560            break;
561        case aload_2:
562            state.push(lvar[2].sym.type);
563            break;
564        case aload_3:
565            state.push(lvar[3].sym.type);
566            break;
567        case iaload:
568        case baload:
569        case caload:
570        case saload:
571            state.pop(2);
572            state.push(syms.intType);
573            break;
574        case laload:
575            state.pop(2);
576            state.push(syms.longType);
577            break;
578        case faload:
579            state.pop(2);
580            state.push(syms.floatType);
581            break;
582        case daload:
583            state.pop(2);
584            state.push(syms.doubleType);
585            break;
586        case istore_0:
587        case istore_1:
588        case istore_2:
589        case istore_3:
590        case fstore_0:
591        case fstore_1:
592        case fstore_2:
593        case fstore_3:
594        case astore_0:
595        case astore_1:
596        case astore_2:
597        case astore_3:
598        case pop:
599        case lshr:
600        case lshl:
601        case lushr:
602            state.pop(1);
603            break;
604        case areturn:
605        case ireturn:
606        case freturn:
607            Assert.check(state.nlocks == 0);
608            state.pop(1);
609            markDead();
610            break;
611        case athrow:
612            state.pop(1);
613            markDead();
614            break;
615        case lstore_0:
616        case lstore_1:
617        case lstore_2:
618        case lstore_3:
619        case dstore_0:
620        case dstore_1:
621        case dstore_2:
622        case dstore_3:
623        case pop2:
624            state.pop(2);
625            break;
626        case lreturn:
627        case dreturn:
628            Assert.check(state.nlocks == 0);
629            state.pop(2);
630            markDead();
631            break;
632        case dup:
633            state.push(state.stack[state.stacksize-1]);
634            break;
635        case return_:
636            Assert.check(state.nlocks == 0);
637            markDead();
638            break;
639        case arraylength:
640            state.pop(1);
641            state.push(syms.intType);
642            break;
643        case isub:
644        case iadd:
645        case imul:
646        case idiv:
647        case imod:
648        case ishl:
649        case ishr:
650        case iushr:
651        case iand:
652        case ior:
653        case ixor:
654            state.pop(1);
655            // state.pop(1);
656            // state.push(syms.intType);
657            break;
658        case aastore:
659            state.pop(3);
660            break;
661        case land:
662        case lor:
663        case lxor:
664        case lmod:
665        case ldiv:
666        case lmul:
667        case lsub:
668        case ladd:
669            state.pop(2);
670            break;
671        case lcmp:
672            state.pop(4);
673            state.push(syms.intType);
674            break;
675        case l2i:
676            state.pop(2);
677            state.push(syms.intType);
678            break;
679        case i2l:
680            state.pop(1);
681            state.push(syms.longType);
682            break;
683        case i2f:
684            state.pop(1);
685            state.push(syms.floatType);
686            break;
687        case i2d:
688            state.pop(1);
689            state.push(syms.doubleType);
690            break;
691        case l2f:
692            state.pop(2);
693            state.push(syms.floatType);
694            break;
695        case l2d:
696            state.pop(2);
697            state.push(syms.doubleType);
698            break;
699        case f2i:
700            state.pop(1);
701            state.push(syms.intType);
702            break;
703        case f2l:
704            state.pop(1);
705            state.push(syms.longType);
706            break;
707        case f2d:
708            state.pop(1);
709            state.push(syms.doubleType);
710            break;
711        case d2i:
712            state.pop(2);
713            state.push(syms.intType);
714            break;
715        case d2l:
716            state.pop(2);
717            state.push(syms.longType);
718            break;
719        case d2f:
720            state.pop(2);
721            state.push(syms.floatType);
722            break;
723        case tableswitch:
724        case lookupswitch:
725            state.pop(1);
726            // the caller is responsible for patching up the state
727            break;
728        case dup_x1: {
729            Type val1 = state.pop1();
730            Type val2 = state.pop1();
731            state.push(val1);
732            state.push(val2);
733            state.push(val1);
734            break;
735        }
736        case bastore:
737            state.pop(3);
738            break;
739        case int2byte:
740        case int2char:
741        case int2short:
742            break;
743        case fmul:
744        case fadd:
745        case fsub:
746        case fdiv:
747        case fmod:
748            state.pop(1);
749            break;
750        case castore:
751        case iastore:
752        case fastore:
753        case sastore:
754            state.pop(3);
755            break;
756        case lastore:
757        case dastore:
758            state.pop(4);
759            break;
760        case dup2:
761            if (state.stack[state.stacksize-1] != null) {
762                Type value1 = state.pop1();
763                Type value2 = state.pop1();
764                state.push(value2);
765                state.push(value1);
766                state.push(value2);
767                state.push(value1);
768            } else {
769                Type value = state.pop2();
770                state.push(value);
771                state.push(value);
772            }
773            break;
774        case dup2_x1:
775            if (state.stack[state.stacksize-1] != null) {
776                Type value1 = state.pop1();
777                Type value2 = state.pop1();
778                Type value3 = state.pop1();
779                state.push(value2);
780                state.push(value1);
781                state.push(value3);
782                state.push(value2);
783                state.push(value1);
784            } else {
785                Type value1 = state.pop2();
786                Type value2 = state.pop1();
787                state.push(value1);
788                state.push(value2);
789                state.push(value1);
790            }
791            break;
792        case dup2_x2:
793            if (state.stack[state.stacksize-1] != null) {
794                Type value1 = state.pop1();
795                Type value2 = state.pop1();
796                if (state.stack[state.stacksize-1] != null) {
797                    // form 1
798                    Type value3 = state.pop1();
799                    Type value4 = state.pop1();
800                    state.push(value2);
801                    state.push(value1);
802                    state.push(value4);
803                    state.push(value3);
804                    state.push(value2);
805                    state.push(value1);
806                } else {
807                    // form 3
808                    Type value3 = state.pop2();
809                    state.push(value2);
810                    state.push(value1);
811                    state.push(value3);
812                    state.push(value2);
813                    state.push(value1);
814                }
815            } else {
816                Type value1 = state.pop2();
817                if (state.stack[state.stacksize-1] != null) {
818                    // form 2
819                    Type value2 = state.pop1();
820                    Type value3 = state.pop1();
821                    state.push(value1);
822                    state.push(value3);
823                    state.push(value2);
824                    state.push(value1);
825                } else {
826                    // form 4
827                    Type value2 = state.pop2();
828                    state.push(value1);
829                    state.push(value2);
830                    state.push(value1);
831                }
832            }
833            break;
834        case dup_x2: {
835            Type value1 = state.pop1();
836            if (state.stack[state.stacksize-1] != null) {
837                // form 1
838                Type value2 = state.pop1();
839                Type value3 = state.pop1();
840                state.push(value1);
841                state.push(value3);
842                state.push(value2);
843                state.push(value1);
844            } else {
845                // form 2
846                Type value2 = state.pop2();
847                state.push(value1);
848                state.push(value2);
849                state.push(value1);
850            }
851        }
852            break;
853        case fcmpl:
854        case fcmpg:
855            state.pop(2);
856            state.push(syms.intType);
857            break;
858        case dcmpl:
859        case dcmpg:
860            state.pop(4);
861            state.push(syms.intType);
862            break;
863        case swap: {
864            Type value1 = state.pop1();
865            Type value2 = state.pop1();
866            state.push(value1);
867            state.push(value2);
868            break;
869        }
870        case dadd:
871        case dsub:
872        case dmul:
873        case ddiv:
874        case dmod:
875            state.pop(2);
876            break;
877        case ret:
878            markDead();
879            break;
880        case wide:
881            // must be handled by the caller.
882            return;
883        case monitorenter:
884        case monitorexit:
885            state.pop(1);
886            break;
887
888        default:
889            throw new AssertionError(mnem(op));
890        }
891        postop();
892    }
893
894    /** Emit an opcode with a one-byte operand field.
895     */
896    public void emitop1(int op, int od) {
897        emitop(op);
898        if (!alive) return;
899        emit1(od);
900        switch (op) {
901        case bipush:
902            state.push(syms.intType);
903            break;
904        case ldc1:
905            state.push(typeForPool(pool.pool[od]));
906            break;
907        default:
908            throw new AssertionError(mnem(op));
909        }
910        postop();
911    }
912
913    /** The type of a constant pool entry. */
914    private Type typeForPool(Object o) {
915        if (o instanceof Integer) return syms.intType;
916        if (o instanceof Float) return syms.floatType;
917        if (o instanceof String) return syms.stringType;
918        if (o instanceof Long) return syms.longType;
919        if (o instanceof Double) return syms.doubleType;
920        if (o instanceof ClassSymbol) return syms.classType;
921        if (o instanceof Pool.MethodHandle) return syms.methodHandleType;
922        if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type);
923        if (o instanceof Type) {
924            Type ty = (Type) o;
925
926            if (ty instanceof Type.ArrayType) return syms.classType;
927            if (ty instanceof Type.MethodType) return syms.methodTypeType;
928        }
929        throw new AssertionError("Invalid type of constant pool entry: " + o.getClass());
930    }
931
932    /** Emit an opcode with a one-byte operand field;
933     *  widen if field does not fit in a byte.
934     */
935    public void emitop1w(int op, int od) {
936        if (od > 0xFF) {
937            emitop(wide);
938            emitop(op);
939            emit2(od);
940        } else {
941            emitop(op);
942            emit1(od);
943        }
944        if (!alive) return;
945        switch (op) {
946        case iload:
947            state.push(syms.intType);
948            break;
949        case lload:
950            state.push(syms.longType);
951            break;
952        case fload:
953            state.push(syms.floatType);
954            break;
955        case dload:
956            state.push(syms.doubleType);
957            break;
958        case aload:
959            state.push(lvar[od].sym.type);
960            break;
961        case lstore:
962        case dstore:
963            state.pop(2);
964            break;
965        case istore:
966        case fstore:
967        case astore:
968            state.pop(1);
969            break;
970        case ret:
971            markDead();
972            break;
973        default:
974            throw new AssertionError(mnem(op));
975        }
976        postop();
977    }
978
979    /** Emit an opcode with two one-byte operand fields;
980     *  widen if either field does not fit in a byte.
981     */
982    public void emitop1w(int op, int od1, int od2) {
983        if (od1 > 0xFF || od2 < -128 || od2 > 127) {
984            emitop(wide);
985            emitop(op);
986            emit2(od1);
987            emit2(od2);
988        } else {
989            emitop(op);
990            emit1(od1);
991            emit1(od2);
992        }
993        if (!alive) return;
994        switch (op) {
995        case iinc:
996            break;
997        default:
998            throw new AssertionError(mnem(op));
999        }
1000    }
1001
1002    /** Emit an opcode with a two-byte operand field.
1003     */
1004    public void emitop2(int op, int od) {
1005        emitop(op);
1006        if (!alive) return;
1007        emit2(od);
1008        switch (op) {
1009        case getstatic:
1010            state.push(((Symbol)(pool.pool[od])).erasure(types));
1011            break;
1012        case putstatic:
1013            state.pop(((Symbol)(pool.pool[od])).erasure(types));
1014            break;
1015        case new_:
1016            Symbol sym;
1017            if (pool.pool[od] instanceof UniqueType) {
1018                // Required by change in Gen.makeRef to allow
1019                // annotated types.
1020                // TODO: is this needed anywhere else?
1021                sym = ((UniqueType)(pool.pool[od])).type.tsym;
1022            } else {
1023                sym = (Symbol)(pool.pool[od]);
1024            }
1025            state.push(uninitializedObject(sym.erasure(types), cp-3));
1026            break;
1027        case sipush:
1028            state.push(syms.intType);
1029            break;
1030        case if_acmp_null:
1031        case if_acmp_nonnull:
1032        case ifeq:
1033        case ifne:
1034        case iflt:
1035        case ifge:
1036        case ifgt:
1037        case ifle:
1038            state.pop(1);
1039            break;
1040        case if_icmpeq:
1041        case if_icmpne:
1042        case if_icmplt:
1043        case if_icmpge:
1044        case if_icmpgt:
1045        case if_icmple:
1046        case if_acmpeq:
1047        case if_acmpne:
1048            state.pop(2);
1049            break;
1050        case goto_:
1051            markDead();
1052            break;
1053        case putfield:
1054            state.pop(((Symbol)(pool.pool[od])).erasure(types));
1055            state.pop(1); // object ref
1056            break;
1057        case getfield:
1058            state.pop(1); // object ref
1059            state.push(((Symbol)(pool.pool[od])).erasure(types));
1060            break;
1061        case checkcast: {
1062            state.pop(1); // object ref
1063            Object o = pool.pool[od];
1064            Type t = (o instanceof Symbol)
1065                ? ((Symbol)o).erasure(types)
1066                : types.erasure((((UniqueType)o).type));
1067            state.push(t);
1068            break; }
1069        case ldc2w:
1070            state.push(typeForPool(pool.pool[od]));
1071            break;
1072        case instanceof_:
1073            state.pop(1);
1074            state.push(syms.intType);
1075            break;
1076        case ldc2:
1077            state.push(typeForPool(pool.pool[od]));
1078            break;
1079        case jsr:
1080            break;
1081        default:
1082            throw new AssertionError(mnem(op));
1083        }
1084        // postop();
1085    }
1086
1087    /** Emit an opcode with a four-byte operand field.
1088     */
1089    public void emitop4(int op, int od) {
1090        emitop(op);
1091        if (!alive) return;
1092        emit4(od);
1093        switch (op) {
1094        case goto_w:
1095            markDead();
1096            break;
1097        case jsr_w:
1098            break;
1099        default:
1100            throw new AssertionError(mnem(op));
1101        }
1102        // postop();
1103    }
1104
1105    /** Align code pointer to next `incr' boundary.
1106     */
1107    public void align(int incr) {
1108        if (alive)
1109            while (cp % incr != 0) emitop0(nop);
1110    }
1111
1112    /** Place a byte into code at address pc.
1113     *  Pre: {@literal pc + 1 <= cp }.
1114     */
1115    private void put1(int pc, int op) {
1116        code[pc] = (byte)op;
1117    }
1118
1119    /** Place two bytes into code at address pc.
1120     *  Pre: {@literal pc + 2 <= cp }.
1121     */
1122    private void put2(int pc, int od) {
1123        // pre: pc + 2 <= cp
1124        put1(pc, od >> 8);
1125        put1(pc+1, od);
1126    }
1127
1128    /** Place four  bytes into code at address pc.
1129     *  Pre: {@literal pc + 4 <= cp }.
1130     */
1131    public void put4(int pc, int od) {
1132        // pre: pc + 4 <= cp
1133        put1(pc  , od >> 24);
1134        put1(pc+1, od >> 16);
1135        put1(pc+2, od >> 8);
1136        put1(pc+3, od);
1137    }
1138
1139    /** Return code byte at position pc as an unsigned int.
1140     */
1141    private int get1(int pc) {
1142        return code[pc] & 0xFF;
1143    }
1144
1145    /** Return two code bytes at position pc as an unsigned int.
1146     */
1147    private int get2(int pc) {
1148        return (get1(pc) << 8) | get1(pc+1);
1149    }
1150
1151    /** Return four code bytes at position pc as an int.
1152     */
1153    public int get4(int pc) {
1154        // pre: pc + 4 <= cp
1155        return
1156            (get1(pc) << 24) |
1157            (get1(pc+1) << 16) |
1158            (get1(pc+2) << 8) |
1159            (get1(pc+3));
1160    }
1161
1162    /** Is code generation currently enabled?
1163     */
1164    public boolean isAlive() {
1165        return alive || pendingJumps != null;
1166    }
1167
1168    /** Switch code generation on/off.
1169     */
1170    public void markDead() {
1171        alive = false;
1172    }
1173
1174    /** Declare an entry point; return current code pointer
1175     */
1176    public int entryPoint() {
1177        int pc = curCP();
1178        alive = true;
1179        pendingStackMap = needStackMap;
1180        return pc;
1181    }
1182
1183    /** Declare an entry point with initial state;
1184     *  return current code pointer
1185     */
1186    public int entryPoint(State state) {
1187        int pc = curCP();
1188        alive = true;
1189        State newState = state.dup();
1190        setDefined(newState.defined);
1191        this.state = newState;
1192        Assert.check(state.stacksize <= max_stack);
1193        if (debugCode) System.err.println("entry point " + state);
1194        pendingStackMap = needStackMap;
1195        return pc;
1196    }
1197
1198    /** Declare an entry point with initial state plus a pushed value;
1199     *  return current code pointer
1200     */
1201    public int entryPoint(State state, Type pushed) {
1202        int pc = curCP();
1203        alive = true;
1204        State newState = state.dup();
1205        setDefined(newState.defined);
1206        this.state = newState;
1207        Assert.check(state.stacksize <= max_stack);
1208        this.state.push(pushed);
1209        if (debugCode) System.err.println("entry point " + state);
1210        pendingStackMap = needStackMap;
1211        return pc;
1212    }
1213
1214
1215/**************************************************************************
1216 * Stack map generation
1217 *************************************************************************/
1218
1219    /** An entry in the stack map. */
1220    static class StackMapFrame {
1221        int pc;
1222        Type[] locals;
1223        Type[] stack;
1224    }
1225
1226    /** A buffer of cldc stack map entries. */
1227    StackMapFrame[] stackMapBuffer = null;
1228
1229    /** A buffer of compressed StackMapTable entries. */
1230    StackMapTableFrame[] stackMapTableBuffer = null;
1231    int stackMapBufferSize = 0;
1232
1233    /** The last PC at which we generated a stack map. */
1234    int lastStackMapPC = -1;
1235
1236    /** The last stack map frame in StackMapTable. */
1237    StackMapFrame lastFrame = null;
1238
1239    /** The stack map frame before the last one. */
1240    StackMapFrame frameBeforeLast = null;
1241
1242    /** Emit a stack map entry.  */
1243    public void emitStackMap() {
1244        int pc = curCP();
1245        if (!needStackMap) return;
1246
1247
1248
1249        switch (stackMap) {
1250            case CLDC:
1251                emitCLDCStackMap(pc, getLocalsSize());
1252                break;
1253            case JSR202:
1254                emitStackMapFrame(pc, getLocalsSize());
1255                break;
1256            default:
1257                throw new AssertionError("Should have chosen a stackmap format");
1258        }
1259        // DEBUG code follows
1260        if (debugCode) state.dump(pc);
1261    }
1262
1263    private int getLocalsSize() {
1264        int nextLocal = 0;
1265        for (int i=max_locals-1; i>=0; i--) {
1266            if (state.defined.isMember(i) && lvar[i] != null) {
1267                nextLocal = i + width(lvar[i].sym.erasure(types));
1268                break;
1269            }
1270        }
1271        return nextLocal;
1272    }
1273
1274    /** Emit a CLDC stack map frame. */
1275    void emitCLDCStackMap(int pc, int localsSize) {
1276        if (lastStackMapPC == pc) {
1277            // drop existing stackmap at this offset
1278            stackMapBuffer[--stackMapBufferSize] = null;
1279        }
1280        lastStackMapPC = pc;
1281
1282        if (stackMapBuffer == null) {
1283            stackMapBuffer = new StackMapFrame[20];
1284        } else {
1285            stackMapBuffer = ArrayUtils.ensureCapacity(stackMapBuffer, stackMapBufferSize);
1286        }
1287        StackMapFrame frame =
1288            stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
1289        frame.pc = pc;
1290
1291        frame.locals = new Type[localsSize];
1292        for (int i=0; i<localsSize; i++) {
1293            if (state.defined.isMember(i) && lvar[i] != null) {
1294                Type vtype = lvar[i].sym.type;
1295                if (!(vtype instanceof UninitializedType))
1296                    vtype = types.erasure(vtype);
1297                frame.locals[i] = vtype;
1298            }
1299        }
1300        frame.stack = new Type[state.stacksize];
1301        for (int i=0; i<state.stacksize; i++)
1302            frame.stack[i] = state.stack[i];
1303    }
1304
1305    void emitStackMapFrame(int pc, int localsSize) {
1306        if (lastFrame == null) {
1307            // first frame
1308            lastFrame = getInitialFrame();
1309        } else if (lastFrame.pc == pc) {
1310            // drop existing stackmap at this offset
1311            stackMapTableBuffer[--stackMapBufferSize] = null;
1312            lastFrame = frameBeforeLast;
1313            frameBeforeLast = null;
1314        }
1315
1316        StackMapFrame frame = new StackMapFrame();
1317        frame.pc = pc;
1318
1319        int localCount = 0;
1320        Type[] locals = new Type[localsSize];
1321        for (int i=0; i<localsSize; i++, localCount++) {
1322            if (state.defined.isMember(i) && lvar[i] != null) {
1323                Type vtype = lvar[i].sym.type;
1324                if (!(vtype instanceof UninitializedType))
1325                    vtype = types.erasure(vtype);
1326                locals[i] = vtype;
1327                if (width(vtype) > 1) i++;
1328            }
1329        }
1330        frame.locals = new Type[localCount];
1331        for (int i=0, j=0; i<localsSize; i++, j++) {
1332            Assert.check(j < localCount);
1333            frame.locals[j] = locals[i];
1334            if (width(locals[i]) > 1) i++;
1335        }
1336
1337        int stackCount = 0;
1338        for (int i=0; i<state.stacksize; i++) {
1339            if (state.stack[i] != null) {
1340                stackCount++;
1341            }
1342        }
1343        frame.stack = new Type[stackCount];
1344        stackCount = 0;
1345        for (int i=0; i<state.stacksize; i++) {
1346            if (state.stack[i] != null) {
1347                frame.stack[stackCount++] = types.erasure(state.stack[i]);
1348            }
1349        }
1350
1351        if (stackMapTableBuffer == null) {
1352            stackMapTableBuffer = new StackMapTableFrame[20];
1353        } else {
1354            stackMapTableBuffer = ArrayUtils.ensureCapacity(
1355                                    stackMapTableBuffer,
1356                                    stackMapBufferSize);
1357        }
1358        stackMapTableBuffer[stackMapBufferSize++] =
1359                StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
1360
1361        frameBeforeLast = lastFrame;
1362        lastFrame = frame;
1363    }
1364
1365    StackMapFrame getInitialFrame() {
1366        StackMapFrame frame = new StackMapFrame();
1367        List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
1368        int len = arg_types.length();
1369        int count = 0;
1370        if (!meth.isStatic()) {
1371            Type thisType = meth.owner.type;
1372            frame.locals = new Type[len+1];
1373            if (meth.isConstructor() && thisType != syms.objectType) {
1374                frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
1375            } else {
1376                frame.locals[count++] = types.erasure(thisType);
1377            }
1378        } else {
1379            frame.locals = new Type[len];
1380        }
1381        for (Type arg_type : arg_types) {
1382            frame.locals[count++] = types.erasure(arg_type);
1383        }
1384        frame.pc = -1;
1385        frame.stack = null;
1386        return frame;
1387    }
1388
1389
1390/**************************************************************************
1391 * Operations having to do with jumps
1392 *************************************************************************/
1393
1394    /** A chain represents a list of unresolved jumps. Jump locations
1395     *  are sorted in decreasing order.
1396     */
1397    public static class Chain {
1398
1399        /** The position of the jump instruction.
1400         */
1401        public final int pc;
1402
1403        /** The machine state after the jump instruction.
1404         *  Invariant: all elements of a chain list have the same stacksize
1405         *  and compatible stack and register contents.
1406         */
1407        Code.State state;
1408
1409        /** The next jump in the list.
1410         */
1411        public final Chain next;
1412
1413        /** Construct a chain from its jump position, stacksize, previous
1414         *  chain, and machine state.
1415         */
1416        public Chain(int pc, Chain next, Code.State state) {
1417            this.pc = pc;
1418            this.next = next;
1419            this.state = state;
1420        }
1421    }
1422
1423    /** Negate a branch opcode.
1424     */
1425    public static int negate(int opcode) {
1426        if (opcode == if_acmp_null) return if_acmp_nonnull;
1427        else if (opcode == if_acmp_nonnull) return if_acmp_null;
1428        else return ((opcode + 1) ^ 1) - 1;
1429    }
1430
1431    /** Emit a jump instruction.
1432     *  Return code pointer of instruction to be patched.
1433     */
1434    public int emitJump(int opcode) {
1435        if (fatcode) {
1436            if (opcode == goto_ || opcode == jsr) {
1437                emitop4(opcode + goto_w - goto_, 0);
1438            } else {
1439                emitop2(negate(opcode), 8);
1440                emitop4(goto_w, 0);
1441                alive = true;
1442                pendingStackMap = needStackMap;
1443            }
1444            return cp - 5;
1445        } else {
1446            emitop2(opcode, 0);
1447            return cp - 3;
1448        }
1449    }
1450
1451    /** Emit a branch with given opcode; return its chain.
1452     *  branch differs from jump in that jsr is treated as no-op.
1453     */
1454    public Chain branch(int opcode) {
1455        Chain result = null;
1456        if (opcode == goto_) {
1457            result = pendingJumps;
1458            pendingJumps = null;
1459        }
1460        if (opcode != dontgoto && isAlive()) {
1461            result = new Chain(emitJump(opcode),
1462                               result,
1463                               state.dup());
1464            fixedPc = fatcode;
1465            if (opcode == goto_) alive = false;
1466        }
1467        return result;
1468    }
1469
1470    /** Resolve chain to point to given target.
1471     */
1472    public void resolve(Chain chain, int target) {
1473        boolean changed = false;
1474        State newState = state;
1475        for (; chain != null; chain = chain.next) {
1476            Assert.check(state != chain.state
1477                    && (target > chain.pc || state.stacksize == 0));
1478            if (target >= cp) {
1479                target = cp;
1480            } else if (get1(target) == goto_) {
1481                if (fatcode) target = target + get4(target + 1);
1482                else target = target + get2(target + 1);
1483            }
1484            if (get1(chain.pc) == goto_ &&
1485                chain.pc + 3 == target && target == cp && !fixedPc) {
1486                // If goto the next instruction, the jump is not needed:
1487                // compact the code.
1488                if (varDebugInfo) {
1489                    adjustAliveRanges(cp, -3);
1490                }
1491                cp = cp - 3;
1492                target = target - 3;
1493                if (chain.next == null) {
1494                    // This is the only jump to the target. Exit the loop
1495                    // without setting new state. The code is reachable
1496                    // from the instruction before goto_.
1497                    alive = true;
1498                    break;
1499                }
1500            } else {
1501                if (fatcode)
1502                    put4(chain.pc + 1, target - chain.pc);
1503                else if (target - chain.pc < Short.MIN_VALUE ||
1504                         target - chain.pc > Short.MAX_VALUE)
1505                    fatcode = true;
1506                else
1507                    put2(chain.pc + 1, target - chain.pc);
1508                Assert.check(!alive ||
1509                    chain.state.stacksize == newState.stacksize &&
1510                    chain.state.nlocks == newState.nlocks);
1511            }
1512            fixedPc = true;
1513            if (cp == target) {
1514                changed = true;
1515                if (debugCode)
1516                    System.err.println("resolving chain state=" + chain.state);
1517                if (alive) {
1518                    newState = chain.state.join(newState);
1519                } else {
1520                    newState = chain.state;
1521                    alive = true;
1522                }
1523            }
1524        }
1525        Assert.check(!changed || state != newState);
1526        if (state != newState) {
1527            setDefined(newState.defined);
1528            state = newState;
1529            pendingStackMap = needStackMap;
1530        }
1531    }
1532
1533    /** Resolve chain to point to current code pointer.
1534     */
1535    public void resolve(Chain chain) {
1536        Assert.check(
1537            !alive ||
1538            chain==null ||
1539            state.stacksize == chain.state.stacksize &&
1540            state.nlocks == chain.state.nlocks);
1541        pendingJumps = mergeChains(chain, pendingJumps);
1542    }
1543
1544    /** Resolve any pending jumps.
1545     */
1546    public void resolvePending() {
1547        Chain x = pendingJumps;
1548        pendingJumps = null;
1549        resolve(x, cp);
1550    }
1551
1552    /** Merge the jumps in of two chains into one.
1553     */
1554    public static Chain mergeChains(Chain chain1, Chain chain2) {
1555        // recursive merge sort
1556        if (chain2 == null) return chain1;
1557        if (chain1 == null) return chain2;
1558        Assert.check(
1559            chain1.state.stacksize == chain2.state.stacksize &&
1560            chain1.state.nlocks == chain2.state.nlocks);
1561        if (chain1.pc < chain2.pc)
1562            return new Chain(
1563                chain2.pc,
1564                mergeChains(chain1, chain2.next),
1565                chain2.state);
1566        return new Chain(
1567                chain1.pc,
1568                mergeChains(chain1.next, chain2),
1569                chain1.state);
1570    }
1571
1572
1573/* **************************************************************************
1574 * Catch clauses
1575 ****************************************************************************/
1576
1577    /** Add a catch clause to code.
1578     */
1579    public void addCatch(char startPc, char endPc,
1580                         char handlerPc, char catchType) {
1581            catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
1582        }
1583
1584
1585    public void compressCatchTable() {
1586        ListBuffer<char[]> compressedCatchInfo = new ListBuffer<>();
1587        List<Integer> handlerPcs = List.nil();
1588        for (char[] catchEntry : catchInfo) {
1589            handlerPcs = handlerPcs.prepend((int)catchEntry[2]);
1590        }
1591        for (char[] catchEntry : catchInfo) {
1592            int startpc = catchEntry[0];
1593            int endpc = catchEntry[1];
1594            if (startpc == endpc ||
1595                    (startpc == (endpc - 1) &&
1596                    handlerPcs.contains(startpc))) {
1597                continue;
1598            } else {
1599                compressedCatchInfo.append(catchEntry);
1600            }
1601        }
1602        catchInfo = compressedCatchInfo;
1603    }
1604
1605
1606/* **************************************************************************
1607 * Line numbers
1608 ****************************************************************************/
1609
1610    /** Add a line number entry.
1611     */
1612    public void addLineNumber(char startPc, char lineNumber) {
1613        if (lineDebugInfo) {
1614            if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
1615                lineInfo = lineInfo.tail;
1616            if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
1617                lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
1618        }
1619    }
1620
1621    /** Mark beginning of statement.
1622     */
1623    public void statBegin(int pos) {
1624        if (pos != Position.NOPOS) {
1625            pendingStatPos = pos;
1626        }
1627    }
1628
1629    /** Force stat begin eagerly
1630     */
1631    public void markStatBegin() {
1632        if (alive && lineDebugInfo) {
1633            int line = lineMap.getLineNumber(pendingStatPos);
1634            char cp1 = (char)cp;
1635            char line1 = (char)line;
1636            if (cp1 == cp && line1 == line)
1637                addLineNumber(cp1, line1);
1638        }
1639        pendingStatPos = Position.NOPOS;
1640    }
1641
1642
1643/* **************************************************************************
1644 * Simulated VM machine state
1645 ****************************************************************************/
1646
1647    class State implements Cloneable {
1648        /** The set of registers containing values. */
1649        Bits defined;
1650
1651        /** The (types of the) contents of the machine stack. */
1652        Type[] stack;
1653
1654        /** The first stack position currently unused. */
1655        int stacksize;
1656
1657        /** The numbers of registers containing locked monitors. */
1658        int[] locks;
1659        int nlocks;
1660
1661        State() {
1662            defined = new Bits();
1663            stack = new Type[16];
1664        }
1665
1666        State dup() {
1667            try {
1668                State state = (State)super.clone();
1669                state.defined = new Bits(defined);
1670                state.stack = stack.clone();
1671                if (locks != null) state.locks = locks.clone();
1672                if (debugCode) {
1673                    System.err.println("duping state " + this);
1674                    dump();
1675                }
1676                return state;
1677            } catch (CloneNotSupportedException ex) {
1678                throw new AssertionError(ex);
1679            }
1680        }
1681
1682        void lock(int register) {
1683            if (locks == null) {
1684                locks = new int[20];
1685            } else {
1686                locks = ArrayUtils.ensureCapacity(locks, nlocks);
1687            }
1688            locks[nlocks] = register;
1689            nlocks++;
1690        }
1691
1692        void unlock(int register) {
1693            nlocks--;
1694            Assert.check(locks[nlocks] == register);
1695            locks[nlocks] = -1;
1696        }
1697
1698        void push(Type t) {
1699            if (debugCode) System.err.println("   pushing " + t);
1700            switch (t.getTag()) {
1701            case VOID:
1702                return;
1703            case BYTE:
1704            case CHAR:
1705            case SHORT:
1706            case BOOLEAN:
1707                t = syms.intType;
1708                break;
1709            default:
1710                break;
1711            }
1712            stack = ArrayUtils.ensureCapacity(stack, stacksize+2);
1713            stack[stacksize++] = t;
1714            switch (width(t)) {
1715            case 1:
1716                break;
1717            case 2:
1718                stack[stacksize++] = null;
1719                break;
1720            default:
1721                throw new AssertionError(t);
1722            }
1723            if (stacksize > max_stack)
1724                max_stack = stacksize;
1725        }
1726
1727        Type pop1() {
1728            if (debugCode) System.err.println("   popping " + 1);
1729            stacksize--;
1730            Type result = stack[stacksize];
1731            stack[stacksize] = null;
1732            Assert.check(result != null && width(result) == 1);
1733            return result;
1734        }
1735
1736        Type peek() {
1737            return stack[stacksize-1];
1738        }
1739
1740        Type pop2() {
1741            if (debugCode) System.err.println("   popping " + 2);
1742            stacksize -= 2;
1743            Type result = stack[stacksize];
1744            stack[stacksize] = null;
1745            Assert.check(stack[stacksize+1] == null
1746                    && result != null && width(result) == 2);
1747            return result;
1748        }
1749
1750        void pop(int n) {
1751            if (debugCode) System.err.println("   popping " + n);
1752            while (n > 0) {
1753                stack[--stacksize] = null;
1754                n--;
1755            }
1756        }
1757
1758        void pop(Type t) {
1759            pop(width(t));
1760        }
1761
1762        /** Force the top of the stack to be treated as this supertype
1763         *  of its current type. */
1764        void forceStackTop(Type t) {
1765            if (!alive) return;
1766            switch (t.getTag()) {
1767            case CLASS:
1768            case ARRAY:
1769                int width = width(t);
1770                Type old = stack[stacksize-width];
1771                Assert.check(types.isSubtype(types.erasure(old),
1772                                       types.erasure(t)));
1773                stack[stacksize-width] = t;
1774                break;
1775            default:
1776            }
1777        }
1778
1779        void markInitialized(UninitializedType old) {
1780            Type newtype = old.initializedType();
1781            for (int i=0; i<stacksize; i++) {
1782                if (stack[i] == old) stack[i] = newtype;
1783            }
1784            for (int i=0; i<lvar.length; i++) {
1785                LocalVar lv = lvar[i];
1786                if (lv != null && lv.sym.type == old) {
1787                    VarSymbol sym = lv.sym;
1788                    sym = sym.clone(sym.owner);
1789                    sym.type = newtype;
1790                    LocalVar newlv = lvar[i] = new LocalVar(sym);
1791                    newlv.aliveRanges = lv.aliveRanges;
1792                }
1793            }
1794        }
1795
1796        State join(State other) {
1797            defined.andSet(other.defined);
1798            Assert.check(stacksize == other.stacksize
1799                    && nlocks == other.nlocks);
1800            for (int i=0; i<stacksize; ) {
1801                Type t = stack[i];
1802                Type tother = other.stack[i];
1803                Type result =
1804                    t==tother ? t :
1805                    types.isSubtype(t, tother) ? tother :
1806                    types.isSubtype(tother, t) ? t :
1807                    error();
1808                int w = width(result);
1809                stack[i] = result;
1810                if (w == 2) Assert.checkNull(stack[i+1]);
1811                i += w;
1812            }
1813            return this;
1814        }
1815
1816        Type error() {
1817            throw new AssertionError("inconsistent stack types at join point");
1818        }
1819
1820        void dump() {
1821            dump(-1);
1822        }
1823
1824        void dump(int pc) {
1825            System.err.print("stackMap for " + meth.owner + "." + meth);
1826            if (pc == -1)
1827                System.out.println();
1828            else
1829                System.out.println(" at " + pc);
1830            System.err.println(" stack (from bottom):");
1831            for (int i=0; i<stacksize; i++)
1832                System.err.println("  " + i + ": " + stack[i]);
1833
1834            int lastLocal = 0;
1835            for (int i=max_locals-1; i>=0; i--) {
1836                if (defined.isMember(i)) {
1837                    lastLocal = i;
1838                    break;
1839                }
1840            }
1841            if (lastLocal >= 0)
1842                System.err.println(" locals:");
1843            for (int i=0; i<=lastLocal; i++) {
1844                System.err.print("  " + i + ": ");
1845                if (defined.isMember(i)) {
1846                    LocalVar var = lvar[i];
1847                    if (var == null) {
1848                        System.err.println("(none)");
1849                    } else if (var.sym == null)
1850                        System.err.println("UNKNOWN!");
1851                    else
1852                        System.err.println("" + var.sym + " of type " +
1853                                           var.sym.erasure(types));
1854                } else {
1855                    System.err.println("undefined");
1856                }
1857            }
1858            if (nlocks != 0) {
1859                System.err.print(" locks:");
1860                for (int i=0; i<nlocks; i++) {
1861                    System.err.print(" " + locks[i]);
1862                }
1863                System.err.println();
1864            }
1865        }
1866    }
1867
1868    static final Type jsrReturnValue = new JCPrimitiveType(INT, null);
1869
1870
1871/* **************************************************************************
1872 * Local variables
1873 ****************************************************************************/
1874
1875    /** A live range of a local variable. */
1876    static class LocalVar {
1877        final VarSymbol sym;
1878        final char reg;
1879
1880        class Range {
1881            char start_pc = Character.MAX_VALUE;
1882            char length = Character.MAX_VALUE;
1883
1884            Range() {}
1885
1886            Range(char start) {
1887                this.start_pc = start;
1888            }
1889
1890            Range(char start, char length) {
1891                this.start_pc = start;
1892                this.length = length;
1893            }
1894
1895            boolean closed() {
1896                return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE;
1897            }
1898
1899            @Override
1900            public String toString() {
1901                int currentStartPC = start_pc;
1902                int currentLength = length;
1903                return "startpc = " + currentStartPC + " length " + currentLength;
1904            }
1905        }
1906
1907        java.util.List<Range> aliveRanges = new java.util.ArrayList<>();
1908
1909        LocalVar(VarSymbol v) {
1910            this.sym = v;
1911            this.reg = (char)v.adr;
1912        }
1913        public LocalVar dup() {
1914            return new LocalVar(sym);
1915        }
1916
1917        Range firstRange() {
1918            return aliveRanges.isEmpty() ? null : aliveRanges.get(0);
1919        }
1920
1921        Range lastRange() {
1922            return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
1923        }
1924
1925        void removeLastRange() {
1926            Range lastRange = lastRange();
1927            if (lastRange != null) {
1928                aliveRanges.remove(lastRange);
1929            }
1930        }
1931
1932        @Override
1933        public String toString() {
1934            if (aliveRanges == null) {
1935                return "empty local var";
1936            }
1937            StringBuilder sb = new StringBuilder().append(sym)
1938                    .append(" in register ").append((int)reg).append(" \n");
1939            for (Range r : aliveRanges) {
1940                sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc)))
1941                    .append(" length=").append(Integer.toString(((int)r.length)))
1942                    .append("\n");
1943            }
1944            return sb.toString();
1945        }
1946
1947        public void openRange(char start) {
1948            if (!hasOpenRange()) {
1949                aliveRanges.add(new Range(start));
1950            }
1951        }
1952
1953        public void closeRange(char length) {
1954            if (isLastRangeInitialized() && length > 0) {
1955                Range range = lastRange();
1956                if (range != null) {
1957                    if (range.length == Character.MAX_VALUE) {
1958                        range.length = length;
1959                    }
1960                }
1961            } else {
1962                removeLastRange();
1963            }
1964        }
1965
1966        public boolean hasOpenRange() {
1967            if (aliveRanges.isEmpty()) {
1968                return false;
1969            }
1970            return lastRange().length == Character.MAX_VALUE;
1971        }
1972
1973        public boolean isLastRangeInitialized() {
1974            if (aliveRanges.isEmpty()) {
1975                return false;
1976            }
1977            return lastRange().start_pc != Character.MAX_VALUE;
1978        }
1979
1980        public Range getWidestRange() {
1981            if (aliveRanges.isEmpty()) {
1982                return new Range();
1983            } else {
1984                Range firstRange = firstRange();
1985                Range lastRange = lastRange();
1986                char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc));
1987                return new Range(firstRange.start_pc, length);
1988            }
1989         }
1990
1991    }
1992
1993    /** Local variables, indexed by register. */
1994    LocalVar[] lvar;
1995
1996    /** Add a new local variable. */
1997    private void addLocalVar(VarSymbol v) {
1998        int adr = v.adr;
1999        lvar = ArrayUtils.ensureCapacity(lvar, adr+1);
2000        Assert.checkNull(lvar[adr]);
2001        if (pendingJumps != null) {
2002            resolvePending();
2003        }
2004        lvar[adr] = new LocalVar(v);
2005        state.defined.excl(adr);
2006    }
2007
2008    void adjustAliveRanges(int oldCP, int delta) {
2009        for (LocalVar localVar: lvar) {
2010            if (localVar != null) {
2011                for (LocalVar.Range range: localVar.aliveRanges) {
2012                    if (range.closed() && range.start_pc + range.length >= oldCP) {
2013                        range.length += delta;
2014                    }
2015                }
2016            }
2017        }
2018    }
2019
2020    /**
2021     * Calculates the size of the LocalVariableTable.
2022     */
2023    public int getLVTSize() {
2024        int result = varBufferSize;
2025        for (int i = 0; i < varBufferSize; i++) {
2026            LocalVar var = varBuffer[i];
2027            result += var.aliveRanges.size() - 1;
2028        }
2029        return result;
2030    }
2031
2032    /** Set the current variable defined state. */
2033    public void setDefined(Bits newDefined) {
2034        if (alive && newDefined != state.defined) {
2035            Bits diff = new Bits(state.defined).xorSet(newDefined);
2036            for (int adr = diff.nextBit(0);
2037                 adr >= 0;
2038                 adr = diff.nextBit(adr+1)) {
2039                if (adr >= nextreg)
2040                    state.defined.excl(adr);
2041                else if (state.defined.isMember(adr))
2042                    setUndefined(adr);
2043                else
2044                    setDefined(adr);
2045            }
2046        }
2047    }
2048
2049    /** Mark a register as being (possibly) defined. */
2050    public void setDefined(int adr) {
2051        LocalVar v = lvar[adr];
2052        if (v == null) {
2053            state.defined.excl(adr);
2054        } else {
2055            state.defined.incl(adr);
2056            if (cp < Character.MAX_VALUE) {
2057                v.openRange((char)cp);
2058            }
2059        }
2060    }
2061
2062    /** Mark a register as being undefined. */
2063    public void setUndefined(int adr) {
2064        state.defined.excl(adr);
2065        if (adr < lvar.length &&
2066            lvar[adr] != null &&
2067            lvar[adr].isLastRangeInitialized()) {
2068            LocalVar v = lvar[adr];
2069            char length = (char)(curCP() - v.lastRange().start_pc);
2070            if (length < Character.MAX_VALUE) {
2071                lvar[adr] = v.dup();
2072                v.closeRange(length);
2073                putVar(v);
2074            } else {
2075                v.removeLastRange();
2076            }
2077        }
2078    }
2079
2080    /** End the scope of a variable. */
2081    private void endScope(int adr) {
2082        LocalVar v = lvar[adr];
2083        if (v != null) {
2084            if (v.isLastRangeInitialized()) {
2085                char length = (char)(curCP() - v.lastRange().start_pc);
2086                if (length < Character.MAX_VALUE) {
2087                    v.closeRange(length);
2088                    putVar(v);
2089                    fillLocalVarPosition(v);
2090                }
2091            }
2092            /** the call to curCP() can implicitly adjust the current cp, if so
2093             * the alive range of local variables may be modified. Thus we need
2094             * all of them. For this reason assigning null to the given address
2095             * should be the last action to do.
2096             */
2097            lvar[adr] = null;
2098        }
2099        state.defined.excl(adr);
2100    }
2101
2102    private void fillLocalVarPosition(LocalVar lv) {
2103        if (lv == null || lv.sym == null || !lv.sym.hasTypeAnnotations())
2104            return;
2105        for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
2106            TypeAnnotationPosition p = ta.position;
2107            LocalVar.Range widestRange = lv.getWidestRange();
2108            p.lvarOffset = new int[] { (int)widestRange.start_pc };
2109            p.lvarLength = new int[] { (int)widestRange.length };
2110            p.lvarIndex = new int[] { (int)lv.reg };
2111            p.isValidOffset = true;
2112        }
2113    }
2114
2115    // Method to be called after compressCatchTable to
2116    // fill in the exception table index for type
2117    // annotations on exception parameters.
2118    public void fillExceptionParameterPositions() {
2119        for (int i = 0; i < varBufferSize; ++i) {
2120            LocalVar lv = varBuffer[i];
2121            if (lv == null || lv.sym == null
2122                    || !lv.sym.hasTypeAnnotations()
2123                    || !lv.sym.isExceptionParameter())
2124                continue;
2125
2126            for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
2127                TypeAnnotationPosition p = ta.position;
2128                if (p.hasCatchType()) {
2129                    final int idx = findExceptionIndex(p);
2130                    if (idx == -1)
2131                        Assert.error("Could not find exception index for type annotation " +
2132                                     ta + " on exception parameter");
2133                    p.setExceptionIndex(idx);
2134                }
2135            }
2136        }
2137    }
2138
2139    private int findExceptionIndex(TypeAnnotationPosition p) {
2140        final int catchType = p.getCatchType();
2141        final int startPos = p.getStartPos();
2142        final int len = catchInfo.length();
2143        List<char[]> iter = catchInfo.toList();
2144        for (int i = 0; i < len; ++i) {
2145            char[] catchEntry = iter.head;
2146            iter = iter.tail;
2147            int ct = catchEntry[3];
2148            int sp = catchEntry[0];
2149            if (catchType == ct && sp == startPos) {
2150                return i;
2151            }
2152        }
2153        return -1;
2154    }
2155
2156    /** Put a live variable range into the buffer to be output to the
2157     *  class file.
2158     */
2159    void putVar(LocalVar var) {
2160        // Keep local variables if
2161        // 1) we need them for debug information
2162        // 2) it is an exception type and it contains type annotations
2163        boolean keepLocalVariables = varDebugInfo ||
2164            (var.sym.isExceptionParameter() && var.sym.hasTypeAnnotations());
2165        if (!keepLocalVariables) return;
2166        //don't keep synthetic vars, unless they are lambda method parameters
2167        boolean ignoredSyntheticVar = (var.sym.flags() & Flags.SYNTHETIC) != 0 &&
2168                ((var.sym.owner.flags() & Flags.LAMBDA_METHOD) == 0 ||
2169                 (var.sym.flags() & Flags.PARAMETER) == 0);
2170        if (ignoredSyntheticVar) return;
2171        if (varBuffer == null)
2172            varBuffer = new LocalVar[20];
2173        else
2174            varBuffer = ArrayUtils.ensureCapacity(varBuffer, varBufferSize);
2175        varBuffer[varBufferSize++] = var;
2176    }
2177
2178    /** Previously live local variables, to be put into the variable table. */
2179    LocalVar[] varBuffer;
2180    int varBufferSize;
2181
2182    /** Create a new local variable address and return it.
2183     */
2184    private int newLocal(int typecode) {
2185        int reg = nextreg;
2186        int w = width(typecode);
2187        nextreg = reg + w;
2188        if (nextreg > max_locals) max_locals = nextreg;
2189        return reg;
2190    }
2191
2192    private int newLocal(Type type) {
2193        return newLocal(typecode(type));
2194    }
2195
2196    public int newLocal(VarSymbol v) {
2197        int reg = v.adr = newLocal(v.erasure(types));
2198        addLocalVar(v);
2199        return reg;
2200    }
2201
2202    /** Start a set of fresh registers.
2203     */
2204    public void newRegSegment() {
2205        nextreg = max_locals;
2206    }
2207
2208    /** End scopes of all variables with registers &ge; first.
2209     */
2210    public void endScopes(int first) {
2211        int prevNextReg = nextreg;
2212        nextreg = first;
2213        for (int i = nextreg; i < prevNextReg; i++) endScope(i);
2214    }
2215
2216/**************************************************************************
2217 * static tables
2218 *************************************************************************/
2219
2220    public static String mnem(int opcode) {
2221        return Mneumonics.mnem[opcode];
2222    }
2223
2224    private static class Mneumonics {
2225        private final static String[] mnem = new String[ByteCodeCount];
2226        static {
2227            mnem[nop] = "nop";
2228            mnem[aconst_null] = "aconst_null";
2229            mnem[iconst_m1] = "iconst_m1";
2230            mnem[iconst_0] = "iconst_0";
2231            mnem[iconst_1] = "iconst_1";
2232            mnem[iconst_2] = "iconst_2";
2233            mnem[iconst_3] = "iconst_3";
2234            mnem[iconst_4] = "iconst_4";
2235            mnem[iconst_5] = "iconst_5";
2236            mnem[lconst_0] = "lconst_0";
2237            mnem[lconst_1] = "lconst_1";
2238            mnem[fconst_0] = "fconst_0";
2239            mnem[fconst_1] = "fconst_1";
2240            mnem[fconst_2] = "fconst_2";
2241            mnem[dconst_0] = "dconst_0";
2242            mnem[dconst_1] = "dconst_1";
2243            mnem[bipush] = "bipush";
2244            mnem[sipush] = "sipush";
2245            mnem[ldc1] = "ldc1";
2246            mnem[ldc2] = "ldc2";
2247            mnem[ldc2w] = "ldc2w";
2248            mnem[iload] = "iload";
2249            mnem[lload] = "lload";
2250            mnem[fload] = "fload";
2251            mnem[dload] = "dload";
2252            mnem[aload] = "aload";
2253            mnem[iload_0] = "iload_0";
2254            mnem[lload_0] = "lload_0";
2255            mnem[fload_0] = "fload_0";
2256            mnem[dload_0] = "dload_0";
2257            mnem[aload_0] = "aload_0";
2258            mnem[iload_1] = "iload_1";
2259            mnem[lload_1] = "lload_1";
2260            mnem[fload_1] = "fload_1";
2261            mnem[dload_1] = "dload_1";
2262            mnem[aload_1] = "aload_1";
2263            mnem[iload_2] = "iload_2";
2264            mnem[lload_2] = "lload_2";
2265            mnem[fload_2] = "fload_2";
2266            mnem[dload_2] = "dload_2";
2267            mnem[aload_2] = "aload_2";
2268            mnem[iload_3] = "iload_3";
2269            mnem[lload_3] = "lload_3";
2270            mnem[fload_3] = "fload_3";
2271            mnem[dload_3] = "dload_3";
2272            mnem[aload_3] = "aload_3";
2273            mnem[iaload] = "iaload";
2274            mnem[laload] = "laload";
2275            mnem[faload] = "faload";
2276            mnem[daload] = "daload";
2277            mnem[aaload] = "aaload";
2278            mnem[baload] = "baload";
2279            mnem[caload] = "caload";
2280            mnem[saload] = "saload";
2281            mnem[istore] = "istore";
2282            mnem[lstore] = "lstore";
2283            mnem[fstore] = "fstore";
2284            mnem[dstore] = "dstore";
2285            mnem[astore] = "astore";
2286            mnem[istore_0] = "istore_0";
2287            mnem[lstore_0] = "lstore_0";
2288            mnem[fstore_0] = "fstore_0";
2289            mnem[dstore_0] = "dstore_0";
2290            mnem[astore_0] = "astore_0";
2291            mnem[istore_1] = "istore_1";
2292            mnem[lstore_1] = "lstore_1";
2293            mnem[fstore_1] = "fstore_1";
2294            mnem[dstore_1] = "dstore_1";
2295            mnem[astore_1] = "astore_1";
2296            mnem[istore_2] = "istore_2";
2297            mnem[lstore_2] = "lstore_2";
2298            mnem[fstore_2] = "fstore_2";
2299            mnem[dstore_2] = "dstore_2";
2300            mnem[astore_2] = "astore_2";
2301            mnem[istore_3] = "istore_3";
2302            mnem[lstore_3] = "lstore_3";
2303            mnem[fstore_3] = "fstore_3";
2304            mnem[dstore_3] = "dstore_3";
2305            mnem[astore_3] = "astore_3";
2306            mnem[iastore] = "iastore";
2307            mnem[lastore] = "lastore";
2308            mnem[fastore] = "fastore";
2309            mnem[dastore] = "dastore";
2310            mnem[aastore] = "aastore";
2311            mnem[bastore] = "bastore";
2312            mnem[castore] = "castore";
2313            mnem[sastore] = "sastore";
2314            mnem[pop] = "pop";
2315            mnem[pop2] = "pop2";
2316            mnem[dup] = "dup";
2317            mnem[dup_x1] = "dup_x1";
2318            mnem[dup_x2] = "dup_x2";
2319            mnem[dup2] = "dup2";
2320            mnem[dup2_x1] = "dup2_x1";
2321            mnem[dup2_x2] = "dup2_x2";
2322            mnem[swap] = "swap";
2323            mnem[iadd] = "iadd";
2324            mnem[ladd] = "ladd";
2325            mnem[fadd] = "fadd";
2326            mnem[dadd] = "dadd";
2327            mnem[isub] = "isub";
2328            mnem[lsub] = "lsub";
2329            mnem[fsub] = "fsub";
2330            mnem[dsub] = "dsub";
2331            mnem[imul] = "imul";
2332            mnem[lmul] = "lmul";
2333            mnem[fmul] = "fmul";
2334            mnem[dmul] = "dmul";
2335            mnem[idiv] = "idiv";
2336            mnem[ldiv] = "ldiv";
2337            mnem[fdiv] = "fdiv";
2338            mnem[ddiv] = "ddiv";
2339            mnem[imod] = "imod";
2340            mnem[lmod] = "lmod";
2341            mnem[fmod] = "fmod";
2342            mnem[dmod] = "dmod";
2343            mnem[ineg] = "ineg";
2344            mnem[lneg] = "lneg";
2345            mnem[fneg] = "fneg";
2346            mnem[dneg] = "dneg";
2347            mnem[ishl] = "ishl";
2348            mnem[lshl] = "lshl";
2349            mnem[ishr] = "ishr";
2350            mnem[lshr] = "lshr";
2351            mnem[iushr] = "iushr";
2352            mnem[lushr] = "lushr";
2353            mnem[iand] = "iand";
2354            mnem[land] = "land";
2355            mnem[ior] = "ior";
2356            mnem[lor] = "lor";
2357            mnem[ixor] = "ixor";
2358            mnem[lxor] = "lxor";
2359            mnem[iinc] = "iinc";
2360            mnem[i2l] = "i2l";
2361            mnem[i2f] = "i2f";
2362            mnem[i2d] = "i2d";
2363            mnem[l2i] = "l2i";
2364            mnem[l2f] = "l2f";
2365            mnem[l2d] = "l2d";
2366            mnem[f2i] = "f2i";
2367            mnem[f2l] = "f2l";
2368            mnem[f2d] = "f2d";
2369            mnem[d2i] = "d2i";
2370            mnem[d2l] = "d2l";
2371            mnem[d2f] = "d2f";
2372            mnem[int2byte] = "int2byte";
2373            mnem[int2char] = "int2char";
2374            mnem[int2short] = "int2short";
2375            mnem[lcmp] = "lcmp";
2376            mnem[fcmpl] = "fcmpl";
2377            mnem[fcmpg] = "fcmpg";
2378            mnem[dcmpl] = "dcmpl";
2379            mnem[dcmpg] = "dcmpg";
2380            mnem[ifeq] = "ifeq";
2381            mnem[ifne] = "ifne";
2382            mnem[iflt] = "iflt";
2383            mnem[ifge] = "ifge";
2384            mnem[ifgt] = "ifgt";
2385            mnem[ifle] = "ifle";
2386            mnem[if_icmpeq] = "if_icmpeq";
2387            mnem[if_icmpne] = "if_icmpne";
2388            mnem[if_icmplt] = "if_icmplt";
2389            mnem[if_icmpge] = "if_icmpge";
2390            mnem[if_icmpgt] = "if_icmpgt";
2391            mnem[if_icmple] = "if_icmple";
2392            mnem[if_acmpeq] = "if_acmpeq";
2393            mnem[if_acmpne] = "if_acmpne";
2394            mnem[goto_] = "goto_";
2395            mnem[jsr] = "jsr";
2396            mnem[ret] = "ret";
2397            mnem[tableswitch] = "tableswitch";
2398            mnem[lookupswitch] = "lookupswitch";
2399            mnem[ireturn] = "ireturn";
2400            mnem[lreturn] = "lreturn";
2401            mnem[freturn] = "freturn";
2402            mnem[dreturn] = "dreturn";
2403            mnem[areturn] = "areturn";
2404            mnem[return_] = "return_";
2405            mnem[getstatic] = "getstatic";
2406            mnem[putstatic] = "putstatic";
2407            mnem[getfield] = "getfield";
2408            mnem[putfield] = "putfield";
2409            mnem[invokevirtual] = "invokevirtual";
2410            mnem[invokespecial] = "invokespecial";
2411            mnem[invokestatic] = "invokestatic";
2412            mnem[invokeinterface] = "invokeinterface";
2413            mnem[invokedynamic] = "invokedynamic";
2414            mnem[new_] = "new_";
2415            mnem[newarray] = "newarray";
2416            mnem[anewarray] = "anewarray";
2417            mnem[arraylength] = "arraylength";
2418            mnem[athrow] = "athrow";
2419            mnem[checkcast] = "checkcast";
2420            mnem[instanceof_] = "instanceof_";
2421            mnem[monitorenter] = "monitorenter";
2422            mnem[monitorexit] = "monitorexit";
2423            mnem[wide] = "wide";
2424            mnem[multianewarray] = "multianewarray";
2425            mnem[if_acmp_null] = "if_acmp_null";
2426            mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2427            mnem[goto_w] = "goto_w";
2428            mnem[jsr_w] = "jsr_w";
2429            mnem[breakpoint] = "breakpoint";
2430        }
2431    }
2432}
2433