/*
 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.tools.javac.jvm;

import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Types.UniqueType;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;

import static com.sun.tools.javac.code.TypeTag.BOT;
import static com.sun.tools.javac.code.TypeTag.INT;
import static com.sun.tools.javac.jvm.ByteCodes.*;
import static com.sun.tools.javac.jvm.UninitializedType.*;
import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;

/** An internal structure that corresponds to the code attribute of
 *  methods in a classfile. The class also provides some utility operations to
 *  generate bytecode instructions.
 *
 *  <p><b>This is NOT part of any supported API.
 *  If you write code that depends on this, you do so at your own risk.
 *  This code and its internal interfaces are subject to change or
 *  deletion without notice.</b>
 */
public class Code {

    public final boolean debugCode;
    public final boolean needStackMap;

    public enum StackMapFormat {
        NONE,
        CLDC {
            Name getAttributeName(Names names) {
                return names.StackMap;
            }
        },
        JSR202 {
            Name getAttributeName(Names names) {
                return names.StackMapTable;
            }
        };
        Name getAttributeName(Names names) {
            return names.empty;
        }
    }

    final Types types;
    final Symtab syms;

/*---------- classfile fields: --------------- */

    /** The maximum stack size.
     */
    public int max_stack = 0;

    /** The maximum number of local variable slots.
     */
    public int max_locals = 0;

    /** The code buffer.
     */
    public byte[] code = new byte[64];

    /** the current code pointer.
     */
    public int cp = 0;

    /** Check the code against VM spec limits; if
     *  problems report them and return true.
     */
    public boolean checkLimits(DiagnosticPosition pos, Log log) {
        if (cp > ClassFile.MAX_CODE) {
            log.error(pos, "limit.code");
            return true;
        }
        if (max_locals > ClassFile.MAX_LOCALS) {
            log.error(pos, "limit.locals");
            return true;
        }
        if (max_stack > ClassFile.MAX_STACK) {
            log.error(pos, "limit.stack");
            return true;
        }
        return false;
    }

    /** A buffer for expression catch data. Each enter is a vector
     *  of four unsigned shorts.
     */
    ListBuffer<char[]> catchInfo = new ListBuffer<char[]>();

    /** A buffer for line number information. Each entry is a vector
     *  of two unsigned shorts.
     */
    List<char[]> lineInfo = List.nil(); // handled in stack fashion

    /** The CharacterRangeTable
     */
    public CRTable crt;

/*---------- internal fields: --------------- */

    /** Are we generating code with jumps &ge; 32K?
     */
    public boolean fatcode;

    /** Code generation enabled?
     */
    private boolean alive = true;

    /** The current machine state (registers and stack).
     */
    State state;

    /** Is it forbidden to compactify code, because something is
     *  pointing to current location?
     */
    private boolean fixedPc = false;

    /** The next available register.
     */
    public int nextreg = 0;

    /** A chain for jumps to be resolved before the next opcode is emitted.
     *  We do this lazily to avoid jumps to jumps.
     */
    Chain pendingJumps = null;

    /** The position of the currently statement, if we are at the
     *  start of this statement, NOPOS otherwise.
     *  We need this to emit line numbers lazily, which we need to do
     *  because of jump-to-jump optimization.
     */
    int pendingStatPos = Position.NOPOS;

    /** Set true when a stackMap is needed at the current PC. */
    boolean pendingStackMap = false;

    /** The stack map format to be generated. */
    StackMapFormat stackMap;

    /** Switch: emit variable debug info.
     */
    boolean varDebugInfo;

    /** Switch: emit line number info.
     */
    boolean lineDebugInfo;

    /** Emit line number info if map supplied
     */
    Position.LineMap lineMap;

    /** The constant pool of the current class.
     */
    final Pool pool;

    final MethodSymbol meth;

    /** Construct a code object, given the settings of the fatcode,
     *  debugging info switches and the CharacterRangeTable.
     */
    public Code(MethodSymbol meth,
                boolean fatcode,
                Position.LineMap lineMap,
                boolean varDebugInfo,
                StackMapFormat stackMap,
                boolean debugCode,
                CRTable crt,
                Symtab syms,
                Types types,
                Pool pool) {
        this.meth = meth;
        this.fatcode = fatcode;
        this.lineMap = lineMap;
        this.lineDebugInfo = lineMap != null;
        this.varDebugInfo = varDebugInfo;
        this.crt = crt;
        this.syms = syms;
        this.types = types;
        this.debugCode = debugCode;
        this.stackMap = stackMap;
        switch (stackMap) {
        case CLDC:
        case JSR202:
            this.needStackMap = true;
            break;
        default:
            this.needStackMap = false;
        }
        state = new State();
        lvar = new LocalVar[20];
        this.pool = pool;
    }


/* **************************************************************************
 * Typecodes & related stuff
 ****************************************************************************/

    /** Given a type, return its type code (used implicitly in the
     *  JVM architecture).
     */
    public static int typecode(Type type) {
        switch (type.getTag()) {
        case BYTE: return BYTEcode;
        case SHORT: return SHORTcode;
        case CHAR: return CHARcode;
        case INT: return INTcode;
        case LONG: return LONGcode;
        case FLOAT: return FLOATcode;
        case DOUBLE: return DOUBLEcode;
        case BOOLEAN: return BYTEcode;
        case VOID: return VOIDcode;
        case CLASS:
        case ARRAY:
        case METHOD:
        case BOT:
        case TYPEVAR:
        case UNINITIALIZED_THIS:
        case UNINITIALIZED_OBJECT:
            return OBJECTcode;
        default: throw new AssertionError("typecode " + type.getTag());
        }
    }

    /** Collapse type code for subtypes of int to INTcode.
     */
    public static int truncate(int tc) {
        switch (tc) {
        case BYTEcode: case SHORTcode: case CHARcode: return INTcode;
        default: return tc;
        }
    }

    /** The width in bytes of objects of the type.
     */
    public static int width(int typecode) {
        switch (typecode) {
        case LONGcode: case DOUBLEcode: return 2;
        case VOIDcode: return 0;
        default: return 1;
        }
    }

    public static int width(Type type) {
        return type == null ? 1 : width(typecode(type));
    }

    /** The total width taken up by a vector of objects.
     */
    public static int width(List<Type> types) {
        int w = 0;
        for (List<Type> l = types; l.nonEmpty(); l = l.tail)
            w = w + width(l.head);
        return w;
    }

    /** Given a type, return its code for allocating arrays of that type.
     */
    public static int arraycode(Type type) {
        switch (type.getTag()) {
        case BYTE: return 8;
        case BOOLEAN: return 4;
        case SHORT: return 9;
        case CHAR: return 5;
        case INT: return 10;
        case LONG: return 11;
        case FLOAT: return 6;
        case DOUBLE: return 7;
        case CLASS: return 0;
        case ARRAY: return 1;
        default: throw new AssertionError("arraycode " + type);
        }
    }


/* **************************************************************************
 * Emit code
 ****************************************************************************/

    /** The current output code pointer.
     */
    public int curCP() {
        /*
         * This method has side-effects because calling it can indirectly provoke
         *  extra code generation, like goto instructions, depending on the context
         *  where it's called.
         *  Use with care or even better avoid using it.
         */
        if (pendingJumps != null) {
            resolvePending();
        }
        if (pendingStatPos != Position.NOPOS) {
            markStatBegin();
        }
        fixedPc = true;
        return cp;
    }

    /** Emit a byte of code.
     */
    private  void emit1(int od) {
        if (!alive) return;
        code = ArrayUtils.ensureCapacity(code, cp);
        code[cp++] = (byte)od;
    }

    /** Emit two bytes of code.
     */
    private void emit2(int od) {
        if (!alive) return;
        if (cp + 2 > code.length) {
            emit1(od >> 8);
            emit1(od);
        } else {
            code[cp++] = (byte)(od >> 8);
            code[cp++] = (byte)od;
        }
    }

