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