Code.java revision 2772:3bdbc3b8aa14
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.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    /** Construct a code object, given the settings of the fatcode,
186     *  debugging info switches and the CharacterRangeTable.
187     */
188    public Code(MethodSymbol meth,
189                boolean fatcode,
190                Position.LineMap lineMap,
191                boolean varDebugInfo,
192                StackMapFormat stackMap,
193                boolean debugCode,
194                CRTable crt,
195                Symtab syms,
196                Types types,
197                Pool pool) {
198        this.meth = meth;
199        this.fatcode = fatcode;
200        this.lineMap = lineMap;
201        this.lineDebugInfo = lineMap != null;
202        this.varDebugInfo = varDebugInfo;
203        this.crt = crt;
204        this.syms = syms;
205        this.types = types;
206        this.debugCode = debugCode;
207        this.stackMap = stackMap;
208        switch (stackMap) {
209        case CLDC:
210        case JSR202:
211            this.needStackMap = true;
212            break;
213        default:
214            this.needStackMap = false;
215        }
216        state = new State();
217        lvar = new LocalVar[20];
218        this.pool = pool;
219    }
220
221
222/* **************************************************************************
223 * Typecodes & related stuff
224 ****************************************************************************/
225
226    /** Given a type, return its type code (used implicitly in the
227     *  JVM architecture).
228     */
229    public static int typecode(Type type) {
230        switch (type.getTag()) {
231        case BYTE: return BYTEcode;
232        case SHORT: return SHORTcode;
233        case CHAR: return CHARcode;
234        case INT: return INTcode;
235        case LONG: return LONGcode;
236        case FLOAT: return FLOATcode;
237        case DOUBLE: return DOUBLEcode;
238        case BOOLEAN: return BYTEcode;
239        case VOID: return VOIDcode;
240        case CLASS:
241        case ARRAY:
242        case METHOD:
243        case BOT:
244        case TYPEVAR:
245        case UNINITIALIZED_THIS:
246        case UNINITIALIZED_OBJECT:
247            return OBJECTcode;
248        default: throw new AssertionError("typecode " + type.getTag());
249        }
250    }
251
252    /** Collapse type code for subtypes of int to INTcode.
253     */
254    public static int truncate(int tc) {
255        switch (tc) {
256        case BYTEcode: case SHORTcode: case CHARcode: return INTcode;
257        default: return tc;
258        }
259    }
260
261    /** The width in bytes of objects of the type.
262     */
263    public static int width(int typecode) {
264        switch (typecode) {
265        case LONGcode: case DOUBLEcode: return 2;
266        case VOIDcode: return 0;
267        default: return 1;
268        }
269    }
270
271    public static int width(Type type) {
272        return type == null ? 1 : width(typecode(type));
273    }
274
275    /** The total width taken up by a vector of objects.
276     */
277    public static int width(List<Type> types) {
278        int w = 0;
279        for (List<Type> l = types; l.nonEmpty(); l = l.tail)
280            w = w + width(l.head);
281        return w;
282    }
283
284    /** Given a type, return its code for allocating arrays of that type.
285     */
286    public static int arraycode(Type type) {
287        switch (type.getTag()) {
288        case BYTE: return 8;
289        case BOOLEAN: return 4;
290        case SHORT: return 9;
291        case CHAR: return 5;
292        case INT: return 10;
293        case LONG: return 11;
294        case FLOAT: return 6;
295        case DOUBLE: return 7;
296        case CLASS: return 0;
297        case ARRAY: return 1;
298        default: throw new AssertionError("arraycode " + type);
299        }
300    }
301
302
303/* **************************************************************************
304 * Emit code
305 ****************************************************************************/
306
307    /** The current output code pointer.
308     */
309    public int curCP() {
310        /*
311         * This method has side-effects because calling it can indirectly provoke
312         *  extra code generation, like goto instructions, depending on the context
313         *  where it's called.
314         *  Use with care or even better avoid using it.
315         */
316        if (pendingJumps != null) {
317            resolvePending();
318        }
319        if (pendingStatPos != Position.NOPOS) {
320            markStatBegin();
321        }
322        fixedPc = true;
323        return cp;
324    }
325
326    /** Emit a byte of code.
327     */
328    private  void emit1(int od) {
329        if (!alive) return;
330        code = ArrayUtils.ensureCapacity(code, cp);
331        code[cp++] = (byte)od;
332    }
333
334    /** Emit two bytes of code.
335     */
336    private void emit2(int od) {
337        if (!alive) return;
338        if (cp + 2 > code.length) {
339            emit1(od >> 8);
340            emit1(od);
341        } else {
342            code[cp++] = (byte)(od >> 8);
343            code[cp++] = (byte)od;
344        }
345    }
346
347    /** Emit four bytes of code.
348     */
349    public void emit4(int od) {
350        if (!alive) return;
351        if (cp + 4 > code.length) {
352            emit1(od >> 24);
353            emit1(od >> 16);
354            emit1(od >> 8);
355            emit1(od);
356        } else {
357            code[cp++] = (byte)(od >> 24);
358            code[cp++] = (byte)(od >> 16);
359            code[cp++] = (byte)(od >> 8);
360            code[cp++] = (byte)od;
361        }
362    }
363
364    /** Emit an opcode.
365     */
366    private void emitop(int op) {
367        if (pendingJumps != null) resolvePending();
368        if (alive) {
369            if (pendingStatPos != Position.NOPOS)
370                markStatBegin();
371            if (pendingStackMap) {
372                pendingStackMap = false;
373                emitStackMap();
374            }
375            if (debugCode)
376                System.err.println("emit@" + cp + " stack=" +
377                                   state.stacksize + ": " +
378                                   mnem(op));
379            emit1(op);
380        }
381    }
382
383    void postop() {
384        Assert.check(alive || state.stacksize == 0);
385    }
386
387    /** Emit a ldc (or ldc_w) instruction, taking into account operand size
388    */
389    public void emitLdc(int od) {
390        if (od <= 255) {
391            emitop1(ldc1, od);
392        }
393        else {
394            emitop2(ldc2, od);
395        }
396    }
397
398    /** Emit a multinewarray instruction.
399     */
400    public void emitMultianewarray(int ndims, int type, Type arrayType) {
401        emitop(multianewarray);
402        if (!alive) return;
403        emit2(type);
404        emit1(ndims);
405        state.pop(ndims);
406        state.push(arrayType);
407    }
408
409    /** Emit newarray.
410     */
411    public void emitNewarray(int elemcode, Type arrayType) {
412        emitop(newarray);
413        if (!alive) return;
414        emit1(elemcode);
415        state.pop(1); // count
416        state.push(arrayType);
417    }
418
419    /** Emit anewarray.
420     */
421    public void emitAnewarray(int od, Type arrayType) {
422        emitop(anewarray);
423        if (!alive) return;
424        emit2(od);
425        state.pop(1);
426        state.push(arrayType);
427    }
428
429    /** Emit an invokeinterface instruction.
430     */
431    public void emitInvokeinterface(int meth, Type mtype) {
432        int argsize = width(mtype.getParameterTypes());
433        emitop(invokeinterface);
434        if (!alive) return;
435        emit2(meth);
436        emit1(argsize + 1);
437        emit1(0);
438        state.pop(argsize + 1);
439        state.push(mtype.getReturnType());
440    }
441
442    /** Emit an invokespecial instruction.
443     */
444    public void emitInvokespecial(int meth, Type mtype) {
445        int argsize = width(mtype.getParameterTypes());
446        emitop(invokespecial);
447        if (!alive) return;
448        emit2(meth);
449        Symbol sym = (Symbol)pool.pool[meth];
450        state.pop(argsize);
451        if (sym.isConstructor())
452            state.markInitialized((UninitializedType)state.peek());
453        state.pop(1);
454        state.push(mtype.getReturnType());
455    }
456
457    /** Emit an invokestatic instruction.
458     */
459    public void emitInvokestatic(int meth, Type mtype) {
460        int argsize = width(mtype.getParameterTypes());
461        emitop(invokestatic);
462        if (!alive) return;
463        emit2(meth);
464        state.pop(argsize);
465        state.push(mtype.getReturnType());
466    }
467
468    /** Emit an invokevirtual instruction.
469     */
470    public void emitInvokevirtual(int meth, Type mtype) {
471        int argsize = width(mtype.getParameterTypes());
472        emitop(invokevirtual);
473        if (!alive) return;
474        emit2(meth);
475        state.pop(argsize + 1);
476        state.push(mtype.getReturnType());
477    }
478
479    /** Emit an invokedynamic instruction.
480     */
481    public void emitInvokedynamic(int desc, Type mtype) {
482        int argsize = width(mtype.getParameterTypes());
483        emitop(invokedynamic);
484        if (!alive) return;
485        emit2(desc);
486        emit2(0);
487        state.pop(argsize);
488        state.push(mtype.getReturnType());
489    }
490
491    /** Emit an opcode with no operand field.
492     */
493    public void emitop0(int op) {
494        emitop(op);
495        if (!alive) return;
496        switch (op) {
497        case aaload: {
498            state.pop(1);// index
499            Type a = state.stack[state.stacksize-1];
500            state.pop(1);
501            //sometimes 'null type' is treated as a one-dimensional array type
502            //see Gen.visitLiteral - we should handle this case accordingly
503            Type stackType = a.hasTag(BOT) ?
504                syms.objectType :
505                types.erasure(types.elemtype(a));
506            state.push(stackType); }
507            break;
508        case goto_:
509            markDead();
510            break;
511        case nop:
512        case ineg:
513        case lneg:
514        case fneg:
515        case dneg:
516            break;
517        case aconst_null:
518            state.push(syms.botType);
519            break;
520        case iconst_m1:
521        case iconst_0:
522        case iconst_1:
523        case iconst_2:
524        case iconst_3:
525        case iconst_4:
526        case iconst_5:
527        case iload_0:
528        case iload_1:
529        case iload_2:
530        case iload_3:
531            state.push(syms.intType);
532            break;
533        case lconst_0:
534        case lconst_1:
535        case lload_0:
536        case lload_1:
537        case lload_2:
538        case lload_3:
539            state.push(syms.longType);
540            break;
541        case fconst_0:
542        case fconst_1:
543        case fconst_2:
544        case fload_0:
545        case fload_1:
546        case fload_2:
547        case fload_3:
548            state.push(syms.floatType);
549            break;
550        case dconst_0:
551        case dconst_1:
552        case dload_0:
553        case dload_1:
554        case dload_2:
555        case dload_3:
556            state.push(syms.doubleType);
557            break;
558        case aload_0:
559            state.push(lvar[0].sym.type);
560            break;
561        case aload_1:
562            state.push(lvar[1].sym.type);
563            break;
564        case aload_2:
565            state.push(lvar[2].sym.type);
566            break;
567        case aload_3:
568            state.push(lvar[3].sym.type);
569            break;
570        case iaload:
571        case baload:
572        case caload:
573        case saload:
574            state.pop(2);
575            state.push(syms.intType);
576            break;
577        case laload:
578            state.pop(2);
579            state.push(syms.longType);
580            break;
581        case faload:
582            state.pop(2);
583            state.push(syms.floatType);
584            break;
585        case daload:
586            state.pop(2);
587            state.push(syms.doubleType);
588            break;
589        case istore_0:
590        case istore_1:
591        case istore_2:
592        case istore_3:
593        case fstore_0:
594        case fstore_1:
595        case fstore_2:
596        case fstore_3:
597        case astore_0:
598        case astore_1:
599        case astore_2:
600        case astore_3:
601        case pop:
602        case lshr:
603        case lshl:
604        case lushr:
605            state.pop(1);
606            break;
607        case areturn:
608        case ireturn:
609        case freturn:
610            Assert.check(state.nlocks == 0);
611            state.pop(1);
612            markDead();
613            break;
614        case athrow:
615            state.pop(1);
616            markDead();
617            break;
618        case lstore_0:
619        case lstore_1:
620        case lstore_2:
621        case lstore_3:
622        case dstore_0:
623        case dstore_1:
624        case dstore_2:
625        case dstore_3:
626        case pop2:
627            state.pop(2);
628            break;
629        case lreturn:
630        case dreturn:
631            Assert.check(state.nlocks == 0);
632            state.pop(2);
633            markDead();
634            break;
635        case dup:
636            state.push(state.stack[state.stacksize-1]);
637            break;
638        case return_:
639            Assert.check(state.nlocks == 0);
640            markDead();
641            break;
642        case arraylength:
643            state.pop(1);
644            state.push(syms.intType);
645            break;
646        case isub:
647        case iadd:
648        case imul:
649        case idiv:
650        case imod:
651        case ishl:
652        case ishr:
653        case iushr:
654        case iand:
655        case ior:
656        case ixor:
657            state.pop(1);
658            // state.pop(1);
659            // state.push(syms.intType);
660            break;
661        case aastore:
662            state.pop(3);
663            break;
664        case land:
665        case lor:
666        case lxor:
667        case lmod:
668        case ldiv:
669        case lmul:
670        case lsub:
671        case ladd:
672            state.pop(2);
673            break;
674        case lcmp:
675            state.pop(4);
676            state.push(syms.intType);
677            break;
678        case l2i:
679            state.pop(2);
680            state.push(syms.intType);
681            break;
682        case i2l:
683            state.pop(1);
684            state.push(syms.longType);
685            break;
686        case i2f:
687            state.pop(1);
688            state.push(syms.floatType);
689            break;
690        case i2d:
691            state.pop(1);
692            state.push(syms.doubleType);
693            break;
694        case l2f:
695            state.pop(2);
696            state.push(syms.floatType);
697            break;
698        case l2d:
699            state.pop(2);
700            state.push(syms.doubleType);
701            break;
702        case f2i:
703            state.pop(1);
704            state.push(syms.intType);
705            break;
706        case f2l:
707            state.pop(1);
708            state.push(syms.longType);
709            break;
710        case f2d:
711            state.pop(1);
712            state.push(syms.doubleType);
713            break;
714        case d2i:
715            state.pop(2);
716            state.push(syms.intType);
717            break;
718        case d2l:
719            state.pop(2);
720            state.push(syms.longType);
721            break;
722        case d2f:
723            state.pop(2);
724            state.push(syms.floatType);
725            break;
726        case tableswitch:
727        case lookupswitch:
728            state.pop(1);
729            // the caller is responsible for patching up the state
730            break;
731        case dup_x1: {
732            Type val1 = state.pop1();
733            Type val2 = state.pop1();
734            state.push(val1);
735            state.push(val2);
736            state.push(val1);
737            break;
738        }
739        case bastore:
740            state.pop(3);
741            break;
742        case int2byte:
743        case int2char:
744        case int2short:
745            break;
746        case fmul:
747        case fadd:
748        case fsub:
749        case fdiv:
750        case fmod:
751            state.pop(1);
752            break;
753        case castore:
754        case iastore:
755        case fastore:
756        case sastore:
757            state.pop(3);
758            break;
759        case lastore:
760        case dastore:
761            state.pop(4);
762            break;
763        case dup2:
764            if (state.stack[state.stacksize-1] != null) {
765                Type value1 = state.pop1();
766                Type value2 = state.pop1();
767                state.push(value2);
768                state.push(value1);
769                state.push(value2);
770                state.push(value1);
771            } else {
772                Type value = state.pop2();
773                state.push(value);
774                state.push(value);
775            }
776            break;
777        case dup2_x1:
778            if (state.stack[state.stacksize-1] != null) {
779                Type value1 = state.pop1();
780                Type value2 = state.pop1();
781                Type value3 = state.pop1();
782                state.push(value2);
783                state.push(value1);
784                state.push(value3);
785                state.push(value2);
786                state.push(value1);
787            } else {
788                Type value1 = state.pop2();
789                Type value2 = state.pop1();
790                state.push(value1);
791                state.push(value2);
792                state.push(value1);
793            }
794            break;
795        case dup2_x2:
796            if (state.stack[state.stacksize-1] != null) {
797                Type value1 = state.pop1();
798                Type value2 = state.pop1();
799                if (state.stack[state.stacksize-1] != null) {
800                    // form 1
801                    Type value3 = state.pop1();
802                    Type value4 = state.pop1();
803                    state.push(value2);
804                    state.push(value1);
805                    state.push(value4);
806                    state.push(value3);
807                    state.push(value2);
808                    state.push(value1);
809                } else {
810                    // form 3
811                    Type value3 = state.pop2();
812                    state.push(value2);
813                    state.push(value1);
814                    state.push(value3);
815                    state.push(value2);
816                    state.push(value1);
817                }
818            } else {
819                Type value1 = state.pop2();
820                if (state.stack[state.stacksize-1] != null) {
821                    // form 2
822                    Type value2 = state.pop1();
823                    Type value3 = state.pop1();
824                    state.push(value1);
825                    state.push(value3);
826                    state.push(value2);
827                    state.push(value1);
828                } else {
829                    // form 4
830                    Type value2 = state.pop2();
831                    state.push(value1);
832                    state.push(value2);
833                    state.push(value1);
834                }
835            }
836            break;
837        case dup_x2: {
838            Type value1 = state.pop1();
839            if (state.stack[state.stacksize-1] != null) {
840                // form 1
841                Type value2 = state.pop1();
842                Type value3 = state.pop1();
843                state.push(value1);
844                state.push(value3);
845                state.push(value2);
846                state.push(value1);
847            } else {
848                // form 2
849                Type value2 = state.pop2();
850                state.push(value1);
851                state.push(value2);
852                state.push(value1);
853            }
854        }
855            break;
856        case fcmpl:
857        case fcmpg:
858            state.pop(2);
859            state.push(syms.intType);
860            break;
861        case dcmpl:
862        case dcmpg:
863            state.pop(4);
864            state.push(syms.intType);
865            break;
866        case swap: {
867            Type value1 = state.pop1();
868            Type value2 = state.pop1();
869            state.push(value1);
870            state.push(value2);
871            break;
872        }
873        case dadd:
874        case dsub:
875        case dmul:
876        case ddiv:
877        case dmod:
878            state.pop(2);
879            break;
880        case ret:
881            markDead();
882            break;
883        case wide:
884            // must be handled by the caller.
885            return;
886        case monitorenter:
887        case monitorexit:
888            state.pop(1);
889            break;
890
891        default:
892            throw new AssertionError(mnem(op));
893        }
894        postop();
895    }
896
897    /** Emit an opcode with a one-byte operand field.
898     */
899    public void emitop1(int op, int od) {
900        emitop(op);
901        if (!alive) return;
902        emit1(od);
903        switch (op) {
904        case bipush:
905            state.push(syms.intType);
906            break;
907        case ldc1:
908            state.push(typeForPool(pool.pool[od]));
909            break;
910        default:
911            throw new AssertionError(mnem(op));
912        }
913        postop();
914    }
915
916    /** The type of a constant pool entry. */
917    private Type typeForPool(Object o) {
918        if (o instanceof Integer) return syms.intType;
919        if (o instanceof Float) return syms.floatType;
920        if (o instanceof String) return syms.stringType;
921        if (o instanceof Long) return syms.longType;
922        if (o instanceof Double) return syms.doubleType;
923        if (o instanceof ClassSymbol) return syms.classType;
924        if (o instanceof Pool.MethodHandle) return syms.methodHandleType;
925        if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type);
926        if (o instanceof Type) {
927            Type ty = (Type) o;
928
929            if (ty instanceof Type.ArrayType) return syms.classType;
930            if (ty instanceof Type.MethodType) return syms.methodTypeType;
931        }
932        throw new AssertionError("Invalid type of constant pool entry: " + o.getClass());
933    }
934
935    /** Emit an opcode with a one-byte operand field;
936     *  widen if field does not fit in a byte.
937     */
938    public void emitop1w(int op, int od) {
939        if (od > 0xFF) {
940            emitop(wide);
941            emitop(op);
942            emit2(od);
943        } else {
944            emitop(op);
945            emit1(od);
946        }
947        if (!alive) return;
948        switch (op) {
949        case iload:
950            state.push(syms.intType);
951            break;
952        case lload:
953            state.push(syms.longType);
954            break;
955        case fload:
956            state.push(syms.floatType);
957            break;
958        case dload:
959            state.push(syms.doubleType);
960            break;
961        case aload:
962            state.push(lvar[od].sym.type);
963            break;
964        case lstore:
965        case dstore:
966            state.pop(2);
967            break;
968        case istore:
969        case fstore:
970        case astore:
971            state.pop(1);
972            break;
973        case ret:
974            markDead();
975            break;
976        default:
977            throw new AssertionError(mnem(op));
978        }
979        postop();
980    }
981
982    /** Emit an opcode with two one-byte operand fields;
983     *  widen if either field does not fit in a byte.
984     */
985    public void emitop1w(int op, int od1, int od2) {
986        if (od1 > 0xFF || od2 < -128 || od2 > 127) {
987            emitop(wide);
988            emitop(op);
989            emit2(od1);
990            emit2(od2);
991        } else {
992            emitop(op);
993            emit1(od1);
994            emit1(od2);
995        }
996        if (!alive) return;
997        switch (op) {
998        case iinc:
999            break;
1000        default:
1001            throw new AssertionError(mnem(op));
1002        }
1003    }
1004
1005    /** Emit an opcode with a two-byte operand field.
1006     */
1007    public void emitop2(int op, int od) {
1008        emitop(op);
1009        if (!alive) return;
1010        emit2(od);
1011        switch (op) {
1012        case getstatic:
1013            state.push(((Symbol)(pool.pool[od])).erasure(types));
1014            break;
1015        case putstatic:
1016            state.pop(((Symbol)(pool.pool[od])).erasure(types));
1017            break;
1018        case new_:
1019            Symbol sym;
1020            if (pool.pool[od] instanceof UniqueType) {
1021                // Required by change in Gen.makeRef to allow
1022                // annotated types.
1023                // TODO: is this needed anywhere else?
1024                sym = ((UniqueType)(pool.pool[od])).type.tsym;
1025            } else {
1026                sym = (Symbol)(pool.pool[od]);
1027            }
1028            state.push(uninitializedObject(sym.erasure(types), cp-3));
1029            break;
1030        case sipush:
1031            state.push(syms.intType);
1032            break;
1033        case if_acmp_null:
1034        case if_acmp_nonnull:
1035        case ifeq:
1036        case ifne:
1037        case iflt:
1038        case ifge:
1039        case ifgt:
1040        case ifle:
1041            state.pop(1);
1042            break;
1043        case if_icmpeq:
1044        case if_icmpne:
1045        case if_icmplt:
1046        case if_icmpge:
1047        case if_icmpgt:
1048        case if_icmple:
1049        case if_acmpeq:
1050        case if_acmpne:
1051            state.pop(2);
1052            break;
1053        case goto_:
1054            markDead();
1055            break;
1056        case putfield:
1057            state.pop(((Symbol)(pool.pool[od])).erasure(types));
1058            state.pop(1); // object ref
1059            break;
1060        case getfield:
1061            state.pop(1); // object ref
1062            state.push(((Symbol)(pool.pool[od])).erasure(types));
1063            break;
1064        case checkcast: {
1065            state.pop(1); // object ref
1066            Object o = pool.pool[od];
1067            Type t = (o instanceof Symbol)
1068                ? ((Symbol)o).erasure(types)
1069                : types.erasure((((UniqueType)o).type));
1070            state.push(t);
1071            break; }
1072        case ldc2w:
1073            state.push(typeForPool(pool.pool[od]));
1074            break;
1075        case instanceof_:
1076            state.pop(1);
1077            state.push(syms.intType);
1078            break;
1079        case ldc2:
1080            state.push(typeForPool(pool.pool[od]));
1081            break;
1082        case jsr:
1083            break;
1084        default:
1085            throw new AssertionError(mnem(op));
1086        }
1087        // postop();
1088    }
1089
1090    /** Emit an opcode with a four-byte operand field.
1091     */
1092    public void emitop4(int op, int od) {
1093        emitop(op);
1094        if (!alive) return;
1095        emit4(od);
1096        switch (op) {
1097        case goto_w:
1098            markDead();
1099            break;
1100        case jsr_w:
1101            break;
1102        default:
1103            throw new AssertionError(mnem(op));
1104        }
1105        // postop();
1106    }
1107
1108    /** Align code pointer to next `incr' boundary.
1109     */
1110    public void align(int incr) {
1111        if (alive)
1112            while (cp % incr != 0) emitop0(nop);
1113    }
1114
1115    /** Place a byte into code at address pc.
1116     *  Pre: {@literal pc + 1 <= cp }.
1117     */
1118    private void put1(int pc, int op) {
1119        code[pc] = (byte)op;
1120    }
1121
1122    /** Place two bytes into code at address pc.
1123     *  Pre: {@literal pc + 2 <= cp }.
1124     */
1125    private void put2(int pc, int od) {
1126        // pre: pc + 2 <= cp
1127        put1(pc, od >> 8);
1128        put1(pc+1, od);
1129    }
1130
1131    /** Place four  bytes into code at address pc.
1132     *  Pre: {@literal pc + 4 <= cp }.
1133     */
1134    public void put4(int pc, int od) {
1135        // pre: pc + 4 <= cp
1136        put1(pc  , od >> 24);
1137        put1(pc+1, od >> 16);
1138        put1(pc+2, od >> 8);
1139        put1(pc+3, od);
1140    }
1141
1142    /** Return code byte at position pc as an unsigned int.
1143     */
1144    private int get1(int pc) {
1145        return code[pc] & 0xFF;
1146    }
1147
1148    /** Return two code bytes at position pc as an unsigned int.
1149     */
1150    private int get2(int pc) {
1151        return (get1(pc) << 8) | get1(pc+1);
1152    }
1153
1154    /** Return four code bytes at position pc as an int.
1155     */
1156    public int get4(int pc) {
1157        // pre: pc + 4 <= cp
1158        return
1159            (get1(pc) << 24) |
1160            (get1(pc+1) << 16) |
1161            (get1(pc+2) << 8) |
1162            (get1(pc+3));
1163    }
1164
1165    /** Is code generation currently enabled?
1166     */
1167    public boolean isAlive() {
1168        return alive || pendingJumps != null;
1169    }
1170
1171    /** Switch code generation on/off.
1172     */
1173    public void markDead() {
1174        alive = false;
1175    }
1176
1177    /** Declare an entry point; return current code pointer
1178     */
1179    public int entryPoint() {
1180        int pc = curCP();
1181        alive = true;
1182        pendingStackMap = needStackMap;
1183        return pc;
1184    }
1185
1186    /** Declare an entry point with initial state;
1187     *  return current code pointer
1188     */
1189    public int entryPoint(State state) {
1190        int pc = curCP();
1191        alive = true;
1192        State newState = state.dup();
1193        setDefined(newState.defined);
1194        this.state = newState;
1195        Assert.check(state.stacksize <= max_stack);
1196        if (debugCode) System.err.println("entry point " + state);
1197        pendingStackMap = needStackMap;
1198        return pc;
1199    }
1200
1201    /** Declare an entry point with initial state plus a pushed value;
1202     *  return current code pointer
1203     */
1204    public int entryPoint(State state, Type pushed) {
1205        int pc = curCP();
1206        alive = true;
1207        State newState = state.dup();
1208        setDefined(newState.defined);
1209        this.state = newState;
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    void adjustAliveRanges(int oldCP, int delta) {
2012        for (LocalVar localVar: lvar) {
2013            if (localVar != null) {
2014                for (LocalVar.Range range: localVar.aliveRanges) {
2015                    if (range.closed() && range.start_pc + range.length >= oldCP) {
2016                        range.length += delta;
2017                    }
2018                }
2019            }
2020        }
2021    }
2022
2023    /**
2024     * Calculates the size of the LocalVariableTable.
2025     */
2026    public int getLVTSize() {
2027        int result = varBufferSize;
2028        for (int i = 0; i < varBufferSize; i++) {
2029            LocalVar var = varBuffer[i];
2030            result += var.aliveRanges.size() - 1;
2031        }
2032        return result;
2033    }
2034
2035    /** Set the current variable defined state. */
2036    public void setDefined(Bits newDefined) {
2037        if (alive && newDefined != state.defined) {
2038            Bits diff = new Bits(state.defined).xorSet(newDefined);
2039            for (int adr = diff.nextBit(0);
2040                 adr >= 0;
2041                 adr = diff.nextBit(adr+1)) {
2042                if (adr >= nextreg)
2043                    state.defined.excl(adr);
2044                else if (state.defined.isMember(adr))
2045                    setUndefined(adr);
2046                else
2047                    setDefined(adr);
2048            }
2049        }
2050    }
2051
2052    /** Mark a register as being (possibly) defined. */
2053    public void setDefined(int adr) {
2054        LocalVar v = lvar[adr];
2055        if (v == null) {
2056            state.defined.excl(adr);
2057        } else {
2058            state.defined.incl(adr);
2059            if (cp < Character.MAX_VALUE) {
2060                v.openRange((char)cp);
2061            }
2062        }
2063    }
2064
2065    /** Mark a register as being undefined. */
2066    public void setUndefined(int adr) {
2067        state.defined.excl(adr);
2068        if (adr < lvar.length &&
2069            lvar[adr] != null &&
2070            lvar[adr].isLastRangeInitialized()) {
2071            LocalVar v = lvar[adr];
2072            char length = (char)(curCP() - v.lastRange().start_pc);
2073            if (length < Character.MAX_VALUE) {
2074                lvar[adr] = v.dup();
2075                v.closeRange(length);
2076                putVar(v);
2077            } else {
2078                v.removeLastRange();
2079            }
2080        }
2081    }
2082
2083    /** End the scope of a variable. */
2084    private void endScope(int adr) {
2085        LocalVar v = lvar[adr];
2086        if (v != null) {
2087            if (v.isLastRangeInitialized()) {
2088                char length = (char)(curCP() - v.lastRange().start_pc);
2089                if (length < Character.MAX_VALUE) {
2090                    v.closeRange(length);
2091                    putVar(v);
2092                    fillLocalVarPosition(v);
2093                }
2094            }
2095            /** the call to curCP() can implicitly adjust the current cp, if so
2096             * the alive range of local variables may be modified. Thus we need
2097             * all of them. For this reason assigning null to the given address
2098             * should be the last action to do.
2099             */
2100            lvar[adr] = null;
2101        }
2102        state.defined.excl(adr);
2103    }
2104
2105    private void fillLocalVarPosition(LocalVar lv) {
2106        if (lv == null || lv.sym == null || !lv.sym.hasTypeAnnotations())
2107            return;
2108        for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
2109            TypeAnnotationPosition p = ta.position;
2110            LocalVar.Range widestRange = lv.getWidestRange();
2111            p.lvarOffset = new int[] { (int)widestRange.start_pc };
2112            p.lvarLength = new int[] { (int)widestRange.length };
2113            p.lvarIndex = new int[] { (int)lv.reg };
2114            p.isValidOffset = true;
2115        }
2116    }
2117
2118    // Method to be called after compressCatchTable to
2119    // fill in the exception table index for type
2120    // annotations on exception parameters.
2121    public void fillExceptionParameterPositions() {
2122        for (int i = 0; i < varBufferSize; ++i) {
2123            LocalVar lv = varBuffer[i];
2124            if (lv == null || lv.sym == null
2125                    || !lv.sym.hasTypeAnnotations()
2126                    || !lv.sym.isExceptionParameter())
2127                continue;
2128
2129            for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
2130                TypeAnnotationPosition p = ta.position;
2131                if (p.hasCatchType()) {
2132                    final int idx = findExceptionIndex(p);
2133                    if (idx == -1)
2134                        Assert.error("Could not find exception index for type annotation " +
2135                                     ta + " on exception parameter");
2136                    p.setExceptionIndex(idx);
2137                }
2138            }
2139        }
2140    }
2141
2142    private int findExceptionIndex(TypeAnnotationPosition p) {
2143        final int catchType = p.getCatchType();
2144        final int startPos = p.getStartPos();
2145        final int len = catchInfo.length();
2146        List<char[]> iter = catchInfo.toList();
2147        for (int i = 0; i < len; ++i) {
2148            char[] catchEntry = iter.head;
2149            iter = iter.tail;
2150            int ct = catchEntry[3];
2151            int sp = catchEntry[0];
2152            if (catchType == ct && sp == startPos) {
2153                return i;
2154            }
2155        }
2156        return -1;
2157    }
2158
2159    /** Put a live variable range into the buffer to be output to the
2160     *  class file.
2161     */
2162    void putVar(LocalVar var) {
2163        // Keep local variables if
2164        // 1) we need them for debug information
2165        // 2) it is an exception type and it contains type annotations
2166        boolean keepLocalVariables = varDebugInfo ||
2167            (var.sym.isExceptionParameter() && var.sym.hasTypeAnnotations());
2168        if (!keepLocalVariables) return;
2169        if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return;
2170        if (varBuffer == null)
2171            varBuffer = new LocalVar[20];
2172        else
2173            varBuffer = ArrayUtils.ensureCapacity(varBuffer, varBufferSize);
2174        varBuffer[varBufferSize++] = var;
2175    }
2176
2177    /** Previously live local variables, to be put into the variable table. */
2178    LocalVar[] varBuffer;
2179    int varBufferSize;
2180
2181    /** Create a new local variable address and return it.
2182     */
2183    private int newLocal(int typecode) {
2184        int reg = nextreg;
2185        int w = width(typecode);
2186        nextreg = reg + w;
2187        if (nextreg > max_locals) max_locals = nextreg;
2188        return reg;
2189    }
2190
2191    private int newLocal(Type type) {
2192        return newLocal(typecode(type));
2193    }
2194
2195    public int newLocal(VarSymbol v) {
2196        int reg = v.adr = newLocal(v.erasure(types));
2197        addLocalVar(v);
2198        return reg;
2199    }
2200
2201    /** Start a set of fresh registers.
2202     */
2203    public void newRegSegment() {
2204        nextreg = max_locals;
2205    }
2206
2207    /** End scopes of all variables with registers &ge; first.
2208     */
2209    public void endScopes(int first) {
2210        int prevNextReg = nextreg;
2211        nextreg = first;
2212        for (int i = nextreg; i < prevNextReg; i++) endScope(i);
2213    }
2214
2215/**************************************************************************
2216 * static tables
2217 *************************************************************************/
2218
2219    public static String mnem(int opcode) {
2220        return Mneumonics.mnem[opcode];
2221    }
2222
2223    private static class Mneumonics {
2224        private final static String[] mnem = new String[ByteCodeCount];
2225        static {
2226            mnem[nop] = "nop";
2227            mnem[aconst_null] = "aconst_null";
2228            mnem[iconst_m1] = "iconst_m1";
2229            mnem[iconst_0] = "iconst_0";
2230            mnem[iconst_1] = "iconst_1";
2231            mnem[iconst_2] = "iconst_2";
2232            mnem[iconst_3] = "iconst_3";
2233            mnem[iconst_4] = "iconst_4";
2234            mnem[iconst_5] = "iconst_5";
2235            mnem[lconst_0] = "lconst_0";
2236            mnem[lconst_1] = "lconst_1";
2237            mnem[fconst_0] = "fconst_0";
2238            mnem[fconst_1] = "fconst_1";
2239            mnem[fconst_2] = "fconst_2";
2240            mnem[dconst_0] = "dconst_0";
2241            mnem[dconst_1] = "dconst_1";
2242            mnem[bipush] = "bipush";
2243            mnem[sipush] = "sipush";
2244            mnem[ldc1] = "ldc1";
2245            mnem[ldc2] = "ldc2";
2246            mnem[ldc2w] = "ldc2w";
2247            mnem[iload] = "iload";
2248            mnem[lload] = "lload";
2249            mnem[fload] = "fload";
2250            mnem[dload] = "dload";
2251            mnem[aload] = "aload";
2252            mnem[iload_0] = "iload_0";
2253            mnem[lload_0] = "lload_0";
2254            mnem[fload_0] = "fload_0";
2255            mnem[dload_0] = "dload_0";
2256            mnem[aload_0] = "aload_0";
2257            mnem[iload_1] = "iload_1";
2258            mnem[lload_1] = "lload_1";
2259            mnem[fload_1] = "fload_1";
2260            mnem[dload_1] = "dload_1";
2261            mnem[aload_1] = "aload_1";
2262            mnem[iload_2] = "iload_2";
2263            mnem[lload_2] = "lload_2";
2264            mnem[fload_2] = "fload_2";
2265            mnem[dload_2] = "dload_2";
2266            mnem[aload_2] = "aload_2";
2267            mnem[iload_3] = "iload_3";
2268            mnem[lload_3] = "lload_3";
2269            mnem[fload_3] = "fload_3";
2270            mnem[dload_3] = "dload_3";
2271            mnem[aload_3] = "aload_3";
2272            mnem[iaload] = "iaload";
2273            mnem[laload] = "laload";
2274            mnem[faload] = "faload";
2275            mnem[daload] = "daload";
2276            mnem[aaload] = "aaload";
2277            mnem[baload] = "baload";
2278            mnem[caload] = "caload";
2279            mnem[saload] = "saload";
2280            mnem[istore] = "istore";
2281            mnem[lstore] = "lstore";
2282            mnem[fstore] = "fstore";
2283            mnem[dstore] = "dstore";
2284            mnem[astore] = "astore";
2285            mnem[istore_0] = "istore_0";
2286            mnem[lstore_0] = "lstore_0";
2287            mnem[fstore_0] = "fstore_0";
2288            mnem[dstore_0] = "dstore_0";
2289            mnem[astore_0] = "astore_0";
2290            mnem[istore_1] = "istore_1";
2291            mnem[lstore_1] = "lstore_1";
2292            mnem[fstore_1] = "fstore_1";
2293            mnem[dstore_1] = "dstore_1";
2294            mnem[astore_1] = "astore_1";
2295            mnem[istore_2] = "istore_2";
2296            mnem[lstore_2] = "lstore_2";
2297            mnem[fstore_2] = "fstore_2";
2298            mnem[dstore_2] = "dstore_2";
2299            mnem[astore_2] = "astore_2";
2300            mnem[istore_3] = "istore_3";
2301            mnem[lstore_3] = "lstore_3";
2302            mnem[fstore_3] = "fstore_3";
2303            mnem[dstore_3] = "dstore_3";
2304            mnem[astore_3] = "astore_3";
2305            mnem[iastore] = "iastore";
2306            mnem[lastore] = "lastore";
2307            mnem[fastore] = "fastore";
2308            mnem[dastore] = "dastore";
2309            mnem[aastore] = "aastore";
2310            mnem[bastore] = "bastore";
2311            mnem[castore] = "castore";
2312            mnem[sastore] = "sastore";
2313            mnem[pop] = "pop";
2314            mnem[pop2] = "pop2";
2315            mnem[dup] = "dup";
2316            mnem[dup_x1] = "dup_x1";
2317            mnem[dup_x2] = "dup_x2";
2318            mnem[dup2] = "dup2";
2319            mnem[dup2_x1] = "dup2_x1";
2320            mnem[dup2_x2] = "dup2_x2";
2321            mnem[swap] = "swap";
2322            mnem[iadd] = "iadd";
2323            mnem[ladd] = "ladd";
2324            mnem[fadd] = "fadd";
2325            mnem[dadd] = "dadd";
2326            mnem[isub] = "isub";
2327            mnem[lsub] = "lsub";
2328            mnem[fsub] = "fsub";
2329            mnem[dsub] = "dsub";
2330            mnem[imul] = "imul";
2331            mnem[lmul] = "lmul";
2332            mnem[fmul] = "fmul";
2333            mnem[dmul] = "dmul";
2334            mnem[idiv] = "idiv";
2335            mnem[ldiv] = "ldiv";
2336            mnem[fdiv] = "fdiv";
2337            mnem[ddiv] = "ddiv";
2338            mnem[imod] = "imod";
2339            mnem[lmod] = "lmod";
2340            mnem[fmod] = "fmod";
2341            mnem[dmod] = "dmod";
2342            mnem[ineg] = "ineg";
2343            mnem[lneg] = "lneg";
2344            mnem[fneg] = "fneg";
2345            mnem[dneg] = "dneg";
2346            mnem[ishl] = "ishl";
2347            mnem[lshl] = "lshl";
2348            mnem[ishr] = "ishr";
2349            mnem[lshr] = "lshr";
2350            mnem[iushr] = "iushr";
2351            mnem[lushr] = "lushr";
2352            mnem[iand] = "iand";
2353            mnem[land] = "land";
2354            mnem[ior] = "ior";
2355            mnem[lor] = "lor";
2356            mnem[ixor] = "ixor";
2357            mnem[lxor] = "lxor";
2358            mnem[iinc] = "iinc";
2359            mnem[i2l] = "i2l";
2360            mnem[i2f] = "i2f";
2361            mnem[i2d] = "i2d";
2362            mnem[l2i] = "l2i";
2363            mnem[l2f] = "l2f";
2364            mnem[l2d] = "l2d";
2365            mnem[f2i] = "f2i";
2366            mnem[f2l] = "f2l";
2367            mnem[f2d] = "f2d";
2368            mnem[d2i] = "d2i";
2369            mnem[d2l] = "d2l";
2370            mnem[d2f] = "d2f";
2371            mnem[int2byte] = "int2byte";
2372            mnem[int2char] = "int2char";
2373            mnem[int2short] = "int2short";
2374            mnem[lcmp] = "lcmp";
2375            mnem[fcmpl] = "fcmpl";
2376            mnem[fcmpg] = "fcmpg";
2377            mnem[dcmpl] = "dcmpl";
2378            mnem[dcmpg] = "dcmpg";
2379            mnem[ifeq] = "ifeq";
2380            mnem[ifne] = "ifne";
2381            mnem[iflt] = "iflt";
2382            mnem[ifge] = "ifge";
2383            mnem[ifgt] = "ifgt";
2384            mnem[ifle] = "ifle";
2385            mnem[if_icmpeq] = "if_icmpeq";
2386            mnem[if_icmpne] = "if_icmpne";
2387            mnem[if_icmplt] = "if_icmplt";
2388            mnem[if_icmpge] = "if_icmpge";
2389            mnem[if_icmpgt] = "if_icmpgt";
2390            mnem[if_icmple] = "if_icmple";
2391            mnem[if_acmpeq] = "if_acmpeq";
2392            mnem[if_acmpne] = "if_acmpne";
2393            mnem[goto_] = "goto_";
2394            mnem[jsr] = "jsr";
2395            mnem[ret] = "ret";
2396            mnem[tableswitch] = "tableswitch";
2397            mnem[lookupswitch] = "lookupswitch";
2398            mnem[ireturn] = "ireturn";
2399            mnem[lreturn] = "lreturn";
2400            mnem[freturn] = "freturn";
2401            mnem[dreturn] = "dreturn";
2402            mnem[areturn] = "areturn";
2403            mnem[return_] = "return_";
2404            mnem[getstatic] = "getstatic";
2405            mnem[putstatic] = "putstatic";
2406            mnem[getfield] = "getfield";
2407            mnem[putfield] = "putfield";
2408            mnem[invokevirtual] = "invokevirtual";
2409            mnem[invokespecial] = "invokespecial";
2410            mnem[invokestatic] = "invokestatic";
2411            mnem[invokeinterface] = "invokeinterface";
2412            mnem[invokedynamic] = "invokedynamic";
2413            mnem[new_] = "new_";
2414            mnem[newarray] = "newarray";
2415            mnem[anewarray] = "anewarray";
2416            mnem[arraylength] = "arraylength";
2417            mnem[athrow] = "athrow";
2418            mnem[checkcast] = "checkcast";
2419            mnem[instanceof_] = "instanceof_";
2420            mnem[monitorenter] = "monitorenter";
2421            mnem[monitorexit] = "monitorexit";
2422            mnem[wide] = "wide";
2423            mnem[multianewarray] = "multianewarray";
2424            mnem[if_acmp_null] = "if_acmp_null";
2425            mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2426            mnem[goto_w] = "goto_w";
2427            mnem[jsr_w] = "jsr_w";
2428            mnem[breakpoint] = "breakpoint";
2429        }
2430    }
2431}
2432