    /** Emit four bytes of code.
     */
    public void emit4(int od) {
        if (!alive) return;
        if (cp + 4 > code.length) {
            emit1(od >> 24);
            emit1(od >> 16);
            emit1(od >> 8);
            emit1(od);
        } else {
            code[cp++] = (byte)(od >> 24);
            code[cp++] = (byte)(od >> 16);
            code[cp++] = (byte)(od >> 8);
            code[cp++] = (byte)od;
        }
    }

    /** Emit an opcode.
     */
    private void emitop(int op) {
        if (pendingJumps != null) resolvePending();
        if (alive) {
            if (pendingStatPos != Position.NOPOS)
                markStatBegin();
            if (pendingStackMap) {
                pendingStackMap = false;
                emitStackMap();
            }
            if (debugCode)
                System.err.println("emit@" + cp + " stack=" +
                                   state.stacksize + ": " +
                                   mnem(op));
            emit1(op);
        }
    }

    void postop() {
        Assert.check(alive || state.stacksize == 0);
    }

    /** Emit a ldc (or ldc_w) instruction, taking into account operand size
    */
    public void emitLdc(int od) {
        if (od <= 255) {
            emitop1(ldc1, od);
        }
        else {
            emitop2(ldc2, od);
        }
    }

    /** Emit a multinewarray instruction.
     */
    public void emitMultianewarray(int ndims, int type, Type arrayType) {
        emitop(multianewarray);
        if (!alive) return;
        emit2(type);
        emit1(ndims);
        state.pop(ndims);
        state.push(arrayType);
    }

    /** Emit newarray.
     */
    public void emitNewarray(int elemcode, Type arrayType) {
        emitop(newarray);
        if (!alive) return;
        emit1(elemcode);
        state.pop(1); // count
        state.push(arrayType);
    }

    /** Emit anewarray.
     */
    public void emitAnewarray(int od, Type arrayType) {
        emitop(anewarray);
        if (!alive) return;
        emit2(od);
        state.pop(1);
        state.push(arrayType);
    }

    /** Emit an invokeinterface instruction.
     */
    public void emitInvokeinterface(int meth, Type mtype) {
        int argsize = width(mtype.getParameterTypes());
        emitop(invokeinterface);
        if (!alive) return;
        emit2(meth);
        emit1(argsize + 1);
        emit1(0);
        state.pop(argsize + 1);
        state.push(mtype.getReturnType());
    }

    /** Emit an invokespecial instruction.
     */
    public void emitInvokespecial(int meth, Type mtype) {
        int argsize = width(mtype.getParameterTypes());
        emitop(invokespecial);
        if (!alive) return;
        emit2(meth);
        Symbol sym = (Symbol)pool.pool[meth];
        state.pop(argsize);
        if (sym.isConstructor())
            state.markInitialized((UninitializedType)state.peek());
        state.pop(1);
        state.push(mtype.getReturnType());
    }

    /** Emit an invokestatic instruction.
     */
    public void emitInvokestatic(int meth, Type mtype) {
        int argsize = width(mtype.getParameterTypes());
        emitop(invokestatic);
        if (!alive) return;
        emit2(meth);
        state.pop(argsize);
        state.push(mtype.getReturnType());
    }

    /** Emit an invokevirtual instruction.
     */
    public void emitInvokevirtual(int meth, Type mtype) {
        int argsize = width(mtype.getParameterTypes());
        emitop(invokevirtual);
        if (!alive) return;
        emit2(meth);
        state.pop(argsize + 1);
        state.push(mtype.getReturnType());
    }

    /** Emit an invokedynamic instruction.
     */
    public void emitInvokedynamic(int desc, Type mtype) {
        int argsize = width(mtype.getParameterTypes());
        emitop(invokedynamic);
        if (!alive) return;
        emit2(desc);
        emit2(0);
        state.pop(argsize);
        state.push(mtype.getReturnType());
    }

    /** Emit an opcode with no operand field.
     */
    public void emitop0(int op) {
        emitop(op);
        if (!alive) return;
        switch (op) {
        case aaload: {
            state.pop(1);// index
            Type a = state.stack[state.stacksize-1];
            state.pop(1);
            //sometimes 'null type' is treated as a one-dimensional array type
            //see Gen.visitLiteral - we should handle this case accordingly
            Type stackType = a.hasTag(BOT) ?
                syms.objectType :
                types.erasure(types.elemtype(a));
            state.push(stackType); }
            break;
        case goto_:
            markDead();
            break;
        case nop:
        case ineg:
        case lneg:
        case fneg:
        case dneg:
            break;
        case aconst_null:
            state.push(syms.botType);
            break;
        case iconst_m1:
        case iconst_0:
        case iconst_1:
        case iconst_2:
        case iconst_3:
        case iconst_4:
        case iconst_5:
        case iload_0:
        case iload_1:
        case iload_2:
        case iload_3:
            state.push(syms.intType);
            break;
        case lconst_0:
        case lconst_1:
        case lload_0:
        case lload_1:
        case lload_2:
        case lload_3:
            state.push(syms.longType);
            break;
        case fconst_0:
        case fconst_1:
        case fconst_2:
        case fload_0:
        case fload_1:
        case fload_2:
        case fload_3:
            state.push(syms.floatType);
            break;
        case dconst_0:
        case dconst_1:
        case dload_0:
        case dload_1:
        case dload_2:
        case dload_3:
            state.push(syms.doubleType);
            break;
        case aload_0:
            state.push(lvar[0].sym.type);
            break;
        case aload_1:
            state.push(lvar[1].sym.type);
            break;
        case aload_2:
            state.push(lvar[2].sym.type);
            break;
        case aload_3:
            state.push(lvar[3].sym.type);
            break;
        case iaload:
        case baload:
        case caload:
        case saload:
            state.pop(2);
            state.push(syms.intType);
            break;
        case laload:
            state.pop(2);
            state.push(syms.longType);
            break;
        case faload:
            state.pop(2);
            state.push(syms.floatType);
            break;
        case daload:
            state.pop(2);
            state.push(syms.doubleType);
            break;
        case istore_0:
        case istore_1:
        case istore_2:
        case istore_3:
        case fstore_0:
        case fstore_1:
        case fstore_2:
        case fstore_3:
        case astore_0:
        case astore_1:
        case astore_2:
        case astore_3:
        case pop:
        case lshr:
        case lshl:
        case lushr:
            state.pop(1);
            break;
        case areturn:
        case ireturn:
        case freturn:
            Assert.check(state.nlocks == 0);
            state.pop(1);
            markDead();
            break;
        case athrow:
            state.pop(1);
            markDead();
            break;
        case lstore_0:
        case lstore_1:
        case lstore_2:
        case lstore_3:
        case dstore_0:
        case dstore_1:
        case dstore_2:
        case dstore_3:
        case pop2:
            state.pop(2);
            break;
        case lreturn:
        case dreturn:
            Assert.check(state.nlocks == 0);
            state.pop(2);
            markDead();
            break;
        case dup:
            state.push(state.stack[state.stacksize-1]);
            break;
        case return_:
            Assert.check(state.nlocks == 0);
            markDead();
            break;
        case arraylength:
            state.pop(1);
            state.push(syms.intType);
            break;
        case isub:
        case iadd:
        case imul:
        case idiv:
        case imod:
        case ishl:
        case ishr:
        case iushr:
        case iand:
        case ior:
        case ixor:
            state.pop(1);
            // state.pop(1);
            // state.push(syms.intType);
            break;
        case aastore:
            state.pop(3);
            break;
        case land:
        case lor:
        case lxor:
        case lmod:
        case ldiv:
        case lmul:
        case lsub:
        case ladd:
            state.pop(2);
            break;
        case lcmp:
            state.pop(4);
            state.push(syms.intType);
            break;
        case l2i:
            state.pop(2);
            state.push(syms.intType);
            break;
        case i2l:
            state.pop(1);
            state.push(syms.longType);
            break;
        case i2f:
            state.pop(1);
            state.push(syms.floatType);
            break;
        case i2d:
            state.pop(1);
            state.push(syms.doubleType);
            break;
        case l2f:
            state.pop(2);
            state.push(syms.floatType);
            break;
        case l2d:
            state.pop(2);
            state.push(syms.doubleType);
            break;
        case f2i:
            state.pop(1);
            state.push(syms.intType);
            break;
        case f2l:
            state.pop(1);
            state.push(syms.longType);
            break;
        case f2d:
            state.pop(1);
            state.push(syms.doubleType);
            break;
        case d2i:
            state.pop(2);
            state.push(syms.intType);
            break;
        case d2l:
            state.pop(2);
            state.push(syms.longType);
            break;
        case d2f:
            state.pop(2);
            state.push(syms.floatType);
            break;
        case tableswitch:
        case lookupswitch:
            state.pop(1);
            // the caller is responsible for patching up the state
            break;
        case dup_x1: {
            Type val1 = state.pop1();
            Type val2 = state.pop1();
            state.push(val1);
            state.push(val2);
            state.push(val1);
            break;
        }
        case bastore:
            state.pop(3);
            break;
        case int2byte:
        case int2char:
        case int2short:
            break;
        case fmul:
        case fadd:
        case fsub:
        case fdiv:
        case fmod:
            state.pop(1);
            break;
        case castore:
        case iastore:
        case fastore:
        case sastore:
            state.pop(3);
            break;
        case lastore:
        case dastore:
            state.pop(4);
            break;
        case dup2:
            if (state.stack[state.stacksize-1] != null) {
                Type value1 = state.pop1();
                Type value2 = state.pop1();
                state.push(value2);
                state.push(value1);
                state.push(value2);
                state.push(value1);
            } else {
                Type value = state.pop2();
                state.push(value);
                state.push(value);
            }
            break;
        case dup2_x1:
            if (state.stack[state.stacksize-1] != null) {
                Type value1 = state.pop1();
                Type value2 = state.pop1();
                Type value3 = state.pop1();
                state.push(value2);
                state.push(value1);
                state.push(value3);
                state.push(value2);
                state.push(value1);
            } else {
                Type value1 = state.pop2();
                Type value2 = state.pop1();
                state.push(value1);
                state.push(value2);
                state.push(value1);
            }
            break;
        case dup2_x2:
            if (state.stack[state.stacksize-1] != null) {
                Type value1 = state.pop1();
                Type value2 = state.pop1();
                if (state.stack[state.stacksize-1] != null) {
                    // form 1
                    Type value3 = state.pop1();
                    Type value4 = state.pop1();
                    state.push(value2);
                    state.push(value1);
                    state.push(value4);
                    state.push(value3);
                    state.push(value2);
                    state.push(value1);
                } else {
                    // form 3
                    Type value3 = state.pop2();
                    state.push(value2);
                    state.push(value1);
                    state.push(value3);
                    state.push(value2);
                    state.push(value1);
                }
            } else {
                Type value1 = state.pop2();
                if (state.stack[state.stacksize-1] != null) {
                    // form 2
                    Type value2 = state.pop1();
                    Type value3 = state.pop1();
                    state.push(value1);
                    state.push(value3);
                    state.push(value2);
                    state.push(value1);
                } else {
                    // form 4
                    Type value2 = state.pop2();
                    state.push(value1);
                    state.push(value2);
                    state.push(value1);
                }
            }
            break;
        case dup_x2: {
            Type value1 = state.pop1();
            if (state.stack[state.stacksize-1] != null) {
                // form 1
                Type value2 = state.pop1();
                Type value3 = state.pop1();
                state.push(value1);
                state.push(value3);
                state.push(value2);
                state.push(value1);
            } else {
                // form 2
                Type value2 = state.pop2();
                state.push(value1);
                state.push(value2);
                state.push(value1);
            }
        }
            break;
        case fcmpl:
        case fcmpg:
            state.pop(2);
            state.push(syms.intType);
            break;
        case dcmpl:
        case dcmpg:
            state.pop(4);
            state.push(syms.intType);
            break;
        case swap: {
            Type value1 = state.pop1();
            Type value2 = state.pop1();
            state.push(value1);
            state.push(value2);
            break;
        }
        case dadd:
        case dsub:
        case dmul:
        case ddiv:
        case dmod:
            state.pop(2);
            break;
        case ret:
            markDead();
            break;
        case wide:
            // must be handled by the caller.
            return;
        case monitorenter:
        case monitorexit:
            state.pop(1);
            break;

        default:
            throw new AssertionError(mnem(op));
        }
        postop();
    }

