Code.java revision 2869:82a435ed8d1a
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            Assert.check(!a.hasTag(BOT)); // null type as is cannot be indexed.
501            state.pop(1);
502            state.push(types.erasure(types.elemtype(a))); }
503            break;
504        case goto_:
505            markDead();
506            break;
507        case nop:
508        case ineg:
509        case lneg:
510        case fneg:
511        case dneg:
512            break;
513        case aconst_null:
514            state.push(syms.botType);
515            break;
516        case iconst_m1:
517        case iconst_0:
518        case iconst_1:
519        case iconst_2:
520        case iconst_3:
521        case iconst_4:
522        case iconst_5:
523        case iload_0:
524        case iload_1:
525        case iload_2:
526        case iload_3:
527            state.push(syms.intType);
528            break;
529        case lconst_0:
530        case lconst_1:
531        case lload_0:
532        case lload_1:
533        case lload_2:
534        case lload_3:
535            state.push(syms.longType);
536            break;
537        case fconst_0:
538        case fconst_1:
539        case fconst_2:
540        case fload_0:
541        case fload_1:
542        case fload_2:
543        case fload_3:
544            state.push(syms.floatType);
545            break;
546        case dconst_0:
547        case dconst_1:
548        case dload_0:
549        case dload_1:
550        case dload_2:
551        case dload_3:
552            state.push(syms.doubleType);
553            break;
554        case aload_0:
555            state.push(lvar[0].sym.type);
556            break;
557        case aload_1:
558            state.push(lvar[1].sym.type);
559            break;
560        case aload_2:
561            state.push(lvar[2].sym.type);
562            break;
563        case aload_3:
564            state.push(lvar[3].sym.type);
565            break;
566        case iaload:
567        case baload:
568        case caload:
569        case saload:
570            state.pop(2);
571            state.push(syms.intType);
572            break;
573        case laload:
574            state.pop(2);
575            state.push(syms.longType);
576            break;
577        case faload:
578            state.pop(2);
579            state.push(syms.floatType);
580            break;
581        case daload:
582            state.pop(2);
583            state.push(syms.doubleType);
584            break;
585        case istore_0:
586        case istore_1:
587        case istore_2:
588        case istore_3:
589        case fstore_0:
590        case fstore_1:
591        case fstore_2:
592        case fstore_3:
593        case astore_0:
594        case astore_1:
595        case astore_2:
596        case astore_3:
597        case pop:
598        case lshr:
599        case lshl:
600        case lushr:
601            state.pop(1);
602            break;
603        case areturn:
604        case ireturn:
605        case freturn:
606            Assert.check(state.nlocks == 0);
607            state.pop(1);
608            markDead();
609            break;
610        case athrow:
611            state.pop(1);
612            markDead();
613            break;
614        case lstore_0:
615        case lstore_1:
616        case lstore_2:
617        case lstore_3:
618        case dstore_0:
619        case dstore_1:
620        case dstore_2:
621        case dstore_3:
622        case pop2:
623            state.pop(2);
624            break;
625        case lreturn:
626        case dreturn:
627            Assert.check(state.nlocks == 0);
628            state.pop(2);
629            markDead();
630            break;
631        case dup:
632            state.push(state.stack[state.stacksize-1]);
633            break;
634        case return_:
635            Assert.check(state.nlocks == 0);
636            markDead();
637            break;
638        case arraylength:
639            state.pop(1);
640            state.push(syms.intType);
641            break;
642        case isub:
643        case iadd:
644        case imul:
645        case idiv:
646        case imod:
647        case ishl:
648        case ishr:
649        case iushr:
650        case iand:
651        case ior:
652        case ixor:
653            state.pop(1);
654            // state.pop(1);
655            // state.push(syms.intType);
656            break;
657        case aastore:
658            state.pop(3);
659            break;
660        case land:
661        case lor:
662        case lxor:
663        case lmod:
664        case ldiv:
665        case lmul:
666        case lsub:
667        case ladd:
668            state.pop(2);
669            break;
670        case lcmp:
671            state.pop(4);
672            state.push(syms.intType);
673            break;
674        case l2i:
675            state.pop(2);
676            state.push(syms.intType);
677            break;
678        case i2l:
679            state.pop(1);
680            state.push(syms.longType);
681            break;
682        case i2f:
683            state.pop(1);
684            state.push(syms.floatType);
685            break;
686        case i2d:
687            state.pop(1);
688            state.push(syms.doubleType);
689            break;
690        case l2f:
691            state.pop(2);
692            state.push(syms.floatType);
693            break;
694        case l2d:
695            state.pop(2);
696            state.push(syms.doubleType);
697            break;
698        case f2i:
699            state.pop(1);
700            state.push(syms.intType);
701            break;
702        case f2l:
703            state.pop(1);
704            state.push(syms.longType);
705            break;
706        case f2d:
707            state.pop(1);
708            state.push(syms.doubleType);
709            break;
710        case d2i:
711            state.pop(2);
712            state.push(syms.intType);
713            break;
714        case d2l:
715            state.pop(2);
716            state.push(syms.longType);
717            break;
718        case d2f:
719            state.pop(2);
720            state.push(syms.floatType);
721            break;
722        case tableswitch:
723        case lookupswitch:
724            state.pop(1);
725            // the caller is responsible for patching up the state
726            break;
727        case dup_x1: {
728            Type val1 = state.pop1();
729            Type val2 = state.pop1();
730            state.push(val1);
731            state.push(val2);
732            state.push(val1);
733            break;
734        }
735        case bastore:
736            state.pop(3);
737            break;
738        case int2byte:
739        case int2char:
740        case int2short:
741            break;
742        case fmul:
743        case fadd:
744        case fsub:
745        case fdiv:
746        case fmod:
747            state.pop(1);
748            break;
749        case castore:
750        case iastore:
751        case fastore:
752        case sastore:
753            state.pop(3);
754            break;
755        case lastore:
756        case dastore:
757            state.pop(4);
758            break;
759        case dup2:
760            if (state.stack[state.stacksize-1] != null) {
761                Type value1 = state.pop1();
762                Type value2 = state.pop1();
763                state.push(value2);
764                state.push(value1);
765                state.push(value2);
766                state.push(value1);
767            } else {
768                Type value = state.pop2();
769                state.push(value);
770                state.push(value);
771            }
772            break;
773        case dup2_x1:
774            if (state.stack[state.stacksize-1] != null) {
775                Type value1 = state.pop1();
776                Type value2 = state.pop1();
777                Type value3 = state.pop1();
778                state.push(value2);
779                state.push(value1);
780                state.push(value3);
781                state.push(value2);
782                state.push(value1);
783            } else {
784                Type value1 = state.pop2();
785                Type value2 = state.pop1();
786                state.push(value1);
787                state.push(value2);
788                state.push(value1);
789            }
790            break;
791        case dup2_x2:
792            if (state.stack[state.stacksize-1] != null) {
793                Type value1 = state.pop1();
794                Type value2 = state.pop1();
795                if (state.stack[state.stacksize-1] != null) {
796                    // form 1
797                    Type value3 = state.pop1();
798                    Type value4 = state.pop1();
799                    state.push(value2);
800                    state.push(value1);
801                    state.push(value4);
802                    state.push(value3);
803                    state.push(value2);
804                    state.push(value1);
805                } else {
806                    // form 3
807                    Type value3 = state.pop2();
808                    state.push(value2);
809                    state.push(value1);
810                    state.push(value3);
811                    state.push(value2);
812                    state.push(value1);
813                }
814            } else {
815                Type value1 = state.pop2();
816                if (state.stack[state.stacksize-1] != null) {
817                    // form 2
818                    Type value2 = state.pop1();
819                    Type value3 = state.pop1();
820                    state.push(value1);
821                    state.push(value3);
822                    state.push(value2);
823                    state.push(value1);
824                } else {
825                    // form 4
826                    Type value2 = state.pop2();
827                    state.push(value1);
828                    state.push(value2);
829                    state.push(value1);
830                }
831            }
832            break;
833        case dup_x2: {
834            Type value1 = state.pop1();
835            if (state.stack[state.stacksize-1] != null) {
836                // form 1
837                Type value2 = state.pop1();
838                Type value3 = state.pop1();
839                state.push(value1);
840                state.push(value3);
841                state.push(value2);
842                state.push(value1);
843            } else {
844                // form 2
845                Type value2 = state.pop2();
846                state.push(value1);
847                state.push(value2);
848                state.push(value1);
849            }
850        }
851            break;
852        case fcmpl:
853        case fcmpg:
854            state.pop(2);
855            state.push(syms.intType);
856            break;
857        case dcmpl:
858        case dcmpg:
859            state.pop(4);
860            state.push(syms.intType);
861            break;
862        case swap: {
863            Type value1 = state.pop1();
864            Type value2 = state.pop1();
865            state.push(value1);
866            state.push(value2);
867            break;
868        }
869        case dadd:
870        case dsub:
871        case dmul:
872        case ddiv:
873        case dmod:
874            state.pop(2);
875            break;
876        case ret:
877            markDead();
878            break;
879        case wide:
880            // must be handled by the caller.
881            return;
882        case monitorenter:
883        case monitorexit:
884            state.pop(1);
885            break;
886
887        default:
888            throw new AssertionError(mnem(op));
889        }
890        postop();
891    }
892
893    /** Emit an opcode with a one-byte operand field.
894     */
895    public void emitop1(int op, int od) {
896        emitop(op);
897        if (!alive) return;
898        emit1(od);
899        switch (op) {
900        case bipush:
901            state.push(syms.intType);
902            break;
903        case ldc1:
904            state.push(typeForPool(pool.pool[od]));
905            break;
906        default:
907            throw new AssertionError(mnem(op));
908        }
909        postop();
910    }
911
912    /** The type of a constant pool entry. */
913    private Type typeForPool(Object o) {
914        if (o instanceof Integer) return syms.intType;
915        if (o instanceof Float) return syms.floatType;
916        if (o instanceof String) return syms.stringType;
917        if (o instanceof Long) return syms.longType;
918        if (o instanceof Double) return syms.doubleType;
919        if (o instanceof ClassSymbol) return syms.classType;
920        if (o instanceof Pool.MethodHandle) return syms.methodHandleType;
921        if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type);
922        if (o instanceof Type) {
923            Type ty = (Type) o;
924
925            if (ty instanceof Type.ArrayType) return syms.classType;
926            if (ty instanceof Type.MethodType) return syms.methodTypeType;
927        }
928        throw new AssertionError("Invalid type of constant pool entry: " + o.getClass());
929    }
930
931    /** Emit an opcode with a one-byte operand field;
932     *  widen if field does not fit in a byte.
933     */
934    public void emitop1w(int op, int od) {
935        if (od > 0xFF) {
936            emitop(wide);
937            emitop(op);
938            emit2(od);
939        } else {
940            emitop(op);
941            emit1(od);
942        }
943        if (!alive) return;
944        switch (op) {
945        case iload:
946            state.push(syms.intType);
947            break;
948        case lload:
949            state.push(syms.longType);
950            break;
951        case fload:
952            state.push(syms.floatType);
953            break;
954        case dload:
955            state.push(syms.doubleType);
956            break;
957        case aload:
958            state.push(lvar[od].sym.type);
959            break;
960        case lstore:
961        case dstore:
962            state.pop(2);
963            break;
964        case istore:
965        case fstore:
966        case astore:
967            state.pop(1);
968            break;
969        case ret:
970            markDead();
971            break;
972        default:
973            throw new AssertionError(mnem(op));
974        }
975        postop();
976    }
977
978    /** Emit an opcode with two one-byte operand fields;
979     *  widen if either field does not fit in a byte.
980     */
981    public void emitop1w(int op, int od1, int od2) {
982        if (od1 > 0xFF || od2 < -128 || od2 > 127) {
983            emitop(wide);
984            emitop(op);
985            emit2(od1);
986            emit2(od2);
987        } else {
988            emitop(op);
989            emit1(od1);
990            emit1(od2);
991        }
992        if (!alive) return;
993        switch (op) {
994        case iinc:
995            break;
996        default:
997            throw new AssertionError(mnem(op));
998        }
999    }
1000
1001    /** Emit an opcode with a two-byte operand field.
1002     */
1003    public void emitop2(int op, int od) {
1004        emitop(op);
1005        if (!alive) return;
1006        emit2(od);
1007        switch (op) {
1008        case getstatic:
1009            state.push(((Symbol)(pool.pool[od])).erasure(types));
1010            break;
1011        case putstatic:
1012            state.pop(((Symbol)(pool.pool[od])).erasure(types));
1013            break;
1014        case new_:
1015            Symbol sym;
1016            if (pool.pool[od] instanceof UniqueType) {
1017                // Required by change in Gen.makeRef to allow
1018                // annotated types.
1019                // TODO: is this needed anywhere else?
1020                sym = ((UniqueType)(pool.pool[od])).type.tsym;
1021            } else {
1022                sym = (Symbol)(pool.pool[od]);
1023            }
1024            state.push(uninitializedObject(sym.erasure(types), cp-3));
1025            break;
1026        case sipush:
1027            state.push(syms.intType);
1028            break;
1029        case if_acmp_null:
1030        case if_acmp_nonnull:
1031        case ifeq:
1032        case ifne:
1033        case iflt:
1034        case ifge:
1035        case ifgt:
1036        case ifle:
1037            state.pop(1);
1038            break;
1039        case if_icmpeq:
1040        case if_icmpne:
1041        case if_icmplt:
1042        case if_icmpge:
1043        case if_icmpgt:
1044        case if_icmple:
1045        case if_acmpeq:
1046        case if_acmpne:
1047            state.pop(2);
1048            break;
1049        case goto_:
1050            markDead();
1051            break;
1052        case putfield:
1053            state.pop(((Symbol)(pool.pool[od])).erasure(types));
1054            state.pop(1); // object ref
1055            break;
1056        case getfield:
1057            state.pop(1); // object ref
1058            state.push(((Symbol)(pool.pool[od])).erasure(types));
1059            break;
1060        case checkcast: {
1061            state.pop(1); // object ref
1062            Object o = pool.pool[od];
1063            Type t = (o instanceof Symbol)
1064                ? ((Symbol)o).erasure(types)
1065                : types.erasure((((UniqueType)o).type));
1066            state.push(t);
1067            break; }
1068        case ldc2w:
1069            state.push(typeForPool(pool.pool[od]));
1070            break;
1071        case instanceof_:
1072            state.pop(1);
1073            state.push(syms.intType);
1074            break;
1075        case ldc2:
1076            state.push(typeForPool(pool.pool[od]));
1077            break;
1078        case jsr:
1079            break;
1080        default:
1081            throw new AssertionError(mnem(op));
1082        }
1083        // postop();
1084    }
1085
1086    /** Emit an opcode with a four-byte operand field.
1087     */
1088    public void emitop4(int op, int od) {
1089        emitop(op);
1090        if (!alive) return;
1091        emit4(od);
1092        switch (op) {
1093        case goto_w:
1094            markDead();
1095            break;
1096        case jsr_w:
1097            break;
1098        default:
1099            throw new AssertionError(mnem(op));
1100        }
1101        // postop();
1102    }
1103
1104    /** Align code pointer to next `incr' boundary.
1105     */
1106    public void align(int incr) {
1107        if (alive)
1108            while (cp % incr != 0) emitop0(nop);
1109    }
1110
1111    /** Place a byte into code at address pc.
1112     *  Pre: {@literal pc + 1 <= cp }.
1113     */
1114    private void put1(int pc, int op) {
1115        code[pc] = (byte)op;
1116    }
1117
1118    /** Place two bytes into code at address pc.
1119     *  Pre: {@literal pc + 2 <= cp }.
1120     */
1121    private void put2(int pc, int od) {
1122        // pre: pc + 2 <= cp
1123        put1(pc, od >> 8);
1124        put1(pc+1, od);
1125    }
1126
1127    /** Place four  bytes into code at address pc.
1128     *  Pre: {@literal pc + 4 <= cp }.
1129     */
1130    public void put4(int pc, int od) {
1131        // pre: pc + 4 <= cp
1132        put1(pc  , od >> 24);
1133        put1(pc+1, od >> 16);
1134        put1(pc+2, od >> 8);
1135        put1(pc+3, od);
1136    }
1137
1138    /** Return code byte at position pc as an unsigned int.
1139     */
1140    private int get1(int pc) {
1141        return code[pc] & 0xFF;
1142    }
1143
1144    /** Return two code bytes at position pc as an unsigned int.
1145     */
1146    private int get2(int pc) {
1147        return (get1(pc) << 8) | get1(pc+1);
1148    }
1149
1150    /** Return four code bytes at position pc as an int.
1151     */
1152    public int get4(int pc) {
1153        // pre: pc + 4 <= cp
1154        return
1155            (get1(pc) << 24) |
1156            (get1(pc+1) << 16) |
1157            (get1(pc+2) << 8) |
1158            (get1(pc+3));
1159    }
1160
1161    /** Is code generation currently enabled?
1162     */
1163    public boolean isAlive() {
1164        return alive || pendingJumps != null;
1165    }
1166
1167    /** Switch code generation on/off.
1168     */
1169    public void markDead() {
1170        alive = false;
1171    }
1172
1173    /** Declare an entry point; return current code pointer
1174     */
1175    public int entryPoint() {
1176        int pc = curCP();
1177        alive = true;
1178        pendingStackMap = needStackMap;
1179        return pc;
1180    }
1181
1182    /** Declare an entry point with initial state;
1183     *  return current code pointer
1184     */
1185    public int entryPoint(State state) {
1186        int pc = curCP();
1187        alive = true;
1188        State newState = state.dup();
1189        setDefined(newState.defined);
1190        this.state = newState;
1191        Assert.check(state.stacksize <= max_stack);
1192        if (debugCode) System.err.println("entry point " + state);
1193        pendingStackMap = needStackMap;
1194        return pc;
1195    }
1196
1197    /** Declare an entry point with initial state plus a pushed value;
1198     *  return current code pointer
1199     */
1200    public int entryPoint(State state, Type pushed) {
1201        int pc = curCP();
1202        alive = true;
1203        State newState = state.dup();
1204        setDefined(newState.defined);
1205        this.state = newState;
1206        Assert.check(state.stacksize <= max_stack);
1207        this.state.push(pushed);
1208        if (debugCode) System.err.println("entry point " + state);
1209        pendingStackMap = needStackMap;
1210        return pc;
1211    }
1212
1213
1214/**************************************************************************
1215 * Stack map generation
1216 *************************************************************************/
1217
1218    /** An entry in the stack map. */
1219    static class StackMapFrame {
1220        int pc;
1221        Type[] locals;
1222        Type[] stack;
1223    }
1224
1225    /** A buffer of cldc stack map entries. */
1226    StackMapFrame[] stackMapBuffer = null;
1227
1228    /** A buffer of compressed StackMapTable entries. */
1229    StackMapTableFrame[] stackMapTableBuffer = null;
1230    int stackMapBufferSize = 0;
1231
1232    /** The last PC at which we generated a stack map. */
1233    int lastStackMapPC = -1;
1234
1235    /** The last stack map frame in StackMapTable. */
1236    StackMapFrame lastFrame = null;
1237
1238    /** The stack map frame before the last one. */
1239    StackMapFrame frameBeforeLast = null;
1240
1241    /** Emit a stack map entry.  */
1242    public void emitStackMap() {
1243        int pc = curCP();
1244        if (!needStackMap) return;
1245
1246
1247
1248        switch (stackMap) {
1249            case CLDC:
1250                emitCLDCStackMap(pc, getLocalsSize());
1251                break;
1252            case JSR202:
1253                emitStackMapFrame(pc, getLocalsSize());
1254                break;
1255            default:
1256                throw new AssertionError("Should have chosen a stackmap format");
1257        }
1258        // DEBUG code follows
1259        if (debugCode) state.dump(pc);
1260    }
1261
1262    private int getLocalsSize() {
1263        int nextLocal = 0;
1264        for (int i=max_locals-1; i>=0; i--) {
1265            if (state.defined.isMember(i) && lvar[i] != null) {
1266                nextLocal = i + width(lvar[i].sym.erasure(types));
1267                break;
1268            }
1269        }
1270        return nextLocal;
1271    }
1272
1273    /** Emit a CLDC stack map frame. */
1274    void emitCLDCStackMap(int pc, int localsSize) {
1275        if (lastStackMapPC == pc) {
1276            // drop existing stackmap at this offset
1277            stackMapBuffer[--stackMapBufferSize] = null;
1278        }
1279        lastStackMapPC = pc;
1280
1281        if (stackMapBuffer == null) {
1282            stackMapBuffer = new StackMapFrame[20];
1283        } else {
1284            stackMapBuffer = ArrayUtils.ensureCapacity(stackMapBuffer, stackMapBufferSize);
1285        }
1286        StackMapFrame frame =
1287            stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
1288        frame.pc = pc;
1289
1290        frame.locals = new Type[localsSize];
1291        for (int i=0; i<localsSize; i++) {
1292            if (state.defined.isMember(i) && lvar[i] != null) {
1293                Type vtype = lvar[i].sym.type;
1294                if (!(vtype instanceof UninitializedType))
1295                    vtype = types.erasure(vtype);
1296                frame.locals[i] = vtype;
1297            }
1298        }
1299        frame.stack = new Type[state.stacksize];
1300        for (int i=0; i<state.stacksize; i++)
1301            frame.stack[i] = state.stack[i];
1302    }
1303
1304    void emitStackMapFrame(int pc, int localsSize) {
1305        if (lastFrame == null) {
1306            // first frame
1307            lastFrame = getInitialFrame();
1308        } else if (lastFrame.pc == pc) {
1309            // drop existing stackmap at this offset
1310            stackMapTableBuffer[--stackMapBufferSize] = null;
1311            lastFrame = frameBeforeLast;
1312            frameBeforeLast = null;
1313        }
1314
1315        StackMapFrame frame = new StackMapFrame();
1316        frame.pc = pc;
1317
1318        int localCount = 0;
1319        Type[] locals = new Type[localsSize];
1320        for (int i=0; i<localsSize; i++, localCount++) {
1321            if (state.defined.isMember(i) && lvar[i] != null) {
1322                Type vtype = lvar[i].sym.type;
1323                if (!(vtype instanceof UninitializedType))
1324                    vtype = types.erasure(vtype);
1325                locals[i] = vtype;
1326                if (width(vtype) > 1) i++;
1327            }
1328        }
1329        frame.locals = new Type[localCount];
1330        for (int i=0, j=0; i<localsSize; i++, j++) {
1331            Assert.check(j < localCount);
1332            frame.locals[j] = locals[i];
1333            if (width(locals[i]) > 1) i++;
1334        }
1335
1336        int stackCount = 0;
1337        for (int i=0; i<state.stacksize; i++) {
1338            if (state.stack[i] != null) {
1339                stackCount++;
1340            }
1341        }
1342        frame.stack = new Type[stackCount];
1343        stackCount = 0;
1344        for (int i=0; i<state.stacksize; i++) {
1345            if (state.stack[i] != null) {
1346                frame.stack[stackCount++] = types.erasure(state.stack[i]);
1347            }
1348        }
1349
1350        if (stackMapTableBuffer == null) {
1351            stackMapTableBuffer = new StackMapTableFrame[20];
1352        } else {
1353            stackMapTableBuffer = ArrayUtils.ensureCapacity(
1354                                    stackMapTableBuffer,
1355                                    stackMapBufferSize);
1356        }
1357        stackMapTableBuffer[stackMapBufferSize++] =
1358                StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
1359
1360        frameBeforeLast = lastFrame;
1361        lastFrame = frame;
1362    }
1363
1364    StackMapFrame getInitialFrame() {
1365        StackMapFrame frame = new StackMapFrame();
1366        List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
1367        int len = arg_types.length();
1368        int count = 0;
1369        if (!meth.isStatic()) {
1370            Type thisType = meth.owner.type;
1371            frame.locals = new Type[len+1];
1372            if (meth.isConstructor() && thisType != syms.objectType) {
1373                frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
1374            } else {
1375                frame.locals[count++] = types.erasure(thisType);
1376            }
1377        } else {
1378            frame.locals = new Type[len];
1379        }
1380        for (Type arg_type : arg_types) {
1381            frame.locals[count++] = types.erasure(arg_type);
1382        }
1383        frame.pc = -1;
1384        frame.stack = null;
1385        return frame;
1386    }
1387
1388
1389/**************************************************************************
1390 * Operations having to do with jumps
1391 *************************************************************************/
1392
1393    /** A chain represents a list of unresolved jumps. Jump locations
1394     *  are sorted in decreasing order.
1395     */
1396    public static class Chain {
1397
1398        /** The position of the jump instruction.
1399         */
1400        public final int pc;
1401
1402        /** The machine state after the jump instruction.
1403         *  Invariant: all elements of a chain list have the same stacksize
1404         *  and compatible stack and register contents.
1405         */
1406        Code.State state;
1407
1408        /** The next jump in the list.
1409         */
1410        public final Chain next;
1411
1412        /** Construct a chain from its jump position, stacksize, previous
1413         *  chain, and machine state.
1414         */
1415        public Chain(int pc, Chain next, Code.State state) {
1416            this.pc = pc;
1417            this.next = next;
1418            this.state = state;
1419        }
1420    }
1421
1422    /** Negate a branch opcode.
1423     */
1424    public static int negate(int opcode) {
1425        if (opcode == if_acmp_null) return if_acmp_nonnull;
1426        else if (opcode == if_acmp_nonnull) return if_acmp_null;
1427        else return ((opcode + 1) ^ 1) - 1;
1428    }
1429
1430    /** Emit a jump instruction.
1431     *  Return code pointer of instruction to be patched.
1432     */
1433    public int emitJump(int opcode) {
1434        if (fatcode) {
1435            if (opcode == goto_ || opcode == jsr) {
1436                emitop4(opcode + goto_w - goto_, 0);
1437            } else {
1438                emitop2(negate(opcode), 8);
1439                emitop4(goto_w, 0);
1440                alive = true;
1441                pendingStackMap = needStackMap;
1442            }
1443            return cp - 5;
1444        } else {
1445            emitop2(opcode, 0);
1446            return cp - 3;
1447        }
1448    }
1449
1450    /** Emit a branch with given opcode; return its chain.
1451     *  branch differs from jump in that jsr is treated as no-op.
1452     */
1453    public Chain branch(int opcode) {
1454        Chain result = null;
1455        if (opcode == goto_) {
1456            result = pendingJumps;
1457            pendingJumps = null;
1458        }
1459        if (opcode != dontgoto && isAlive()) {
1460            result = new Chain(emitJump(opcode),
1461                               result,
1462                               state.dup());
1463            fixedPc = fatcode;
1464            if (opcode == goto_) alive = false;
1465        }
1466        return result;
1467    }
1468
1469    /** Resolve chain to point to given target.
1470     */
1471    public void resolve(Chain chain, int target) {
1472        boolean changed = false;
1473        State newState = state;
1474        for (; chain != null; chain = chain.next) {
1475            Assert.check(state != chain.state
1476                    && (target > chain.pc || state.stacksize == 0));
1477            if (target >= cp) {
1478                target = cp;
1479            } else if (get1(target) == goto_) {
1480                if (fatcode) target = target + get4(target + 1);
1481                else target = target + get2(target + 1);
1482            }
1483            if (get1(chain.pc) == goto_ &&
1484                chain.pc + 3 == target && target == cp && !fixedPc) {
1485                // If goto the next instruction, the jump is not needed:
1486                // compact the code.
1487                if (varDebugInfo) {
1488                    adjustAliveRanges(cp, -3);
1489                }
1490                cp = cp - 3;
1491                target = target - 3;
1492                if (chain.next == null) {
1493                    // This is the only jump to the target. Exit the loop
1494                    // without setting new state. The code is reachable
1495                    // from the instruction before goto_.
1496                    alive = true;
1497                    break;
1498                }
1499            } else {
1500                if (fatcode)
1501                    put4(chain.pc + 1, target - chain.pc);
1502                else if (target - chain.pc < Short.MIN_VALUE ||
1503                         target - chain.pc > Short.MAX_VALUE)
1504                    fatcode = true;
1505                else
1506                    put2(chain.pc + 1, target - chain.pc);
1507                Assert.check(!alive ||
1508                    chain.state.stacksize == newState.stacksize &&
1509                    chain.state.nlocks == newState.nlocks);
1510            }
1511            fixedPc = true;
1512            if (cp == target) {
1513                changed = true;
1514                if (debugCode)
1515                    System.err.println("resolving chain state=" + chain.state);
1516                if (alive) {
1517                    newState = chain.state.join(newState);
1518                } else {
1519                    newState = chain.state;
1520                    alive = true;
1521                }
1522            }
1523        }
1524        Assert.check(!changed || state != newState);
1525        if (state != newState) {
1526            setDefined(newState.defined);
1527            state = newState;
1528            pendingStackMap = needStackMap;
1529        }
1530    }
1531
1532    /** Resolve chain to point to current code pointer.
1533     */
1534    public void resolve(Chain chain) {
1535        Assert.check(
1536            !alive ||
1537            chain==null ||
1538            state.stacksize == chain.state.stacksize &&
1539            state.nlocks == chain.state.nlocks);
1540        pendingJumps = mergeChains(chain, pendingJumps);
1541    }
1542
1543    /** Resolve any pending jumps.
1544     */
1545    public void resolvePending() {
1546        Chain x = pendingJumps;
1547        pendingJumps = null;
1548        resolve(x, cp);
1549    }
1550
1551    /** Merge the jumps in of two chains into one.
1552     */
1553    public static Chain mergeChains(Chain chain1, Chain chain2) {
1554        // recursive merge sort
1555        if (chain2 == null) return chain1;
1556        if (chain1 == null) return chain2;
1557        Assert.check(
1558            chain1.state.stacksize == chain2.state.stacksize &&
1559            chain1.state.nlocks == chain2.state.nlocks);
1560        if (chain1.pc < chain2.pc)
1561            return new Chain(
1562                chain2.pc,
1563                mergeChains(chain1, chain2.next),
1564                chain2.state);
1565        return new Chain(
1566                chain1.pc,
1567                mergeChains(chain1.next, chain2),
1568                chain1.state);
1569    }
1570
1571
1572/* **************************************************************************
1573 * Catch clauses
1574 ****************************************************************************/
1575
1576    /** Add a catch clause to code.
1577     */
1578    public void addCatch(char startPc, char endPc,
1579                         char handlerPc, char catchType) {
1580            catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
1581        }
1582
1583
1584    public void compressCatchTable() {
1585        ListBuffer<char[]> compressedCatchInfo = new ListBuffer<>();
1586        List<Integer> handlerPcs = List.nil();
1587        for (char[] catchEntry : catchInfo) {
1588            handlerPcs = handlerPcs.prepend((int)catchEntry[2]);
1589        }
1590        for (char[] catchEntry : catchInfo) {
1591            int startpc = catchEntry[0];
1592            int endpc = catchEntry[1];
1593            if (startpc == endpc ||
1594                    (startpc == (endpc - 1) &&
1595                    handlerPcs.contains(startpc))) {
1596                continue;
1597            } else {
1598                compressedCatchInfo.append(catchEntry);
1599            }
1600        }
1601        catchInfo = compressedCatchInfo;
1602    }
1603
1604
1605/* **************************************************************************
1606 * Line numbers
1607 ****************************************************************************/
1608
1609    /** Add a line number entry.
1610     */
1611    public void addLineNumber(char startPc, char lineNumber) {
1612        if (lineDebugInfo) {
1613            if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
1614                lineInfo = lineInfo.tail;
1615            if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
1616                lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
1617        }
1618    }
1619
1620    /** Mark beginning of statement.
1621     */
1622    public void statBegin(int pos) {
1623        if (pos != Position.NOPOS) {
1624            pendingStatPos = pos;
1625        }
1626    }
1627
1628    /** Force stat begin eagerly
1629     */
1630    public void markStatBegin() {
1631        if (alive && lineDebugInfo) {
1632            int line = lineMap.getLineNumber(pendingStatPos);
1633            char cp1 = (char)cp;
1634            char line1 = (char)line;
1635            if (cp1 == cp && line1 == line)
1636                addLineNumber(cp1, line1);
1637        }
1638        pendingStatPos = Position.NOPOS;
1639    }
1640
1641
1642/* **************************************************************************
1643 * Simulated VM machine state
1644 ****************************************************************************/
1645
1646    class State implements Cloneable {
1647        /** The set of registers containing values. */
1648        Bits defined;
1649
1650        /** The (types of the) contents of the machine stack. */
1651        Type[] stack;
1652
1653        /** The first stack position currently unused. */
1654        int stacksize;
1655
1656        /** The numbers of registers containing locked monitors. */
1657        int[] locks;
1658        int nlocks;
1659
1660        State() {
1661            defined = new Bits();
1662            stack = new Type[16];
1663        }
1664
1665        State dup() {
1666            try {
1667                State state = (State)super.clone();
1668                state.defined = new Bits(defined);
1669                state.stack = stack.clone();
1670                if (locks != null) state.locks = locks.clone();
1671                if (debugCode) {
1672                    System.err.println("duping state " + this);
1673                    dump();
1674                }
1675                return state;
1676            } catch (CloneNotSupportedException ex) {
1677                throw new AssertionError(ex);
1678            }
1679        }
1680
1681        void lock(int register) {
1682            if (locks == null) {
1683                locks = new int[20];
1684            } else {
1685                locks = ArrayUtils.ensureCapacity(locks, nlocks);
1686            }
1687            locks[nlocks] = register;
1688            nlocks++;
1689        }
1690
1691        void unlock(int register) {
1692            nlocks--;
1693            Assert.check(locks[nlocks] == register);
1694            locks[nlocks] = -1;
1695        }
1696
1697        void push(Type t) {
1698            if (debugCode) System.err.println("   pushing " + t);
1699            switch (t.getTag()) {
1700            case VOID:
1701                return;
1702            case BYTE:
1703            case CHAR:
1704            case SHORT:
1705            case BOOLEAN:
1706                t = syms.intType;
1707                break;
1708            default:
1709                break;
1710            }
1711            stack = ArrayUtils.ensureCapacity(stack, stacksize+2);
1712            stack[stacksize++] = t;
1713            switch (width(t)) {
1714            case 1:
1715                break;
1716            case 2:
1717                stack[stacksize++] = null;
1718                break;
1719            default:
1720                throw new AssertionError(t);
1721            }
1722            if (stacksize > max_stack)
1723                max_stack = stacksize;
1724        }
1725
1726        Type pop1() {
1727            if (debugCode) System.err.println("   popping " + 1);
1728            stacksize--;
1729            Type result = stack[stacksize];
1730            stack[stacksize] = null;
1731            Assert.check(result != null && width(result) == 1);
1732            return result;
1733        }
1734
1735        Type peek() {
1736            return stack[stacksize-1];
1737        }
1738
1739        Type pop2() {
1740            if (debugCode) System.err.println("   popping " + 2);
1741            stacksize -= 2;
1742            Type result = stack[stacksize];
1743            stack[stacksize] = null;
1744            Assert.check(stack[stacksize+1] == null
1745                    && result != null && width(result) == 2);
1746            return result;
1747        }
1748
1749        void pop(int n) {
1750            if (debugCode) System.err.println("   popping " + n);
1751            while (n > 0) {
1752                stack[--stacksize] = null;
1753                n--;
1754            }
1755        }
1756
1757        void pop(Type t) {
1758            pop(width(t));
1759        }
1760
1761        /** Force the top of the stack to be treated as this supertype
1762         *  of its current type. */
1763        void forceStackTop(Type t) {
1764            if (!alive) return;
1765            switch (t.getTag()) {
1766            case CLASS:
1767            case ARRAY:
1768                int width = width(t);
1769                Type old = stack[stacksize-width];
1770                Assert.check(types.isSubtype(types.erasure(old),
1771                                       types.erasure(t)));
1772                stack[stacksize-width] = t;
1773                break;
1774            default:
1775            }
1776        }
1777
1778        void markInitialized(UninitializedType old) {
1779            Type newtype = old.initializedType();
1780            for (int i=0; i<stacksize; i++) {
1781                if (stack[i] == old) stack[i] = newtype;
1782            }
1783            for (int i=0; i<lvar.length; i++) {
1784                LocalVar lv = lvar[i];
1785                if (lv != null && lv.sym.type == old) {
1786                    VarSymbol sym = lv.sym;
1787                    sym = sym.clone(sym.owner);
1788                    sym.type = newtype;
1789                    LocalVar newlv = lvar[i] = new LocalVar(sym);
1790                    newlv.aliveRanges = lv.aliveRanges;
1791                }
1792            }
1793        }
1794
1795        State join(State other) {
1796            defined.andSet(other.defined);
1797            Assert.check(stacksize == other.stacksize
1798                    && nlocks == other.nlocks);
1799            for (int i=0; i<stacksize; ) {
1800                Type t = stack[i];
1801                Type tother = other.stack[i];
1802                Type result =
1803                    t==tother ? t :
1804                    types.isSubtype(t, tother) ? tother :
1805                    types.isSubtype(tother, t) ? t :
1806                    error();
1807                int w = width(result);
1808                stack[i] = result;
1809                if (w == 2) Assert.checkNull(stack[i+1]);
1810                i += w;
1811            }
1812            return this;
1813        }
1814
1815        Type error() {
1816            throw new AssertionError("inconsistent stack types at join point");
1817        }
1818
1819        void dump() {
1820            dump(-1);
1821        }
1822
1823        void dump(int pc) {
1824            System.err.print("stackMap for " + meth.owner + "." + meth);
1825            if (pc == -1)
1826                System.out.println();
1827            else
1828                System.out.println(" at " + pc);
1829            System.err.println(" stack (from bottom):");
1830            for (int i=0; i<stacksize; i++)
1831                System.err.println("  " + i + ": " + stack[i]);
1832
1833            int lastLocal = 0;
1834            for (int i=max_locals-1; i>=0; i--) {
1835                if (defined.isMember(i)) {
1836                    lastLocal = i;
1837                    break;
1838                }
1839            }
1840            if (lastLocal >= 0)
1841                System.err.println(" locals:");
1842            for (int i=0; i<=lastLocal; i++) {
1843                System.err.print("  " + i + ": ");
1844                if (defined.isMember(i)) {
1845                    LocalVar var = lvar[i];
1846                    if (var == null) {
1847                        System.err.println("(none)");
1848                    } else if (var.sym == null)
1849                        System.err.println("UNKNOWN!");
1850                    else
1851                        System.err.println("" + var.sym + " of type " +
1852                                           var.sym.erasure(types));
1853                } else {
1854                    System.err.println("undefined");
1855                }
1856            }
1857            if (nlocks != 0) {
1858                System.err.print(" locks:");
1859                for (int i=0; i<nlocks; i++) {
1860                    System.err.print(" " + locks[i]);
1861                }
1862                System.err.println();
1863            }
1864        }
1865    }
1866
1867    static final Type jsrReturnValue = new JCPrimitiveType(INT, null);
1868
1869
1870/* **************************************************************************
1871 * Local variables
1872 ****************************************************************************/
1873
1874    /** A live range of a local variable. */
1875    static class LocalVar {
1876        final VarSymbol sym;
1877        final char reg;
1878
1879        class Range {
1880            char start_pc = Character.MAX_VALUE;
1881            char length = Character.MAX_VALUE;
1882
1883            Range() {}
1884
1885            Range(char start) {
1886                this.start_pc = start;
1887            }
1888
1889            Range(char start, char length) {
1890                this.start_pc = start;
1891                this.length = length;
1892            }
1893
1894            boolean closed() {
1895                return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE;
1896            }
1897
1898            @Override
1899            public String toString() {
1900                int currentStartPC = start_pc;
1901                int currentLength = length;
1902                return "startpc = " + currentStartPC + " length " + currentLength;
1903            }
1904        }
1905
1906        java.util.List<Range> aliveRanges = new java.util.ArrayList<>();
1907
1908        LocalVar(VarSymbol v) {
1909            this.sym = v;
1910            this.reg = (char)v.adr;
1911        }
1912        public LocalVar dup() {
1913            return new LocalVar(sym);
1914        }
1915
1916        Range firstRange() {
1917            return aliveRanges.isEmpty() ? null : aliveRanges.get(0);
1918        }
1919
1920        Range lastRange() {
1921            return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
1922        }
1923
1924        void removeLastRange() {
1925            Range lastRange = lastRange();
1926            if (lastRange != null) {
1927                aliveRanges.remove(lastRange);
1928            }
1929        }
1930
1931        @Override
1932        public String toString() {
1933            if (aliveRanges == null) {
1934                return "empty local var";
1935            }
1936            StringBuilder sb = new StringBuilder().append(sym)
1937                    .append(" in register ").append((int)reg).append(" \n");
1938            for (Range r : aliveRanges) {
1939                sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc)))
1940                    .append(" length=").append(Integer.toString(((int)r.length)))
1941                    .append("\n");
1942            }
1943            return sb.toString();
1944        }
1945
1946        public void openRange(char start) {
1947            if (!hasOpenRange()) {
1948                aliveRanges.add(new Range(start));
1949            }
1950        }
1951
1952        public void closeRange(char length) {
1953            if (isLastRangeInitialized() && length > 0) {
1954                Range range = lastRange();
1955                if (range != null) {
1956                    if (range.length == Character.MAX_VALUE) {
1957                        range.length = length;
1958                    }
1959                }
1960            } else {
1961                removeLastRange();
1962            }
1963        }
1964
1965        public boolean hasOpenRange() {
1966            if (aliveRanges.isEmpty()) {
1967                return false;
1968            }
1969            return lastRange().length == Character.MAX_VALUE;
1970        }
1971
1972        public boolean isLastRangeInitialized() {
1973            if (aliveRanges.isEmpty()) {
1974                return false;
1975            }
1976            return lastRange().start_pc != Character.MAX_VALUE;
1977        }
1978
1979        public Range getWidestRange() {
1980            if (aliveRanges.isEmpty()) {
1981                return new Range();
1982            } else {
1983                Range firstRange = firstRange();
1984                Range lastRange = lastRange();
1985                char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc));
1986                return new Range(firstRange.start_pc, length);
1987            }
1988         }
1989
1990    }
1991
1992    /** Local variables, indexed by register. */
1993    LocalVar[] lvar;
1994
1995    /** Add a new local variable. */
1996    private void addLocalVar(VarSymbol v) {
1997        int adr = v.adr;
1998        lvar = ArrayUtils.ensureCapacity(lvar, adr+1);
1999        Assert.checkNull(lvar[adr]);
2000        if (pendingJumps != null) {
2001            resolvePending();
2002        }
2003        lvar[adr] = new LocalVar(v);
2004        state.defined.excl(adr);
2005    }
2006
2007    void adjustAliveRanges(int oldCP, int delta) {
2008        for (LocalVar localVar: lvar) {
2009            if (localVar != null) {
2010                for (LocalVar.Range range: localVar.aliveRanges) {
2011                    if (range.closed() && range.start_pc + range.length >= oldCP) {
2012                        range.length += delta;
2013                    }
2014                }
2015            }
2016        }
2017    }
2018
2019    /**
2020     * Calculates the size of the LocalVariableTable.
2021     */
2022    public int getLVTSize() {
2023        int result = varBufferSize;
2024        for (int i = 0; i < varBufferSize; i++) {
2025            LocalVar var = varBuffer[i];
2026            result += var.aliveRanges.size() - 1;
2027        }
2028        return result;
2029    }
2030
2031    /** Set the current variable defined state. */
2032    public void setDefined(Bits newDefined) {
2033        if (alive && newDefined != state.defined) {
2034            Bits diff = new Bits(state.defined).xorSet(newDefined);
2035            for (int adr = diff.nextBit(0);
2036                 adr >= 0;
2037                 adr = diff.nextBit(adr+1)) {
2038                if (adr >= nextreg)
2039                    state.defined.excl(adr);
2040                else if (state.defined.isMember(adr))
2041                    setUndefined(adr);
2042                else
2043                    setDefined(adr);
2044            }
2045        }
2046    }
2047
2048    /** Mark a register as being (possibly) defined. */
2049    public void setDefined(int adr) {
2050        LocalVar v = lvar[adr];
2051        if (v == null) {
2052            state.defined.excl(adr);
2053        } else {
2054            state.defined.incl(adr);
2055            if (cp < Character.MAX_VALUE) {
2056                v.openRange((char)cp);
2057            }
2058        }
2059    }
2060
2061    /** Mark a register as being undefined. */
2062    public void setUndefined(int adr) {
2063        state.defined.excl(adr);
2064        if (adr < lvar.length &&
2065            lvar[adr] != null &&
2066            lvar[adr].isLastRangeInitialized()) {
2067            LocalVar v = lvar[adr];
2068            char length = (char)(curCP() - v.lastRange().start_pc);
2069            if (length < Character.MAX_VALUE) {
2070                lvar[adr] = v.dup();
2071                v.closeRange(length);
2072                putVar(v);
2073            } else {
2074                v.removeLastRange();
2075            }
2076        }
2077    }
2078
2079    /** End the scope of a variable. */
2080    private void endScope(int adr) {
2081        LocalVar v = lvar[adr];
2082        if (v != null) {
2083            if (v.isLastRangeInitialized()) {
2084                char length = (char)(curCP() - v.lastRange().start_pc);
2085                if (length < Character.MAX_VALUE) {
2086                    v.closeRange(length);
2087                    putVar(v);
2088                    fillLocalVarPosition(v);
2089                }
2090            }
2091            /** the call to curCP() can implicitly adjust the current cp, if so
2092             * the alive range of local variables may be modified. Thus we need
2093             * all of them. For this reason assigning null to the given address
2094             * should be the last action to do.
2095             */
2096            lvar[adr] = null;
2097        }
2098        state.defined.excl(adr);
2099    }
2100
2101    private void fillLocalVarPosition(LocalVar lv) {
2102        if (lv == null || lv.sym == null || !lv.sym.hasTypeAnnotations())
2103            return;
2104        for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
2105            TypeAnnotationPosition p = ta.position;
2106            LocalVar.Range widestRange = lv.getWidestRange();
2107            p.lvarOffset = new int[] { (int)widestRange.start_pc };
2108            p.lvarLength = new int[] { (int)widestRange.length };
2109            p.lvarIndex = new int[] { (int)lv.reg };
2110            p.isValidOffset = true;
2111        }
2112    }
2113
2114    // Method to be called after compressCatchTable to
2115    // fill in the exception table index for type
2116    // annotations on exception parameters.
2117    public void fillExceptionParameterPositions() {
2118        for (int i = 0; i < varBufferSize; ++i) {
2119            LocalVar lv = varBuffer[i];
2120            if (lv == null || lv.sym == null
2121                    || !lv.sym.hasTypeAnnotations()
2122                    || !lv.sym.isExceptionParameter())
2123                continue;
2124
2125            for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
2126                TypeAnnotationPosition p = ta.position;
2127                if (p.hasCatchType()) {
2128                    final int idx = findExceptionIndex(p);
2129                    if (idx == -1)
2130                        Assert.error("Could not find exception index for type annotation " +
2131                                     ta + " on exception parameter");
2132                    p.setExceptionIndex(idx);
2133                }
2134            }
2135        }
2136    }
2137
2138    private int findExceptionIndex(TypeAnnotationPosition p) {
2139        final int catchType = p.getCatchType();
2140        final int startPos = p.getStartPos();
2141        final int len = catchInfo.length();
2142        List<char[]> iter = catchInfo.toList();
2143        for (int i = 0; i < len; ++i) {
2144            char[] catchEntry = iter.head;
2145            iter = iter.tail;
2146            int ct = catchEntry[3];
2147            int sp = catchEntry[0];
2148            if (catchType == ct && sp == startPos) {
2149                return i;
2150            }
2151        }
2152        return -1;
2153    }
2154
2155    /** Put a live variable range into the buffer to be output to the
2156     *  class file.
2157     */
2158    void putVar(LocalVar var) {
2159        // Keep local variables if
2160        // 1) we need them for debug information
2161        // 2) it is an exception type and it contains type annotations
2162        boolean keepLocalVariables = varDebugInfo ||
2163            (var.sym.isExceptionParameter() && var.sym.hasTypeAnnotations());
2164        if (!keepLocalVariables) return;
2165        //don't keep synthetic vars, unless they are lambda method parameters
2166        boolean ignoredSyntheticVar = (var.sym.flags() & Flags.SYNTHETIC) != 0 &&
2167                ((var.sym.owner.flags() & Flags.LAMBDA_METHOD) == 0 ||
2168                 (var.sym.flags() & Flags.PARAMETER) == 0);
2169        if (ignoredSyntheticVar) 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