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