    /** Emit an opcode with a one-byte operand field.
     */
    public void emitop1(int op, int od) {
        emitop(op);
        if (!alive) return;
        emit1(od);
        switch (op) {
        case bipush:
            state.push(syms.intType);
            break;
        case ldc1:
            state.push(typeForPool(pool.pool[od]));
            break;
        default:
            throw new AssertionError(mnem(op));
        }
        postop();
    }

    /** The type of a constant pool entry. */
    private Type typeForPool(Object o) {
        if (o instanceof Integer) return syms.intType;
        if (o instanceof Float) return syms.floatType;
        if (o instanceof String) return syms.stringType;
        if (o instanceof Long) return syms.longType;
        if (o instanceof Double) return syms.doubleType;
        if (o instanceof ClassSymbol) return syms.classType;
        if (o instanceof Pool.MethodHandle) return syms.methodHandleType;
        if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type);
        if (o instanceof Type) {
            Type ty = ((Type)o).unannotatedType();

            if (ty instanceof Type.ArrayType) return syms.classType;
            if (ty instanceof Type.MethodType) return syms.methodTypeType;
        }
        throw new AssertionError("Invalid type of constant pool entry: " + o.getClass());
    }

    /** Emit an opcode with a one-byte operand field;
     *  widen if field does not fit in a byte.
     */
    public void emitop1w(int op, int od) {
        if (od > 0xFF) {
            emitop(wide);
            emitop(op);
            emit2(od);
        } else {
            emitop(op);
            emit1(od);
        }
        if (!alive) return;
        switch (op) {
        case iload:
            state.push(syms.intType);
            break;
        case lload:
            state.push(syms.longType);
            break;
        case fload:
            state.push(syms.floatType);
            break;
        case dload:
            state.push(syms.doubleType);
            break;
        case aload:
            state.push(lvar[od].sym.type);
            break;
        case lstore:
        case dstore:
            state.pop(2);
            break;
        case istore:
        case fstore:
        case astore:
            state.pop(1);
            break;
        case ret:
            markDead();
            break;
        default:
            throw new AssertionError(mnem(op));
        }
        postop();
    }

    /** Emit an opcode with two one-byte operand fields;
     *  widen if either field does not fit in a byte.
     */
    public void emitop1w(int op, int od1, int od2) {
        if (od1 > 0xFF || od2 < -128 || od2 > 127) {
            emitop(wide);
            emitop(op);
            emit2(od1);
            emit2(od2);
        } else {
            emitop(op);
            emit1(od1);
            emit1(od2);
        }
        if (!alive) return;
        switch (op) {
        case iinc:
            break;
        default:
            throw new AssertionError(mnem(op));
        }
    }

    /** Emit an opcode with a two-byte operand field.
     */
    public void emitop2(int op, int od) {
        emitop(op);
        if (!alive) return;
        emit2(od);
        switch (op) {
        case getstatic:
            state.push(((Symbol)(pool.pool[od])).erasure(types));
            break;
        case putstatic:
            state.pop(((Symbol)(pool.pool[od])).erasure(types));
            break;
        case new_:
            Symbol sym;
            if (pool.pool[od] instanceof UniqueType) {
                // Required by change in Gen.makeRef to allow
                // annotated types.
                // TODO: is this needed anywhere else?
                sym = ((UniqueType)(pool.pool[od])).type.tsym;
            } else {
                sym = (Symbol)(pool.pool[od]);
            }
            state.push(uninitializedObject(sym.erasure(types), cp-3));
            break;
        case sipush:
            state.push(syms.intType);
            break;
        case if_acmp_null:
        case if_acmp_nonnull:
        case ifeq:
        case ifne:
        case iflt:
        case ifge:
        case ifgt:
        case ifle:
            state.pop(1);
            break;
        case if_icmpeq:
        case if_icmpne:
        case if_icmplt:
        case if_icmpge:
        case if_icmpgt:
        case if_icmple:
        case if_acmpeq:
        case if_acmpne:
            state.pop(2);
            break;
        case goto_:
            markDead();
            break;
        case putfield:
            state.pop(((Symbol)(pool.pool[od])).erasure(types));
            state.pop(1); // object ref
            break;
        case getfield:
            state.pop(1); // object ref
            state.push(((Symbol)(pool.pool[od])).erasure(types));
            break;
        case checkcast: {
            state.pop(1); // object ref
            Object o = pool.pool[od];
            Type t = (o instanceof Symbol)
                ? ((Symbol)o).erasure(types)
                : types.erasure((((UniqueType)o).type));
            state.push(t);
            break; }
        case ldc2w:
            state.push(typeForPool(pool.pool[od]));
            break;
        case instanceof_:
            state.pop(1);
            state.push(syms.intType);
            break;
        case ldc2:
            state.push(typeForPool(pool.pool[od]));
            break;
        case jsr:
            break;
        default:
            throw new AssertionError(mnem(op));
        }
        // postop();
    }

    /** Emit an opcode with a four-byte operand field.
     */
    public void emitop4(int op, int od) {
        emitop(op);
        if (!alive) return;
        emit4(od);
        switch (op) {
        case goto_w:
            markDead();
            break;
        case jsr_w:
            break;
        default:
            throw new AssertionError(mnem(op));
        }
        // postop();
    }

    /** Align code pointer to next `incr' boundary.
     */
    public void align(int incr) {
        if (alive)
            while (cp % incr != 0) emitop0(nop);
    }

    /** Place a byte into code at address pc.
     *  Pre: {@literal pc + 1 <= cp }.
     */
    private void put1(int pc, int op) {
        code[pc] = (byte)op;
    }

    /** Place two bytes into code at address pc.
     *  Pre: {@literal pc + 2 <= cp }.
     */
    private void put2(int pc, int od) {
        // pre: pc + 2 <= cp
        put1(pc, od >> 8);
        put1(pc+1, od);
    }

    /** Place four  bytes into code at address pc.
     *  Pre: {@literal pc + 4 <= cp }.
     */
    public void put4(int pc, int od) {
        // pre: pc + 4 <= cp
        put1(pc  , od >> 24);
        put1(pc+1, od >> 16);
        put1(pc+2, od >> 8);
        put1(pc+3, od);
    }

    /** Return code byte at position pc as an unsigned int.
     */
    private int get1(int pc) {
        return code[pc] & 0xFF;
    }

    /** Return two code bytes at position pc as an unsigned int.
     */
    private int get2(int pc) {
        return (get1(pc) << 8) | get1(pc+1);
    }

    /** Return four code bytes at position pc as an int.
     */
    public int get4(int pc) {
        // pre: pc + 4 <= cp
        return
            (get1(pc) << 24) |
            (get1(pc+1) << 16) |
            (get1(pc+2) << 8) |
            (get1(pc+3));
    }

    /** Is code generation currently enabled?
     */
    public boolean isAlive() {
        return alive || pendingJumps != null;
    }

    /** Switch code generation on/off.
     */
    public void markDead() {
        alive = false;
    }

    /** Declare an entry point; return current code pointer
     */
    public int entryPoint() {
        int pc = curCP();
        alive = true;
        pendingStackMap = needStackMap;
        return pc;
    }

    /** Declare an entry point with initial state;
     *  return current code pointer
     */
    public int entryPoint(State state) {
        int pc = curCP();
        alive = true;
        State newState = state.dup();
        setDefined(newState.defined);
        this.state = newState;
        Assert.check(state.stacksize <= max_stack);
        if (debugCode) System.err.println("entry point " + state);
        pendingStackMap = needStackMap;
        return pc;
    }

    /** Declare an entry point with initial state plus a pushed value;
     *  return current code pointer
     */
    public int entryPoint(State state, Type pushed) {
        int pc = curCP();
        alive = true;
        State newState = state.dup();
        setDefined(newState.defined);
        this.state = newState;
        Assert.check(state.stacksize <= max_stack);
        this.state.push(pushed);
        if (debugCode) System.err.println("entry point " + state);
        pendingStackMap = needStackMap;
        return pc;
    }


/**************************************************************************
 * Stack map generation
 *************************************************************************/

    /** An entry in the stack map. */
    static class StackMapFrame {
        int pc;
        Type[] locals;
        Type[] stack;
    }

    /** A buffer of cldc stack map entries. */
    StackMapFrame[] stackMapBuffer = null;

    /** A buffer of compressed StackMapTable entries. */
    StackMapTableFrame[] stackMapTableBuffer = null;
    int stackMapBufferSize = 0;

    /** The last PC at which we generated a stack map. */
    int lastStackMapPC = -1;

    /** The last stack map frame in StackMapTable. */
    StackMapFrame lastFrame = null;

    /** The stack map frame before the last one. */
    StackMapFrame frameBeforeLast = null;

    /** Emit a stack map entry.  */
    public void emitStackMap() {
        int pc = curCP();
        if (!needStackMap) return;



        switch (stackMap) {
            case CLDC:
                emitCLDCStackMap(pc, getLocalsSize());
                break;
            case JSR202:
                emitStackMapFrame(pc, getLocalsSize());
                break;
            default:
                throw new AssertionError("Should have chosen a stackmap format");
        }
        // DEBUG code follows
        if (debugCode) state.dump(pc);
    }

    private int getLocalsSize() {
        int nextLocal = 0;
        for (int i=max_locals-1; i>=0; i--) {
            if (state.defined.isMember(i) && lvar[i] != null) {
                nextLocal = i + width(lvar[i].sym.erasure(types));
                break;
            }
        }
        return nextLocal;
    }

    /** Emit a CLDC stack map frame. */
    void emitCLDCStackMap(int pc, int localsSize) {
        if (lastStackMapPC == pc) {
            // drop existing stackmap at this offset
            stackMapBuffer[--stackMapBufferSize] = null;
        }
        lastStackMapPC = pc;

        if (stackMapBuffer == null) {
            stackMapBuffer = new StackMapFrame[20];
        } else {
            stackMapBuffer = ArrayUtils.ensureCapacity(stackMapBuffer, stackMapBufferSize);
        }
        StackMapFrame frame =
            stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
        frame.pc = pc;

        frame.locals = new Type[localsSize];
        for (int i=0; i<localsSize; i++) {
            if (state.defined.isMember(i) && lvar[i] != null) {
                Type vtype = lvar[i].sym.type;
                if (!(vtype instanceof UninitializedType))
                    vtype = types.erasure(vtype);
                frame.locals[i] = vtype;
            }
        }
        frame.stack = new Type[state.stacksize];
        for (int i=0; i<state.stacksize; i++)
            frame.stack[i] = state.stack[i];
    }

    void emitStackMapFrame(int pc, int localsSize) {
        if (lastFrame == null) {
            // first frame
            lastFrame = getInitialFrame();
        } else if (lastFrame.pc == pc) {
            // drop existing stackmap at this offset
            stackMapTableBuffer[--stackMapBufferSize] = null;
            lastFrame = frameBeforeLast;
            frameBeforeLast = null;
        }

        StackMapFrame frame = new StackMapFrame();
        frame.pc = pc;

        int localCount = 0;
        Type[] locals = new Type[localsSize];
        for (int i=0; i<localsSize; i++, localCount++) {
            if (state.defined.isMember(i) && lvar[i] != null) {
                Type vtype = lvar[i].sym.type;
                if (!(vtype instanceof UninitializedType))
                    vtype = types.erasure(vtype);
                locals[i] = vtype;
                if (width(vtype) > 1) i++;
            }
        }
        frame.locals = new Type[localCount];
        for (int i=0, j=0; i<localsSize; i++, j++) {
            Assert.check(j < localCount);
            frame.locals[j] = locals[i];
            if (width(locals[i]) > 1) i++;
        }

        int stackCount = 0;
        for (int i=0; i<state.stacksize; i++) {
            if (state.stack[i] != null) {
                stackCount++;
            }
        }
        frame.stack = new Type[stackCount];
        stackCount = 0;
        for (int i=0; i<state.stacksize; i++) {
            if (state.stack[i] != null) {
                frame.stack[stackCount++] = types.erasure(state.stack[i]);
            }
        }

        if (stackMapTableBuffer == null) {
            stackMapTableBuffer = new StackMapTableFrame[20];
        } else {
            stackMapTableBuffer = ArrayUtils.ensureCapacity(
                                    stackMapTableBuffer,
                                    stackMapBufferSize);
        }
        stackMapTableBuffer[stackMapBufferSize++] =
                StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);

        frameBeforeLast = lastFrame;
        lastFrame = frame;
    }

    StackMapFrame getInitialFrame() {
        StackMapFrame frame = new StackMapFrame();
        List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
        int len = arg_types.length();
        int count = 0;
        if (!meth.isStatic()) {
            Type thisType = meth.owner.type;
            frame.locals = new Type[len+1];
            if (meth.isConstructor() && thisType != syms.objectType) {
                frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
            } else {
                frame.locals[count++] = types.erasure(thisType);
            }
        } else {
            frame.locals = new Type[len];
        }
        for (Type arg_type : arg_types) {
            frame.locals[count++] = types.erasure(arg_type);
        }
        frame.pc = -1;
        frame.stack = null;
        return frame;
    }


/**************************************************************************
 * Operations having to do with jumps
 *************************************************************************/

    /** A chain represents a list of unresolved jumps. Jump locations
     *  are sorted in decreasing order.
     */
    public static class Chain {

        /** The position of the jump instruction.
         */
        public final int pc;

        /** The machine state after the jump instruction.
         *  Invariant: all elements of a chain list have the same stacksize
         *  and compatible stack and register contents.
         */
        Code.State state;

        /** The next jump in the list.
         */
        public final Chain next;

        /** Construct a chain from its jump position, stacksize, previous
         *  chain, and machine state.
         */
        public Chain(int pc, Chain next, Code.State state) {
            this.pc = pc;
            this.next = next;
            this.state = state;
        }
    }

    /** Negate a branch opcode.
     */
    public static int negate(int opcode) {
        if (opcode == if_acmp_null) return if_acmp_nonnull;
        else if (opcode == if_acmp_nonnull) return if_acmp_null;
        else return ((opcode + 1) ^ 1) - 1;
    }

    /** Emit a jump instruction.
     *  Return code pointer of instruction to be patched.
     */
    public int emitJump(int opcode) {
        if (fatcode) {
            if (opcode == goto_ || opcode == jsr) {
                emitop4(opcode + goto_w - goto_, 0);
            } else {
                emitop2(negate(opcode), 8);
                emitop4(goto_w, 0);
                alive = true;
                pendingStackMap = needStackMap;
            }
            return cp - 5;
        } else {
            emitop2(opcode, 0);
            return cp - 3;
        }
    }

    /** Emit a branch with given opcode; return its chain.
     *  branch differs from jump in that jsr is treated as no-op.
     */
    public Chain branch(int opcode) {
        Chain result = null;
        if (opcode == goto_) {
            result = pendingJumps;
            pendingJumps = null;
        }
        if (opcode != dontgoto && isAlive()) {
            result = new Chain(emitJump(opcode),
                               result,
                               state.dup());
            fixedPc = fatcode;
            if (opcode == goto_) alive = false;
        }
        return result;
    }

    /** Resolve chain to point to given target.
     */
    public void resolve(Chain chain, int target) {
        boolean changed = false;
        State newState = state;
        for (; chain != null; chain = chain.next) {
            Assert.check(state != chain.state
                    && (target > chain.pc || state.stacksize == 0));
            if (target >= cp) {
                target = cp;
            } else if (get1(target) == goto_) {
                if (fatcode) target = target + get4(target + 1);
                else target = target + get2(target + 1);
            }
            if (get1(chain.pc) == goto_ &&
                chain.pc + 3 == target && target == cp && !fixedPc) {
                // If goto the next instruction, the jump is not needed:
                // compact the code.
                if (varDebugInfo) {
                    adjustAliveRanges(cp, -3);
                }
                cp = cp - 3;
                target = target - 3;
                if (chain.next == null) {
                    // This is the only jump to the target. Exit the loop
                    // without setting new state. The code is reachable
                    // from the instruction before goto_.
                    alive = true;
                    break;
                }
            } else {
                if (fatcode)
                    put4(chain.pc + 1, target - chain.pc);
                else if (target - chain.pc < Short.MIN_VALUE ||
                         target - chain.pc > Short.MAX_VALUE)
                    fatcode = true;
                else
                    put2(chain.pc + 1, target - chain.pc);
                Assert.check(!alive ||
                    chain.state.stacksize == newState.stacksize &&
                    chain.state.nlocks == newState.nlocks);
            }
            fixedPc = true;
            if (cp == target) {
                changed = true;
                if (debugCode)
                    System.err.println("resolving chain state=" + chain.state);
                if (alive) {
                    newState = chain.state.join(newState);
                } else {
                    newState = chain.state;
                    alive = true;
                }
            }
        }
        Assert.check(!changed || state != newState);
        if (state != newState) {
            setDefined(newState.defined);
            state = newState;
            pendingStackMap = needStackMap;
        }
    }

    /** Resolve chain to point to current code pointer.
     */
    public void resolve(Chain chain) {
        Assert.check(
            !alive ||
            chain==null ||
            state.stacksize == chain.state.stacksize &&
            state.nlocks == chain.state.nlocks);
        pendingJumps = mergeChains(chain, pendingJumps);
    }

    /** Resolve any pending jumps.
     */
    public void resolvePending() {
        Chain x = pendingJumps;
        pendingJumps = null;
        resolve(x, cp);
    }

    /** Merge the jumps in of two chains into one.
     */
    public static Chain mergeChains(Chain chain1, Chain chain2) {
        // recursive merge sort
        if (chain2 == null) return chain1;
        if (chain1 == null) return chain2;
        Assert.check(
            chain1.state.stacksize == chain2.state.stacksize &&
            chain1.state.nlocks == chain2.state.nlocks);
        if (chain1.pc < chain2.pc)
            return new Chain(
                chain2.pc,
                mergeChains(chain1, chain2.next),
                chain2.state);
        return new Chain(
                chain1.pc,
                mergeChains(chain1.next, chain2),
                chain1.state);
    }


/* **************************************************************************
 * Catch clauses
 ****************************************************************************/

    /** Add a catch clause to code.
     */
    public void addCatch(
        char startPc, char endPc, char handlerPc, char catchType) {
            catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
        }


    public void compressCatchTable() {
        ListBuffer<char[]> compressedCatchInfo = new ListBuffer<>();
        List<Integer> handlerPcs = List.nil();
        for (char[] catchEntry : catchInfo) {
            handlerPcs = handlerPcs.prepend((int)catchEntry[2]);
        }
        for (char[] catchEntry : catchInfo) {
            int startpc = catchEntry[0];
            int endpc = catchEntry[1];
            if (startpc == endpc ||
                    (startpc == (endpc - 1) &&
                    handlerPcs.contains(startpc))) {
                continue;
            } else {
                compressedCatchInfo.append(catchEntry);
            }
        }
        catchInfo = compressedCatchInfo;
    }


/* **************************************************************************
 * Line numbers
 ****************************************************************************/

    /** Add a line number entry.
     */
    public void addLineNumber(char startPc, char lineNumber) {
        if (lineDebugInfo) {
            if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
                lineInfo = lineInfo.tail;
            if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
                lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
        }
    }

    /** Mark beginning of statement.
     */
    public void statBegin(int pos) {
        if (pos != Position.NOPOS) {
            pendingStatPos = pos;
        }
    }

    /** Force stat begin eagerly
     */
    public void markStatBegin() {
        if (alive && lineDebugInfo) {
            int line = lineMap.getLineNumber(pendingStatPos);
            char cp1 = (char)cp;
            char line1 = (char)line;
            if (cp1 == cp && line1 == line)
                addLineNumber(cp1, line1);
        }
        pendingStatPos = Position.NOPOS;
    }


/* **************************************************************************
 * Simulated VM machine state
 ****************************************************************************/

    class State implements Cloneable {
        /** The set of registers containing values. */
        Bits defined;

        /** The (types of the) contents of the machine stack. */
        Type[] stack;

        /** The first stack position currently unused. */
        int stacksize;

        /** The numbers of registers containing locked monitors. */
        int[] locks;
        int nlocks;

        State() {
            defined = new Bits();
            stack = new Type[16];
        }

        State dup() {
            try {
                State state = (State)super.clone();
                state.defined = new Bits(defined);
                state.stack = stack.clone();
                if (locks != null) state.locks = locks.clone();
                if (debugCode) {
                    System.err.println("duping state " + this);
                    dump();
                }
                return state;
            } catch (CloneNotSupportedException ex) {
                throw new AssertionError(ex);
            }
        }

        void lock(int register) {
            if (locks == null) {
                locks = new int[20];
            } else {
                locks = ArrayUtils.ensureCapacity(locks, nlocks);
            }
            locks[nlocks] = register;
            nlocks++;
        }

        void unlock(int register) {
            nlocks--;
            Assert.check(locks[nlocks] == register);
            locks[nlocks] = -1;
        }

        void push(Type t) {
            if (debugCode) System.err.println("   pushing " + t);
            switch (t.getTag()) {
            case VOID:
                return;
            case BYTE:
            case CHAR:
            case SHORT:
            case BOOLEAN:
                t = syms.intType;
                break;
            default:
                break;
            }
            stack = ArrayUtils.ensureCapacity(stack, stacksize+2);
            stack[stacksize++] = t;
            switch (width(t)) {
            case 1:
                break;
            case 2:
                stack[stacksize++] = null;
                break;
            default:
                throw new AssertionError(t);
            }
            if (stacksize > max_stack)
                max_stack = stacksize;
        }

        Type pop1() {
            if (debugCode) System.err.println("   popping " + 1);
            stacksize--;
            Type result = stack[stacksize];
            stack[stacksize] = null;
            Assert.check(result != null && width(result) == 1);
            return result;
        }

        Type peek() {
            return stack[stacksize-1];
        }

        Type pop2() {
            if (debugCode) System.err.println("   popping " + 2);
            stacksize -= 2;
            Type result = stack[stacksize];
            stack[stacksize] = null;
            Assert.check(stack[stacksize+1] == null
                    && result != null && width(result) == 2);
            return result;
        }

        void pop(int n) {
            if (debugCode) System.err.println("   popping " + n);
            while (n > 0) {
                stack[--stacksize] = null;
                n--;
            }
        }

        void pop(Type t) {
            pop(width(t));
        }

        /** Force the top of the stack to be treated as this supertype
         *  of its current type. */
        void forceStackTop(Type t) {
            if (!alive) return;
            switch (t.getTag()) {
            case CLASS:
            case ARRAY:
                int width = width(t);
                Type old = stack[stacksize-width];
                Assert.check(types.isSubtype(types.erasure(old),
                                       types.erasure(t)));
                stack[stacksize-width] = t;
                break;
            default:
            }
        }

        void markInitialized(UninitializedType old) {
            Type newtype = old.initializedType();
            for (int i=0; i<stacksize; i++) {
                if (stack[i] == old) stack[i] = newtype;
            }
            for (int i=0; i<lvar.length; i++) {
                LocalVar lv = lvar[i];
                if (lv != null && lv.sym.type == old) {
                    VarSymbol sym = lv.sym;
                    sym = sym.clone(sym.owner);
                    sym.type = newtype;
                    LocalVar newlv = lvar[i] = new LocalVar(sym);
                    newlv.aliveRanges = lv.aliveRanges;
                }
            }
        }

        State join(State other) {
            defined.andSet(other.defined);
            Assert.check(stacksize == other.stacksize
                    && nlocks == other.nlocks);
            for (int i=0; i<stacksize; ) {
                Type t = stack[i];
                Type tother = other.stack[i];
                Type result =
                    t==tother ? t :
                    types.isSubtype(t, tother) ? tother :
                    types.isSubtype(tother, t) ? t :
                    error();
                int w = width(result);
                stack[i] = result;
                if (w == 2) Assert.checkNull(stack[i+1]);
                i += w;
            }
            return this;
        }

        Type error() {
            throw new AssertionError("inconsistent stack types at join point");
        }

        void dump() {
            dump(-1);
        }

        void dump(int pc) {
            System.err.print("stackMap for " + meth.owner + "." + meth);
            if (pc == -1)
                System.out.println();
            else
                System.out.println(" at " + pc);
            System.err.println(" stack (from bottom):");
            for (int i=0; i<stacksize; i++)
                System.err.println("  " + i + ": " + stack[i]);

            int lastLocal = 0;
            for (int i=max_locals-1; i>=0; i--) {
                if (defined.isMember(i)) {
                    lastLocal = i;
                    break;
                }
            }
            if (lastLocal >= 0)
                System.err.println(" locals:");
            for (int i=0; i<=lastLocal; i++) {
                System.err.print("  " + i + ": ");
                if (defined.isMember(i)) {
                    LocalVar var = lvar[i];
                    if (var == null) {
                        System.err.println("(none)");
                    } else if (var.sym == null)
                        System.err.println("UNKNOWN!");
                    else
                        System.err.println("" + var.sym + " of type " +
                                           var.sym.erasure(types));
                } else {
                    System.err.println("undefined");
                }
            }
            if (nlocks != 0) {
                System.err.print(" locks:");
                for (int i=0; i<nlocks; i++) {
                    System.err.print(" " + locks[i]);
                }
                System.err.println();
            }
        }
    }

    static final Type jsrReturnValue = new JCPrimitiveType(INT, null);


/* **************************************************************************
 * Local variables
 ****************************************************************************/

    /** A live range of a local variable. */
    static class LocalVar {
        final VarSymbol sym;
        final char reg;

        class Range {
            char start_pc = Character.MAX_VALUE;
            char length = Character.MAX_VALUE;

            Range() {}

            Range(char start) {
                this.start_pc = start;
            }

            Range(char start, char length) {
                this.start_pc = start;
                this.length = length;
            }

            boolean closed() {
                return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE;
            }

            @Override
            public String toString() {
                int currentStartPC = start_pc;
                int currentLength = length;
                return "startpc = " + currentStartPC + " length " + currentLength;
            }
        }

        java.util.List<Range> aliveRanges = new java.util.ArrayList<>();

        LocalVar(VarSymbol v) {
            this.sym = v;
            this.reg = (char)v.adr;
        }
        public LocalVar dup() {
            return new LocalVar(sym);
        }

        Range firstRange() {
            return aliveRanges.isEmpty() ? null : aliveRanges.get(0);
        }

        Range lastRange() {
            return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
        }

        void removeLastRange() {
            Range lastRange = lastRange();
            if (lastRange != null) {
                aliveRanges.remove(lastRange);
            }
        }

        @Override
        public String toString() {
            if (aliveRanges == null) {
                return "empty local var";
            }
            StringBuilder sb = new StringBuilder().append(sym)
                    .append(" in register ").append((int)reg).append(" \n");
            for (Range r : aliveRanges) {
                sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc)))
                    .append(" length=").append(Integer.toString(((int)r.length)))
                    .append("\n");
            }
            return sb.toString();
        }

        public void openRange(char start) {
            if (!hasOpenRange()) {
                aliveRanges.add(new Range(start));
            }
        }

        public void closeRange(char length) {
            if (isLastRangeInitialized() && length > 0) {
                Range range = lastRange();
                if (range != null) {
                    if (range.length == Character.MAX_VALUE) {
                        range.length = length;
                    }
                }
            } else {
                removeLastRange();
            }
        }

        public boolean hasOpenRange() {
            if (aliveRanges.isEmpty()) {
                return false;
            }
            return lastRange().length == Character.MAX_VALUE;
        }

        public boolean isLastRangeInitialized() {
            if (aliveRanges.isEmpty()) {
                return false;
            }
            return lastRange().start_pc != Character.MAX_VALUE;
        }

        public Range getWidestRange() {
            if (aliveRanges.isEmpty()) {
                return new Range();
            } else {
                Range firstRange = firstRange();
                Range lastRange = lastRange();
                char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc));
                return new Range(firstRange.start_pc, length);
            }
         }

    };

    /** Local variables, indexed by register. */
    LocalVar[] lvar;

    /** Add a new local variable. */
    private void addLocalVar(VarSymbol v) {
        int adr = v.adr;
        lvar = ArrayUtils.ensureCapacity(lvar, adr+1);
        Assert.checkNull(lvar[adr]);
        if (pendingJumps != null) {
            resolvePending();
        }
        lvar[adr] = new LocalVar(v);
        state.defined.excl(adr);
    }

    void adjustAliveRanges(int oldCP, int delta) {
        for (LocalVar localVar: lvar) {
            if (localVar != null) {
                for (LocalVar.Range range: localVar.aliveRanges) {
                    if (range.closed() && range.start_pc + range.length >= oldCP) {
                        range.length += delta;
                    }
                }
            }
        }
    }

    /**
     * Calculates the size of the LocalVariableTable.
     */
    public int getLVTSize() {
        int result = varBufferSize;
        for (int i = 0; i < varBufferSize; i++) {
            LocalVar var = varBuffer[i];
            result += var.aliveRanges.size() - 1;
        }
        return result;
    }

    /** Set the current variable defined state. */
    public void setDefined(Bits newDefined) {
        if (alive && newDefined != state.defined) {
            Bits diff = new Bits(state.defined).xorSet(newDefined);
            for (int adr = diff.nextBit(0);
                 adr >= 0;
                 adr = diff.nextBit(adr+1)) {
                if (adr >= nextreg)
                    state.defined.excl(adr);
                else if (state.defined.isMember(adr))
                    setUndefined(adr);
                else
                    setDefined(adr);
            }
        }
    }

    /** Mark a register as being (possibly) defined. */
    public void setDefined(int adr) {
        LocalVar v = lvar[adr];
        if (v == null) {
            state.defined.excl(adr);
        } else {
            state.defined.incl(adr);
            if (cp < Character.MAX_VALUE) {
                v.openRange((char)cp);
            }
        }
    }

    /** Mark a register as being undefined. */
    public void setUndefined(int adr) {
        state.defined.excl(adr);
        if (adr < lvar.length &&
            lvar[adr] != null &&
            lvar[adr].isLastRangeInitialized()) {
            LocalVar v = lvar[adr];
            char length = (char)(curCP() - v.lastRange().start_pc);
            if (length < Character.MAX_VALUE) {
                lvar[adr] = v.dup();
                v.closeRange(length);
                putVar(v);
            } else {
                v.removeLastRange();
            }
        }
    }

    /** End the scope of a variable. */
    private void endScope(int adr) {
        LocalVar v = lvar[adr];
        if (v != null) {
            if (v.isLastRangeInitialized()) {
                char length = (char)(curCP() - v.lastRange().start_pc);
                if (length < Character.MAX_VALUE) {
                    v.closeRange(length);
                    putVar(v);
                    fillLocalVarPosition(v);
                }
            }
            /** the call to curCP() can implicitly adjust the current cp, if so
             * the alive range of local variables may be modified. Thus we need
             * all of them. For this reason assigning null to the given address
             * should be the last action to do.
             */
            lvar[adr] = null;
        }
        state.defined.excl(adr);
    }

    private void fillLocalVarPosition(LocalVar lv) {
        if (lv == null || lv.sym == null || !lv.sym.hasTypeAnnotations())
            return;
        for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
            TypeAnnotationPosition p = ta.position;
            LocalVar.Range widestRange = lv.getWidestRange();
            p.lvarOffset = new int[] { (int)widestRange.start_pc };
            p.lvarLength = new int[] { (int)widestRange.length };
            p.lvarIndex = new int[] { (int)lv.reg };
            p.isValidOffset = true;
        }
    }

    // Method to be called after compressCatchTable to
    // fill in the exception table index for type
    // annotations on exception parameters.
    public void fillExceptionParameterPositions() {
        for (int i = 0; i < varBufferSize; ++i) {
            LocalVar lv = varBuffer[i];
            if (lv == null || lv.sym == null
                    || !lv.sym.hasTypeAnnotations()
                    || !lv.sym.isExceptionParameter())
                continue;

            for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
                TypeAnnotationPosition p = ta.position;
                // At this point p.type_index contains the catch type index.
                // Use that index to determine the exception table index.
                // We can afterwards discard the type_index.
                // A TA position is shared for all type annotations in the
                // same location; updating one is enough.
                // Use -666 as a marker that the exception_index was already updated.
                if (p.type_index != -666) {
                    p.exception_index = findExceptionIndex(p.type_index);
                    p.type_index = -666;
                }
            }
        }
    }

    private int findExceptionIndex(int catchType) {
        if (catchType == Integer.MIN_VALUE) {
            // We didn't set the catch type index correctly.
            // This shouldn't happen.
            // TODO: issue error?
            return -1;
        }
        List<char[]> iter = catchInfo.toList();
        int len = catchInfo.length();
        for (int i = 0; i < len; ++i) {
            char[] catchEntry = iter.head;
            iter = iter.tail;
            char ct = catchEntry[3];
            if (catchType == ct) {
                return i;
            }
        }
        return -1;
    }

    /** Put a live variable range into the buffer to be output to the
     *  class file.
     */
    void putVar(LocalVar var) {
        // Keep local variables if
        // 1) we need them for debug information
        // 2) it is an exception type and it contains type annotations
        boolean keepLocalVariables = varDebugInfo ||
            (var.sym.isExceptionParameter() && var.sym.hasTypeAnnotations());
        if (!keepLocalVariables) return;
        //don't keep synthetic vars, unless they are lambda method parameters
        boolean ignoredSyntheticVar = (var.sym.flags() & Flags.SYNTHETIC) != 0 &&
                ((var.sym.owner.flags() & Flags.LAMBDA_METHOD) == 0 ||
                 (var.sym.flags() & Flags.PARAMETER) == 0);
        if (ignoredSyntheticVar) return;
        if (varBuffer == null)
            varBuffer = new LocalVar[20];
        else
            varBuffer = ArrayUtils.ensureCapacity(varBuffer, varBufferSize);
        varBuffer[varBufferSize++] = var;
    }

    /** Previously live local variables, to be put into the variable table. */
    LocalVar[] varBuffer;
    int varBufferSize;

    /** Create a new local variable address and return it.
     */
    private int newLocal(int typecode) {
        int reg = nextreg;
        int w = width(typecode);
        nextreg = reg + w;
        if (nextreg > max_locals) max_locals = nextreg;
        return reg;
    }

    private int newLocal(Type type) {
        return newLocal(typecode(type));
    }

    public int newLocal(VarSymbol v) {
        int reg = v.adr = newLocal(v.erasure(types));
        addLocalVar(v);
        return reg;
    }

    /** Start a set of fresh registers.
     */
    public void newRegSegment() {
        nextreg = max_locals;
    }

    /** End scopes of all variables with registers &ge; first.
     */
    public void endScopes(int first) {
        int prevNextReg = nextreg;
        nextreg = first;
        for (int i = nextreg; i < prevNextReg; i++) endScope(i);
    }

/**************************************************************************
 * static tables
 *************************************************************************/

    public static String mnem(int opcode) {
        return Mneumonics.mnem[opcode];
    }

    private static class Mneumonics {
        private final static String[] mnem = new String[ByteCodeCount];
        static {
            mnem[nop] = "nop";
            mnem[aconst_null] = "aconst_null";
            mnem[iconst_m1] = "iconst_m1";
            mnem[iconst_0] = "iconst_0";
            mnem[iconst_1] = "iconst_1";
            mnem[iconst_2] = "iconst_2";
            mnem[iconst_3] = "iconst_3";
            mnem[iconst_4] = "iconst_4";
            mnem[iconst_5] = "iconst_5";
            mnem[lconst_0] = "lconst_0";
            mnem[lconst_1] = "lconst_1";
            mnem[fconst_0] = "fconst_0";
            mnem[fconst_1] = "fconst_1";
            mnem[fconst_2] = "fconst_2";
            mnem[dconst_0] = "dconst_0";
            mnem[dconst_1] = "dconst_1";
            mnem[bipush] = "bipush";
            mnem[sipush] = "sipush";
            mnem[ldc1] = "ldc1";
            mnem[ldc2] = "ldc2";
            mnem[ldc2w] = "ldc2w";
            mnem[iload] = "iload";
            mnem[lload] = "lload";
            mnem[fload] = "fload";
            mnem[dload] = "dload";
            mnem[aload] = "aload";
            mnem[iload_0] = "iload_0";
            mnem[lload_0] = "lload_0";
            mnem[fload_0] = "fload_0";
            mnem[dload_0] = "dload_0";
            mnem[aload_0] = "aload_0";
            mnem[iload_1] = "iload_1";
            mnem[lload_1] = "lload_1";
            mnem[fload_1] = "fload_1";
            mnem[dload_1] = "dload_1";
            mnem[aload_1] = "aload_1";
            mnem[iload_2] = "iload_2";
            mnem[lload_2] = "lload_2";
            mnem[fload_2] = "fload_2";
            mnem[dload_2] = "dload_2";
            mnem[aload_2] = "aload_2";
            mnem[iload_3] = "iload_3";
            mnem[lload_3] = "lload_3";
            mnem[fload_3] = "fload_3";
            mnem[dload_3] = "dload_3";
            mnem[aload_3] = "aload_3";
            mnem[iaload] = "iaload";
            mnem[laload] = "laload";
            mnem[faload] = "faload";
            mnem[daload] = "daload";
            mnem[aaload] = "aaload";
            mnem[baload] = "baload";
            mnem[caload] = "caload";
            mnem[saload] = "saload";
            mnem[istore] = "istore";
            mnem[lstore] = "lstore";
            mnem[fstore] = "fstore";
            mnem[dstore] = "dstore";
            mnem[astore] = "astore";
            mnem[istore_0] = "istore_0";
            mnem[lstore_0] = "lstore_0";
            mnem[fstore_0] = "fstore_0";
            mnem[dstore_0] = "dstore_0";
            mnem[astore_0] = "astore_0";
            mnem[istore_1] = "istore_1";
            mnem[lstore_1] = "lstore_1";
            mnem[fstore_1] = "fstore_1";
            mnem[dstore_1] = "dstore_1";
            mnem[astore_1] = "astore_1";
            mnem[istore_2] = "istore_2";
            mnem[lstore_2] = "lstore_2";
            mnem[fstore_2] = "fstore_2";
            mnem[dstore_2] = "dstore_2";
            mnem[astore_2] = "astore_2";
            mnem[istore_3] = "istore_3";
            mnem[lstore_3] = "lstore_3";
            mnem[fstore_3] = "fstore_3";
            mnem[dstore_3] = "dstore_3";
            mnem[astore_3] = "astore_3";
            mnem[iastore] = "iastore";
            mnem[lastore] = "lastore";
            mnem[fastore] = "fastore";
            mnem[dastore] = "dastore";
            mnem[aastore] = "aastore";
            mnem[bastore] = "bastore";
            mnem[castore] = "castore";
            mnem[sastore] = "sastore";
            mnem[pop] = "pop";
            mnem[pop2] = "pop2";
            mnem[dup] = "dup";
            mnem[dup_x1] = "dup_x1";
            mnem[dup_x2] = "dup_x2";
            mnem[dup2] = "dup2";
            mnem[dup2_x1] = "dup2_x1";
            mnem[dup2_x2] = "dup2_x2";
            mnem[swap] = "swap";
            mnem[iadd] = "iadd";
            mnem[ladd] = "ladd";
            mnem[fadd] = "fadd";
            mnem[dadd] = "dadd";
            mnem[isub] = "isub";
            mnem[lsub] = "lsub";
            mnem[fsub] = "fsub";
            mnem[dsub] = "dsub";
            mnem[imul] = "imul";
            mnem[lmul] = "lmul";
            mnem[fmul] = "fmul";
            mnem[dmul] = "dmul";
            mnem[idiv] = "idiv";
            mnem[ldiv] = "ldiv";
            mnem[fdiv] = "fdiv";
            mnem[ddiv] = "ddiv";
            mnem[imod] = "imod";
            mnem[lmod] = "lmod";
            mnem[fmod] = "fmod";
            mnem[dmod] = "dmod";
            mnem[ineg] = "ineg";
            mnem[lneg] = "lneg";
            mnem[fneg] = "fneg";
            mnem[dneg] = "dneg";
            mnem[ishl] = "ishl";
            mnem[lshl] = "lshl";
            mnem[ishr] = "ishr";
            mnem[lshr] = "lshr";
            mnem[iushr] = "iushr";
            mnem[lushr] = "lushr";
            mnem[iand] = "iand";
            mnem[land] = "land";
            mnem[ior] = "ior";
            mnem[lor] = "lor";
            mnem[ixor] = "ixor";
            mnem[lxor] = "lxor";
            mnem[iinc] = "iinc";
            mnem[i2l] = "i2l";
            mnem[i2f] = "i2f";
            mnem[i2d] = "i2d";
            mnem[l2i] = "l2i";
            mnem[l2f] = "l2f";
            mnem[l2d] = "l2d";
            mnem[f2i] = "f2i";
            mnem[f2l] = "f2l";
            mnem[f2d] = "f2d";
            mnem[d2i] = "d2i";
            mnem[d2l] = "d2l";
            mnem[d2f] = "d2f";
            mnem[int2byte] = "int2byte";
            mnem[int2char] = "int2char";
            mnem[int2short] = "int2short";
            mnem[lcmp] = "lcmp";
            mnem[fcmpl] = "fcmpl";
            mnem[fcmpg] = "fcmpg";
            mnem[dcmpl] = "dcmpl";
            mnem[dcmpg] = "dcmpg";
            mnem[ifeq] = "ifeq";
            mnem[ifne] = "ifne";
            mnem[iflt] = "iflt";
            mnem[ifge] = "ifge";
            mnem[ifgt] = "ifgt";
            mnem[ifle] = "ifle";
            mnem[if_icmpeq] = "if_icmpeq";
            mnem[if_icmpne] = "if_icmpne";
            mnem[if_icmplt] = "if_icmplt";
            mnem[if_icmpge] = "if_icmpge";
            mnem[if_icmpgt] = "if_icmpgt";
            mnem[if_icmple] = "if_icmple";
            mnem[if_acmpeq] = "if_acmpeq";
            mnem[if_acmpne] = "if_acmpne";
            mnem[goto_] = "goto_";
            mnem[jsr] = "jsr";
            mnem[ret] = "ret";
            mnem[tableswitch] = "tableswitch";
            mnem[lookupswitch] = "lookupswitch";
            mnem[ireturn] = "ireturn";
            mnem[lreturn] = "lreturn";
            mnem[freturn] = "freturn";
            mnem[dreturn] = "dreturn";
            mnem[areturn] = "areturn";
            mnem[return_] = "return_";
            mnem[getstatic] = "getstatic";
            mnem[putstatic] = "putstatic";
            mnem[getfield] = "getfield";
            mnem[putfield] = "putfield";
            mnem[invokevirtual] = "invokevirtual";
            mnem[invokespecial] = "invokespecial";
            mnem[invokestatic] = "invokestatic";
            mnem[invokeinterface] = "invokeinterface";
            mnem[invokedynamic] = "invokedynamic";
            mnem[new_] = "new_";
            mnem[newarray] = "newarray";
            mnem[anewarray] = "anewarray";
            mnem[arraylength] = "arraylength";
            mnem[athrow] = "athrow";
            mnem[checkcast] = "checkcast";
            mnem[instanceof_] = "instanceof_";
            mnem[monitorenter] = "monitorenter";
            mnem[monitorexit] = "monitorexit";
            mnem[wide] = "wide";
            mnem[multianewarray] = "multianewarray";
            mnem[if_acmp_null] = "if_acmp_null";
            mnem[if_acmp_nonnull] = "if_acmp_nonnull";
            mnem[goto_w] = "goto_w";
            mnem[jsr_w] = "jsr_w";
            mnem[breakpoint] = "breakpoint";
        }
    }
}
