src/share/classes/com/sun/tools/javac/jvm/Code.java

changeset 0
959103a6100f
child 2525
2eb010b6cb22
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Wed Apr 27 01:34:52 2016 +0800
     1.3 @@ -0,0 +1,2460 @@
     1.4 +/*
     1.5 + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Oracle designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Oracle in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 + * or visit www.oracle.com if you need additional information or have any
    1.26 + * questions.
    1.27 + */
    1.28 +
    1.29 +package com.sun.tools.javac.jvm;
    1.30 +
    1.31 +import com.sun.tools.javac.code.*;
    1.32 +import com.sun.tools.javac.code.Symbol.*;
    1.33 +import com.sun.tools.javac.code.Types.UniqueType;
    1.34 +import com.sun.tools.javac.tree.JCTree;
    1.35 +import com.sun.tools.javac.util.*;
    1.36 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    1.37 +
    1.38 +import static com.sun.tools.javac.code.TypeTag.BOT;
    1.39 +import static com.sun.tools.javac.code.TypeTag.INT;
    1.40 +import static com.sun.tools.javac.jvm.ByteCodes.*;
    1.41 +import static com.sun.tools.javac.jvm.UninitializedType.*;
    1.42 +import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
    1.43 +
    1.44 +/** An internal structure that corresponds to the code attribute of
    1.45 + *  methods in a classfile. The class also provides some utility operations to
    1.46 + *  generate bytecode instructions.
    1.47 + *
    1.48 + *  <p><b>This is NOT part of any supported API.
    1.49 + *  If you write code that depends on this, you do so at your own risk.
    1.50 + *  This code and its internal interfaces are subject to change or
    1.51 + *  deletion without notice.</b>
    1.52 + */
    1.53 +public class Code {
    1.54 +
    1.55 +    public final boolean debugCode;
    1.56 +    public final boolean needStackMap;
    1.57 +
    1.58 +    public enum StackMapFormat {
    1.59 +        NONE,
    1.60 +        CLDC {
    1.61 +            Name getAttributeName(Names names) {
    1.62 +                return names.StackMap;
    1.63 +            }
    1.64 +        },
    1.65 +        JSR202 {
    1.66 +            Name getAttributeName(Names names) {
    1.67 +                return names.StackMapTable;
    1.68 +            }
    1.69 +        };
    1.70 +        Name getAttributeName(Names names) {
    1.71 +            return names.empty;
    1.72 +        }
    1.73 +    }
    1.74 +
    1.75 +    final Types types;
    1.76 +    final Symtab syms;
    1.77 +
    1.78 +/*---------- classfile fields: --------------- */
    1.79 +
    1.80 +    /** The maximum stack size.
    1.81 +     */
    1.82 +    public int max_stack = 0;
    1.83 +
    1.84 +    /** The maximum number of local variable slots.
    1.85 +     */
    1.86 +    public int max_locals = 0;
    1.87 +
    1.88 +    /** The code buffer.
    1.89 +     */
    1.90 +    public byte[] code = new byte[64];
    1.91 +
    1.92 +    /** the current code pointer.
    1.93 +     */
    1.94 +    public int cp = 0;
    1.95 +
    1.96 +    /** Check the code against VM spec limits; if
    1.97 +     *  problems report them and return true.
    1.98 +     */
    1.99 +    public boolean checkLimits(DiagnosticPosition pos, Log log) {
   1.100 +        if (cp > ClassFile.MAX_CODE) {
   1.101 +            log.error(pos, "limit.code");
   1.102 +            return true;
   1.103 +        }
   1.104 +        if (max_locals > ClassFile.MAX_LOCALS) {
   1.105 +            log.error(pos, "limit.locals");
   1.106 +            return true;
   1.107 +        }
   1.108 +        if (max_stack > ClassFile.MAX_STACK) {
   1.109 +            log.error(pos, "limit.stack");
   1.110 +            return true;
   1.111 +        }
   1.112 +        return false;
   1.113 +    }
   1.114 +
   1.115 +    /** A buffer for expression catch data. Each enter is a vector
   1.116 +     *  of four unsigned shorts.
   1.117 +     */
   1.118 +    ListBuffer<char[]> catchInfo = new ListBuffer<char[]>();
   1.119 +
   1.120 +    /** A buffer for line number information. Each entry is a vector
   1.121 +     *  of two unsigned shorts.
   1.122 +     */
   1.123 +    List<char[]> lineInfo = List.nil(); // handled in stack fashion
   1.124 +
   1.125 +    /** The CharacterRangeTable
   1.126 +     */
   1.127 +    public CRTable crt;
   1.128 +
   1.129 +/*---------- internal fields: --------------- */
   1.130 +
   1.131 +    /** Are we generating code with jumps &ge; 32K?
   1.132 +     */
   1.133 +    public boolean fatcode;
   1.134 +
   1.135 +    /** Code generation enabled?
   1.136 +     */
   1.137 +    private boolean alive = true;
   1.138 +
   1.139 +    /** The current machine state (registers and stack).
   1.140 +     */
   1.141 +    State state;
   1.142 +
   1.143 +    /** Is it forbidden to compactify code, because something is
   1.144 +     *  pointing to current location?
   1.145 +     */
   1.146 +    private boolean fixedPc = false;
   1.147 +
   1.148 +    /** The next available register.
   1.149 +     */
   1.150 +    public int nextreg = 0;
   1.151 +
   1.152 +    /** A chain for jumps to be resolved before the next opcode is emitted.
   1.153 +     *  We do this lazily to avoid jumps to jumps.
   1.154 +     */
   1.155 +    Chain pendingJumps = null;
   1.156 +
   1.157 +    /** The position of the currently statement, if we are at the
   1.158 +     *  start of this statement, NOPOS otherwise.
   1.159 +     *  We need this to emit line numbers lazily, which we need to do
   1.160 +     *  because of jump-to-jump optimization.
   1.161 +     */
   1.162 +    int pendingStatPos = Position.NOPOS;
   1.163 +
   1.164 +    /** Set true when a stackMap is needed at the current PC. */
   1.165 +    boolean pendingStackMap = false;
   1.166 +
   1.167 +    /** The stack map format to be generated. */
   1.168 +    StackMapFormat stackMap;
   1.169 +
   1.170 +    /** Switch: emit variable debug info.
   1.171 +     */
   1.172 +    boolean varDebugInfo;
   1.173 +
   1.174 +    /** Switch: emit line number info.
   1.175 +     */
   1.176 +    boolean lineDebugInfo;
   1.177 +
   1.178 +    /** Emit line number info if map supplied
   1.179 +     */
   1.180 +    Position.LineMap lineMap;
   1.181 +
   1.182 +    /** The constant pool of the current class.
   1.183 +     */
   1.184 +    final Pool pool;
   1.185 +
   1.186 +    final MethodSymbol meth;
   1.187 +
   1.188 +    final LVTRanges lvtRanges;
   1.189 +
   1.190 +    /** Construct a code object, given the settings of the fatcode,
   1.191 +     *  debugging info switches and the CharacterRangeTable.
   1.192 +     */
   1.193 +    public Code(MethodSymbol meth,
   1.194 +                boolean fatcode,
   1.195 +                Position.LineMap lineMap,
   1.196 +                boolean varDebugInfo,
   1.197 +                StackMapFormat stackMap,
   1.198 +                boolean debugCode,
   1.199 +                CRTable crt,
   1.200 +                Symtab syms,
   1.201 +                Types types,
   1.202 +                Pool pool,
   1.203 +                LVTRanges lvtRanges) {
   1.204 +        this.meth = meth;
   1.205 +        this.fatcode = fatcode;
   1.206 +        this.lineMap = lineMap;
   1.207 +        this.lineDebugInfo = lineMap != null;
   1.208 +        this.varDebugInfo = varDebugInfo;
   1.209 +        this.crt = crt;
   1.210 +        this.syms = syms;
   1.211 +        this.types = types;
   1.212 +        this.debugCode = debugCode;
   1.213 +        this.stackMap = stackMap;
   1.214 +        switch (stackMap) {
   1.215 +        case CLDC:
   1.216 +        case JSR202:
   1.217 +            this.needStackMap = true;
   1.218 +            break;
   1.219 +        default:
   1.220 +            this.needStackMap = false;
   1.221 +        }
   1.222 +        state = new State();
   1.223 +        lvar = new LocalVar[20];
   1.224 +        this.pool = pool;
   1.225 +        this.lvtRanges = lvtRanges;
   1.226 +    }
   1.227 +
   1.228 +
   1.229 +/* **************************************************************************
   1.230 + * Typecodes & related stuff
   1.231 + ****************************************************************************/
   1.232 +
   1.233 +    /** Given a type, return its type code (used implicitly in the
   1.234 +     *  JVM architecture).
   1.235 +     */
   1.236 +    public static int typecode(Type type) {
   1.237 +        switch (type.getTag()) {
   1.238 +        case BYTE: return BYTEcode;
   1.239 +        case SHORT: return SHORTcode;
   1.240 +        case CHAR: return CHARcode;
   1.241 +        case INT: return INTcode;
   1.242 +        case LONG: return LONGcode;
   1.243 +        case FLOAT: return FLOATcode;
   1.244 +        case DOUBLE: return DOUBLEcode;
   1.245 +        case BOOLEAN: return BYTEcode;
   1.246 +        case VOID: return VOIDcode;
   1.247 +        case CLASS:
   1.248 +        case ARRAY:
   1.249 +        case METHOD:
   1.250 +        case BOT:
   1.251 +        case TYPEVAR:
   1.252 +        case UNINITIALIZED_THIS:
   1.253 +        case UNINITIALIZED_OBJECT:
   1.254 +            return OBJECTcode;
   1.255 +        default: throw new AssertionError("typecode " + type.getTag());
   1.256 +        }
   1.257 +    }
   1.258 +
   1.259 +    /** Collapse type code for subtypes of int to INTcode.
   1.260 +     */
   1.261 +    public static int truncate(int tc) {
   1.262 +        switch (tc) {
   1.263 +        case BYTEcode: case SHORTcode: case CHARcode: return INTcode;
   1.264 +        default: return tc;
   1.265 +        }
   1.266 +    }
   1.267 +
   1.268 +    /** The width in bytes of objects of the type.
   1.269 +     */
   1.270 +    public static int width(int typecode) {
   1.271 +        switch (typecode) {
   1.272 +        case LONGcode: case DOUBLEcode: return 2;
   1.273 +        case VOIDcode: return 0;
   1.274 +        default: return 1;
   1.275 +        }
   1.276 +    }
   1.277 +
   1.278 +    public static int width(Type type) {
   1.279 +        return type == null ? 1 : width(typecode(type));
   1.280 +    }
   1.281 +
   1.282 +    /** The total width taken up by a vector of objects.
   1.283 +     */
   1.284 +    public static int width(List<Type> types) {
   1.285 +        int w = 0;
   1.286 +        for (List<Type> l = types; l.nonEmpty(); l = l.tail)
   1.287 +            w = w + width(l.head);
   1.288 +        return w;
   1.289 +    }
   1.290 +
   1.291 +    /** Given a type, return its code for allocating arrays of that type.
   1.292 +     */
   1.293 +    public static int arraycode(Type type) {
   1.294 +        switch (type.getTag()) {
   1.295 +        case BYTE: return 8;
   1.296 +        case BOOLEAN: return 4;
   1.297 +        case SHORT: return 9;
   1.298 +        case CHAR: return 5;
   1.299 +        case INT: return 10;
   1.300 +        case LONG: return 11;
   1.301 +        case FLOAT: return 6;
   1.302 +        case DOUBLE: return 7;
   1.303 +        case CLASS: return 0;
   1.304 +        case ARRAY: return 1;
   1.305 +        default: throw new AssertionError("arraycode " + type);
   1.306 +        }
   1.307 +    }
   1.308 +
   1.309 +
   1.310 +/* **************************************************************************
   1.311 + * Emit code
   1.312 + ****************************************************************************/
   1.313 +
   1.314 +    /** The current output code pointer.
   1.315 +     */
   1.316 +    public int curCP() {
   1.317 +        /*
   1.318 +         * This method has side-effects because calling it can indirectly provoke
   1.319 +         *  extra code generation, like goto instructions, depending on the context
   1.320 +         *  where it's called.
   1.321 +         *  Use with care or even better avoid using it.
   1.322 +         */
   1.323 +        if (pendingJumps != null) {
   1.324 +            resolvePending();
   1.325 +        }
   1.326 +        if (pendingStatPos != Position.NOPOS) {
   1.327 +            markStatBegin();
   1.328 +        }
   1.329 +        fixedPc = true;
   1.330 +        return cp;
   1.331 +    }
   1.332 +
   1.333 +    /** Emit a byte of code.
   1.334 +     */
   1.335 +    private  void emit1(int od) {
   1.336 +        if (!alive) return;
   1.337 +        code = ArrayUtils.ensureCapacity(code, cp);
   1.338 +        code[cp++] = (byte)od;
   1.339 +    }
   1.340 +
   1.341 +    /** Emit two bytes of code.
   1.342 +     */
   1.343 +    private void emit2(int od) {
   1.344 +        if (!alive) return;
   1.345 +        if (cp + 2 > code.length) {
   1.346 +            emit1(od >> 8);
   1.347 +            emit1(od);
   1.348 +        } else {
   1.349 +            code[cp++] = (byte)(od >> 8);
   1.350 +            code[cp++] = (byte)od;
   1.351 +        }
   1.352 +    }
   1.353 +
   1.354 +    /** Emit four bytes of code.
   1.355 +     */
   1.356 +    public void emit4(int od) {
   1.357 +        if (!alive) return;
   1.358 +        if (cp + 4 > code.length) {
   1.359 +            emit1(od >> 24);
   1.360 +            emit1(od >> 16);
   1.361 +            emit1(od >> 8);
   1.362 +            emit1(od);
   1.363 +        } else {
   1.364 +            code[cp++] = (byte)(od >> 24);
   1.365 +            code[cp++] = (byte)(od >> 16);
   1.366 +            code[cp++] = (byte)(od >> 8);
   1.367 +            code[cp++] = (byte)od;
   1.368 +        }
   1.369 +    }
   1.370 +
   1.371 +    /** Emit an opcode.
   1.372 +     */
   1.373 +    private void emitop(int op) {
   1.374 +        if (pendingJumps != null) resolvePending();
   1.375 +        if (alive) {
   1.376 +            if (pendingStatPos != Position.NOPOS)
   1.377 +                markStatBegin();
   1.378 +            if (pendingStackMap) {
   1.379 +                pendingStackMap = false;
   1.380 +                emitStackMap();
   1.381 +            }
   1.382 +            if (debugCode)
   1.383 +                System.err.println("emit@" + cp + " stack=" +
   1.384 +                                   state.stacksize + ": " +
   1.385 +                                   mnem(op));
   1.386 +            emit1(op);
   1.387 +        }
   1.388 +    }
   1.389 +
   1.390 +    void postop() {
   1.391 +        Assert.check(alive || state.stacksize == 0);
   1.392 +    }
   1.393 +
   1.394 +    /** Emit a ldc (or ldc_w) instruction, taking into account operand size
   1.395 +    */
   1.396 +    public void emitLdc(int od) {
   1.397 +        if (od <= 255) {
   1.398 +            emitop1(ldc1, od);
   1.399 +        }
   1.400 +        else {
   1.401 +            emitop2(ldc2, od);
   1.402 +        }
   1.403 +    }
   1.404 +
   1.405 +    /** Emit a multinewarray instruction.
   1.406 +     */
   1.407 +    public void emitMultianewarray(int ndims, int type, Type arrayType) {
   1.408 +        emitop(multianewarray);
   1.409 +        if (!alive) return;
   1.410 +        emit2(type);
   1.411 +        emit1(ndims);
   1.412 +        state.pop(ndims);
   1.413 +        state.push(arrayType);
   1.414 +    }
   1.415 +
   1.416 +    /** Emit newarray.
   1.417 +     */
   1.418 +    public void emitNewarray(int elemcode, Type arrayType) {
   1.419 +        emitop(newarray);
   1.420 +        if (!alive) return;
   1.421 +        emit1(elemcode);
   1.422 +        state.pop(1); // count
   1.423 +        state.push(arrayType);
   1.424 +    }
   1.425 +
   1.426 +    /** Emit anewarray.
   1.427 +     */
   1.428 +    public void emitAnewarray(int od, Type arrayType) {
   1.429 +        emitop(anewarray);
   1.430 +        if (!alive) return;
   1.431 +        emit2(od);
   1.432 +        state.pop(1);
   1.433 +        state.push(arrayType);
   1.434 +    }
   1.435 +
   1.436 +    /** Emit an invokeinterface instruction.
   1.437 +     */
   1.438 +    public void emitInvokeinterface(int meth, Type mtype) {
   1.439 +        int argsize = width(mtype.getParameterTypes());
   1.440 +        emitop(invokeinterface);
   1.441 +        if (!alive) return;
   1.442 +        emit2(meth);
   1.443 +        emit1(argsize + 1);
   1.444 +        emit1(0);
   1.445 +        state.pop(argsize + 1);
   1.446 +        state.push(mtype.getReturnType());
   1.447 +    }
   1.448 +
   1.449 +    /** Emit an invokespecial instruction.
   1.450 +     */
   1.451 +    public void emitInvokespecial(int meth, Type mtype) {
   1.452 +        int argsize = width(mtype.getParameterTypes());
   1.453 +        emitop(invokespecial);
   1.454 +        if (!alive) return;
   1.455 +        emit2(meth);
   1.456 +        Symbol sym = (Symbol)pool.pool[meth];
   1.457 +        state.pop(argsize);
   1.458 +        if (sym.isConstructor())
   1.459 +            state.markInitialized((UninitializedType)state.peek());
   1.460 +        state.pop(1);
   1.461 +        state.push(mtype.getReturnType());
   1.462 +    }
   1.463 +
   1.464 +    /** Emit an invokestatic instruction.
   1.465 +     */
   1.466 +    public void emitInvokestatic(int meth, Type mtype) {
   1.467 +        int argsize = width(mtype.getParameterTypes());
   1.468 +        emitop(invokestatic);
   1.469 +        if (!alive) return;
   1.470 +        emit2(meth);
   1.471 +        state.pop(argsize);
   1.472 +        state.push(mtype.getReturnType());
   1.473 +    }
   1.474 +
   1.475 +    /** Emit an invokevirtual instruction.
   1.476 +     */
   1.477 +    public void emitInvokevirtual(int meth, Type mtype) {
   1.478 +        int argsize = width(mtype.getParameterTypes());
   1.479 +        emitop(invokevirtual);
   1.480 +        if (!alive) return;
   1.481 +        emit2(meth);
   1.482 +        state.pop(argsize + 1);
   1.483 +        state.push(mtype.getReturnType());
   1.484 +    }
   1.485 +
   1.486 +    /** Emit an invokedynamic instruction.
   1.487 +     */
   1.488 +    public void emitInvokedynamic(int desc, Type mtype) {
   1.489 +        int argsize = width(mtype.getParameterTypes());
   1.490 +        emitop(invokedynamic);
   1.491 +        if (!alive) return;
   1.492 +        emit2(desc);
   1.493 +        emit2(0);
   1.494 +        state.pop(argsize);
   1.495 +        state.push(mtype.getReturnType());
   1.496 +    }
   1.497 +
   1.498 +    /** Emit an opcode with no operand field.
   1.499 +     */
   1.500 +    public void emitop0(int op) {
   1.501 +        emitop(op);
   1.502 +        if (!alive) return;
   1.503 +        switch (op) {
   1.504 +        case aaload: {
   1.505 +            state.pop(1);// index
   1.506 +            Type a = state.stack[state.stacksize-1];
   1.507 +            state.pop(1);
   1.508 +            //sometimes 'null type' is treated as a one-dimensional array type
   1.509 +            //see Gen.visitLiteral - we should handle this case accordingly
   1.510 +            Type stackType = a.hasTag(BOT) ?
   1.511 +                syms.objectType :
   1.512 +                types.erasure(types.elemtype(a));
   1.513 +            state.push(stackType); }
   1.514 +            break;
   1.515 +        case goto_:
   1.516 +            markDead();
   1.517 +            break;
   1.518 +        case nop:
   1.519 +        case ineg:
   1.520 +        case lneg:
   1.521 +        case fneg:
   1.522 +        case dneg:
   1.523 +            break;
   1.524 +        case aconst_null:
   1.525 +            state.push(syms.botType);
   1.526 +            break;
   1.527 +        case iconst_m1:
   1.528 +        case iconst_0:
   1.529 +        case iconst_1:
   1.530 +        case iconst_2:
   1.531 +        case iconst_3:
   1.532 +        case iconst_4:
   1.533 +        case iconst_5:
   1.534 +        case iload_0:
   1.535 +        case iload_1:
   1.536 +        case iload_2:
   1.537 +        case iload_3:
   1.538 +            state.push(syms.intType);
   1.539 +            break;
   1.540 +        case lconst_0:
   1.541 +        case lconst_1:
   1.542 +        case lload_0:
   1.543 +        case lload_1:
   1.544 +        case lload_2:
   1.545 +        case lload_3:
   1.546 +            state.push(syms.longType);
   1.547 +            break;
   1.548 +        case fconst_0:
   1.549 +        case fconst_1:
   1.550 +        case fconst_2:
   1.551 +        case fload_0:
   1.552 +        case fload_1:
   1.553 +        case fload_2:
   1.554 +        case fload_3:
   1.555 +            state.push(syms.floatType);
   1.556 +            break;
   1.557 +        case dconst_0:
   1.558 +        case dconst_1:
   1.559 +        case dload_0:
   1.560 +        case dload_1:
   1.561 +        case dload_2:
   1.562 +        case dload_3:
   1.563 +            state.push(syms.doubleType);
   1.564 +            break;
   1.565 +        case aload_0:
   1.566 +            state.push(lvar[0].sym.type);
   1.567 +            break;
   1.568 +        case aload_1:
   1.569 +            state.push(lvar[1].sym.type);
   1.570 +            break;
   1.571 +        case aload_2:
   1.572 +            state.push(lvar[2].sym.type);
   1.573 +            break;
   1.574 +        case aload_3:
   1.575 +            state.push(lvar[3].sym.type);
   1.576 +            break;
   1.577 +        case iaload:
   1.578 +        case baload:
   1.579 +        case caload:
   1.580 +        case saload:
   1.581 +            state.pop(2);
   1.582 +            state.push(syms.intType);
   1.583 +            break;
   1.584 +        case laload:
   1.585 +            state.pop(2);
   1.586 +            state.push(syms.longType);
   1.587 +            break;
   1.588 +        case faload:
   1.589 +            state.pop(2);
   1.590 +            state.push(syms.floatType);
   1.591 +            break;
   1.592 +        case daload:
   1.593 +            state.pop(2);
   1.594 +            state.push(syms.doubleType);
   1.595 +            break;
   1.596 +        case istore_0:
   1.597 +        case istore_1:
   1.598 +        case istore_2:
   1.599 +        case istore_3:
   1.600 +        case fstore_0:
   1.601 +        case fstore_1:
   1.602 +        case fstore_2:
   1.603 +        case fstore_3:
   1.604 +        case astore_0:
   1.605 +        case astore_1:
   1.606 +        case astore_2:
   1.607 +        case astore_3:
   1.608 +        case pop:
   1.609 +        case lshr:
   1.610 +        case lshl:
   1.611 +        case lushr:
   1.612 +            state.pop(1);
   1.613 +            break;
   1.614 +        case areturn:
   1.615 +        case ireturn:
   1.616 +        case freturn:
   1.617 +            Assert.check(state.nlocks == 0);
   1.618 +            state.pop(1);
   1.619 +            markDead();
   1.620 +            break;
   1.621 +        case athrow:
   1.622 +            state.pop(1);
   1.623 +            markDead();
   1.624 +            break;
   1.625 +        case lstore_0:
   1.626 +        case lstore_1:
   1.627 +        case lstore_2:
   1.628 +        case lstore_3:
   1.629 +        case dstore_0:
   1.630 +        case dstore_1:
   1.631 +        case dstore_2:
   1.632 +        case dstore_3:
   1.633 +        case pop2:
   1.634 +            state.pop(2);
   1.635 +            break;
   1.636 +        case lreturn:
   1.637 +        case dreturn:
   1.638 +            Assert.check(state.nlocks == 0);
   1.639 +            state.pop(2);
   1.640 +            markDead();
   1.641 +            break;
   1.642 +        case dup:
   1.643 +            state.push(state.stack[state.stacksize-1]);
   1.644 +            break;
   1.645 +        case return_:
   1.646 +            Assert.check(state.nlocks == 0);
   1.647 +            markDead();
   1.648 +            break;
   1.649 +        case arraylength:
   1.650 +            state.pop(1);
   1.651 +            state.push(syms.intType);
   1.652 +            break;
   1.653 +        case isub:
   1.654 +        case iadd:
   1.655 +        case imul:
   1.656 +        case idiv:
   1.657 +        case imod:
   1.658 +        case ishl:
   1.659 +        case ishr:
   1.660 +        case iushr:
   1.661 +        case iand:
   1.662 +        case ior:
   1.663 +        case ixor:
   1.664 +            state.pop(1);
   1.665 +            // state.pop(1);
   1.666 +            // state.push(syms.intType);
   1.667 +            break;
   1.668 +        case aastore:
   1.669 +            state.pop(3);
   1.670 +            break;
   1.671 +        case land:
   1.672 +        case lor:
   1.673 +        case lxor:
   1.674 +        case lmod:
   1.675 +        case ldiv:
   1.676 +        case lmul:
   1.677 +        case lsub:
   1.678 +        case ladd:
   1.679 +            state.pop(2);
   1.680 +            break;
   1.681 +        case lcmp:
   1.682 +            state.pop(4);
   1.683 +            state.push(syms.intType);
   1.684 +            break;
   1.685 +        case l2i:
   1.686 +            state.pop(2);
   1.687 +            state.push(syms.intType);
   1.688 +            break;
   1.689 +        case i2l:
   1.690 +            state.pop(1);
   1.691 +            state.push(syms.longType);
   1.692 +            break;
   1.693 +        case i2f:
   1.694 +            state.pop(1);
   1.695 +            state.push(syms.floatType);
   1.696 +            break;
   1.697 +        case i2d:
   1.698 +            state.pop(1);
   1.699 +            state.push(syms.doubleType);
   1.700 +            break;
   1.701 +        case l2f:
   1.702 +            state.pop(2);
   1.703 +            state.push(syms.floatType);
   1.704 +            break;
   1.705 +        case l2d:
   1.706 +            state.pop(2);
   1.707 +            state.push(syms.doubleType);
   1.708 +            break;
   1.709 +        case f2i:
   1.710 +            state.pop(1);
   1.711 +            state.push(syms.intType);
   1.712 +            break;
   1.713 +        case f2l:
   1.714 +            state.pop(1);
   1.715 +            state.push(syms.longType);
   1.716 +            break;
   1.717 +        case f2d:
   1.718 +            state.pop(1);
   1.719 +            state.push(syms.doubleType);
   1.720 +            break;
   1.721 +        case d2i:
   1.722 +            state.pop(2);
   1.723 +            state.push(syms.intType);
   1.724 +            break;
   1.725 +        case d2l:
   1.726 +            state.pop(2);
   1.727 +            state.push(syms.longType);
   1.728 +            break;
   1.729 +        case d2f:
   1.730 +            state.pop(2);
   1.731 +            state.push(syms.floatType);
   1.732 +            break;
   1.733 +        case tableswitch:
   1.734 +        case lookupswitch:
   1.735 +            state.pop(1);
   1.736 +            // the caller is responsible for patching up the state
   1.737 +            break;
   1.738 +        case dup_x1: {
   1.739 +            Type val1 = state.pop1();
   1.740 +            Type val2 = state.pop1();
   1.741 +            state.push(val1);
   1.742 +            state.push(val2);
   1.743 +            state.push(val1);
   1.744 +            break;
   1.745 +        }
   1.746 +        case bastore:
   1.747 +            state.pop(3);
   1.748 +            break;
   1.749 +        case int2byte:
   1.750 +        case int2char:
   1.751 +        case int2short:
   1.752 +            break;
   1.753 +        case fmul:
   1.754 +        case fadd:
   1.755 +        case fsub:
   1.756 +        case fdiv:
   1.757 +        case fmod:
   1.758 +            state.pop(1);
   1.759 +            break;
   1.760 +        case castore:
   1.761 +        case iastore:
   1.762 +        case fastore:
   1.763 +        case sastore:
   1.764 +            state.pop(3);
   1.765 +            break;
   1.766 +        case lastore:
   1.767 +        case dastore:
   1.768 +            state.pop(4);
   1.769 +            break;
   1.770 +        case dup2:
   1.771 +            if (state.stack[state.stacksize-1] != null) {
   1.772 +                Type value1 = state.pop1();
   1.773 +                Type value2 = state.pop1();
   1.774 +                state.push(value2);
   1.775 +                state.push(value1);
   1.776 +                state.push(value2);
   1.777 +                state.push(value1);
   1.778 +            } else {
   1.779 +                Type value = state.pop2();
   1.780 +                state.push(value);
   1.781 +                state.push(value);
   1.782 +            }
   1.783 +            break;
   1.784 +        case dup2_x1:
   1.785 +            if (state.stack[state.stacksize-1] != null) {
   1.786 +                Type value1 = state.pop1();
   1.787 +                Type value2 = state.pop1();
   1.788 +                Type value3 = state.pop1();
   1.789 +                state.push(value2);
   1.790 +                state.push(value1);
   1.791 +                state.push(value3);
   1.792 +                state.push(value2);
   1.793 +                state.push(value1);
   1.794 +            } else {
   1.795 +                Type value1 = state.pop2();
   1.796 +                Type value2 = state.pop1();
   1.797 +                state.push(value1);
   1.798 +                state.push(value2);
   1.799 +                state.push(value1);
   1.800 +            }
   1.801 +            break;
   1.802 +        case dup2_x2:
   1.803 +            if (state.stack[state.stacksize-1] != null) {
   1.804 +                Type value1 = state.pop1();
   1.805 +                Type value2 = state.pop1();
   1.806 +                if (state.stack[state.stacksize-1] != null) {
   1.807 +                    // form 1
   1.808 +                    Type value3 = state.pop1();
   1.809 +                    Type value4 = state.pop1();
   1.810 +                    state.push(value2);
   1.811 +                    state.push(value1);
   1.812 +                    state.push(value4);
   1.813 +                    state.push(value3);
   1.814 +                    state.push(value2);
   1.815 +                    state.push(value1);
   1.816 +                } else {
   1.817 +                    // form 3
   1.818 +                    Type value3 = state.pop2();
   1.819 +                    state.push(value2);
   1.820 +                    state.push(value1);
   1.821 +                    state.push(value3);
   1.822 +                    state.push(value2);
   1.823 +                    state.push(value1);
   1.824 +                }
   1.825 +            } else {
   1.826 +                Type value1 = state.pop2();
   1.827 +                if (state.stack[state.stacksize-1] != null) {
   1.828 +                    // form 2
   1.829 +                    Type value2 = state.pop1();
   1.830 +                    Type value3 = state.pop1();
   1.831 +                    state.push(value1);
   1.832 +                    state.push(value3);
   1.833 +                    state.push(value2);
   1.834 +                    state.push(value1);
   1.835 +                } else {
   1.836 +                    // form 4
   1.837 +                    Type value2 = state.pop2();
   1.838 +                    state.push(value1);
   1.839 +                    state.push(value2);
   1.840 +                    state.push(value1);
   1.841 +                }
   1.842 +            }
   1.843 +            break;
   1.844 +        case dup_x2: {
   1.845 +            Type value1 = state.pop1();
   1.846 +            if (state.stack[state.stacksize-1] != null) {
   1.847 +                // form 1
   1.848 +                Type value2 = state.pop1();
   1.849 +                Type value3 = state.pop1();
   1.850 +                state.push(value1);
   1.851 +                state.push(value3);
   1.852 +                state.push(value2);
   1.853 +                state.push(value1);
   1.854 +            } else {
   1.855 +                // form 2
   1.856 +                Type value2 = state.pop2();
   1.857 +                state.push(value1);
   1.858 +                state.push(value2);
   1.859 +                state.push(value1);
   1.860 +            }
   1.861 +        }
   1.862 +            break;
   1.863 +        case fcmpl:
   1.864 +        case fcmpg:
   1.865 +            state.pop(2);
   1.866 +            state.push(syms.intType);
   1.867 +            break;
   1.868 +        case dcmpl:
   1.869 +        case dcmpg:
   1.870 +            state.pop(4);
   1.871 +            state.push(syms.intType);
   1.872 +            break;
   1.873 +        case swap: {
   1.874 +            Type value1 = state.pop1();
   1.875 +            Type value2 = state.pop1();
   1.876 +            state.push(value1);
   1.877 +            state.push(value2);
   1.878 +            break;
   1.879 +        }
   1.880 +        case dadd:
   1.881 +        case dsub:
   1.882 +        case dmul:
   1.883 +        case ddiv:
   1.884 +        case dmod:
   1.885 +            state.pop(2);
   1.886 +            break;
   1.887 +        case ret:
   1.888 +            markDead();
   1.889 +            break;
   1.890 +        case wide:
   1.891 +            // must be handled by the caller.
   1.892 +            return;
   1.893 +        case monitorenter:
   1.894 +        case monitorexit:
   1.895 +            state.pop(1);
   1.896 +            break;
   1.897 +
   1.898 +        default:
   1.899 +            throw new AssertionError(mnem(op));
   1.900 +        }
   1.901 +        postop();
   1.902 +    }
   1.903 +
   1.904 +    /** Emit an opcode with a one-byte operand field.
   1.905 +     */
   1.906 +    public void emitop1(int op, int od) {
   1.907 +        emitop(op);
   1.908 +        if (!alive) return;
   1.909 +        emit1(od);
   1.910 +        switch (op) {
   1.911 +        case bipush:
   1.912 +            state.push(syms.intType);
   1.913 +            break;
   1.914 +        case ldc1:
   1.915 +            state.push(typeForPool(pool.pool[od]));
   1.916 +            break;
   1.917 +        default:
   1.918 +            throw new AssertionError(mnem(op));
   1.919 +        }
   1.920 +        postop();
   1.921 +    }
   1.922 +
   1.923 +    /** The type of a constant pool entry. */
   1.924 +    private Type typeForPool(Object o) {
   1.925 +        if (o instanceof Integer) return syms.intType;
   1.926 +        if (o instanceof Float) return syms.floatType;
   1.927 +        if (o instanceof String) return syms.stringType;
   1.928 +        if (o instanceof Long) return syms.longType;
   1.929 +        if (o instanceof Double) return syms.doubleType;
   1.930 +        if (o instanceof ClassSymbol) return syms.classType;
   1.931 +        if (o instanceof Pool.MethodHandle) return syms.methodHandleType;
   1.932 +        if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type);
   1.933 +        if (o instanceof Type) {
   1.934 +            Type ty = ((Type)o).unannotatedType();
   1.935 +
   1.936 +            if (ty instanceof Type.ArrayType) return syms.classType;
   1.937 +            if (ty instanceof Type.MethodType) return syms.methodTypeType;
   1.938 +        }
   1.939 +        throw new AssertionError("Invalid type of constant pool entry: " + o.getClass());
   1.940 +    }
   1.941 +
   1.942 +    /** Emit an opcode with a one-byte operand field;
   1.943 +     *  widen if field does not fit in a byte.
   1.944 +     */
   1.945 +    public void emitop1w(int op, int od) {
   1.946 +        if (od > 0xFF) {
   1.947 +            emitop(wide);
   1.948 +            emitop(op);
   1.949 +            emit2(od);
   1.950 +        } else {
   1.951 +            emitop(op);
   1.952 +            emit1(od);
   1.953 +        }
   1.954 +        if (!alive) return;
   1.955 +        switch (op) {
   1.956 +        case iload:
   1.957 +            state.push(syms.intType);
   1.958 +            break;
   1.959 +        case lload:
   1.960 +            state.push(syms.longType);
   1.961 +            break;
   1.962 +        case fload:
   1.963 +            state.push(syms.floatType);
   1.964 +            break;
   1.965 +        case dload:
   1.966 +            state.push(syms.doubleType);
   1.967 +            break;
   1.968 +        case aload:
   1.969 +            state.push(lvar[od].sym.type);
   1.970 +            break;
   1.971 +        case lstore:
   1.972 +        case dstore:
   1.973 +            state.pop(2);
   1.974 +            break;
   1.975 +        case istore:
   1.976 +        case fstore:
   1.977 +        case astore:
   1.978 +            state.pop(1);
   1.979 +            break;
   1.980 +        case ret:
   1.981 +            markDead();
   1.982 +            break;
   1.983 +        default:
   1.984 +            throw new AssertionError(mnem(op));
   1.985 +        }
   1.986 +        postop();
   1.987 +    }
   1.988 +
   1.989 +    /** Emit an opcode with two one-byte operand fields;
   1.990 +     *  widen if either field does not fit in a byte.
   1.991 +     */
   1.992 +    public void emitop1w(int op, int od1, int od2) {
   1.993 +        if (od1 > 0xFF || od2 < -128 || od2 > 127) {
   1.994 +            emitop(wide);
   1.995 +            emitop(op);
   1.996 +            emit2(od1);
   1.997 +            emit2(od2);
   1.998 +        } else {
   1.999 +            emitop(op);
  1.1000 +            emit1(od1);
  1.1001 +            emit1(od2);
  1.1002 +        }
  1.1003 +        if (!alive) return;
  1.1004 +        switch (op) {
  1.1005 +        case iinc:
  1.1006 +            break;
  1.1007 +        default:
  1.1008 +            throw new AssertionError(mnem(op));
  1.1009 +        }
  1.1010 +    }
  1.1011 +
  1.1012 +    /** Emit an opcode with a two-byte operand field.
  1.1013 +     */
  1.1014 +    public void emitop2(int op, int od) {
  1.1015 +        emitop(op);
  1.1016 +        if (!alive) return;
  1.1017 +        emit2(od);
  1.1018 +        switch (op) {
  1.1019 +        case getstatic:
  1.1020 +            state.push(((Symbol)(pool.pool[od])).erasure(types));
  1.1021 +            break;
  1.1022 +        case putstatic:
  1.1023 +            state.pop(((Symbol)(pool.pool[od])).erasure(types));
  1.1024 +            break;
  1.1025 +        case new_:
  1.1026 +            Symbol sym;
  1.1027 +            if (pool.pool[od] instanceof UniqueType) {
  1.1028 +                // Required by change in Gen.makeRef to allow
  1.1029 +                // annotated types.
  1.1030 +                // TODO: is this needed anywhere else?
  1.1031 +                sym = ((UniqueType)(pool.pool[od])).type.tsym;
  1.1032 +            } else {
  1.1033 +                sym = (Symbol)(pool.pool[od]);
  1.1034 +            }
  1.1035 +            state.push(uninitializedObject(sym.erasure(types), cp-3));
  1.1036 +            break;
  1.1037 +        case sipush:
  1.1038 +            state.push(syms.intType);
  1.1039 +            break;
  1.1040 +        case if_acmp_null:
  1.1041 +        case if_acmp_nonnull:
  1.1042 +        case ifeq:
  1.1043 +        case ifne:
  1.1044 +        case iflt:
  1.1045 +        case ifge:
  1.1046 +        case ifgt:
  1.1047 +        case ifle:
  1.1048 +            state.pop(1);
  1.1049 +            break;
  1.1050 +        case if_icmpeq:
  1.1051 +        case if_icmpne:
  1.1052 +        case if_icmplt:
  1.1053 +        case if_icmpge:
  1.1054 +        case if_icmpgt:
  1.1055 +        case if_icmple:
  1.1056 +        case if_acmpeq:
  1.1057 +        case if_acmpne:
  1.1058 +            state.pop(2);
  1.1059 +            break;
  1.1060 +        case goto_:
  1.1061 +            markDead();
  1.1062 +            break;
  1.1063 +        case putfield:
  1.1064 +            state.pop(((Symbol)(pool.pool[od])).erasure(types));
  1.1065 +            state.pop(1); // object ref
  1.1066 +            break;
  1.1067 +        case getfield:
  1.1068 +            state.pop(1); // object ref
  1.1069 +            state.push(((Symbol)(pool.pool[od])).erasure(types));
  1.1070 +            break;
  1.1071 +        case checkcast: {
  1.1072 +            state.pop(1); // object ref
  1.1073 +            Object o = pool.pool[od];
  1.1074 +            Type t = (o instanceof Symbol)
  1.1075 +                ? ((Symbol)o).erasure(types)
  1.1076 +                : types.erasure((((UniqueType)o).type));
  1.1077 +            state.push(t);
  1.1078 +            break; }
  1.1079 +        case ldc2w:
  1.1080 +            state.push(typeForPool(pool.pool[od]));
  1.1081 +            break;
  1.1082 +        case instanceof_:
  1.1083 +            state.pop(1);
  1.1084 +            state.push(syms.intType);
  1.1085 +            break;
  1.1086 +        case ldc2:
  1.1087 +            state.push(typeForPool(pool.pool[od]));
  1.1088 +            break;
  1.1089 +        case jsr:
  1.1090 +            break;
  1.1091 +        default:
  1.1092 +            throw new AssertionError(mnem(op));
  1.1093 +        }
  1.1094 +        // postop();
  1.1095 +    }
  1.1096 +
  1.1097 +    /** Emit an opcode with a four-byte operand field.
  1.1098 +     */
  1.1099 +    public void emitop4(int op, int od) {
  1.1100 +        emitop(op);
  1.1101 +        if (!alive) return;
  1.1102 +        emit4(od);
  1.1103 +        switch (op) {
  1.1104 +        case goto_w:
  1.1105 +            markDead();
  1.1106 +            break;
  1.1107 +        case jsr_w:
  1.1108 +            break;
  1.1109 +        default:
  1.1110 +            throw new AssertionError(mnem(op));
  1.1111 +        }
  1.1112 +        // postop();
  1.1113 +    }
  1.1114 +
  1.1115 +    /** Align code pointer to next `incr' boundary.
  1.1116 +     */
  1.1117 +    public void align(int incr) {
  1.1118 +        if (alive)
  1.1119 +            while (cp % incr != 0) emitop0(nop);
  1.1120 +    }
  1.1121 +
  1.1122 +    /** Place a byte into code at address pc.
  1.1123 +     *  Pre: {@literal pc + 1 <= cp }.
  1.1124 +     */
  1.1125 +    private void put1(int pc, int op) {
  1.1126 +        code[pc] = (byte)op;
  1.1127 +    }
  1.1128 +
  1.1129 +    /** Place two bytes into code at address pc.
  1.1130 +     *  Pre: {@literal pc + 2 <= cp }.
  1.1131 +     */
  1.1132 +    private void put2(int pc, int od) {
  1.1133 +        // pre: pc + 2 <= cp
  1.1134 +        put1(pc, od >> 8);
  1.1135 +        put1(pc+1, od);
  1.1136 +    }
  1.1137 +
  1.1138 +    /** Place four  bytes into code at address pc.
  1.1139 +     *  Pre: {@literal pc + 4 <= cp }.
  1.1140 +     */
  1.1141 +    public void put4(int pc, int od) {
  1.1142 +        // pre: pc + 4 <= cp
  1.1143 +        put1(pc  , od >> 24);
  1.1144 +        put1(pc+1, od >> 16);
  1.1145 +        put1(pc+2, od >> 8);
  1.1146 +        put1(pc+3, od);
  1.1147 +    }
  1.1148 +
  1.1149 +    /** Return code byte at position pc as an unsigned int.
  1.1150 +     */
  1.1151 +    private int get1(int pc) {
  1.1152 +        return code[pc] & 0xFF;
  1.1153 +    }
  1.1154 +
  1.1155 +    /** Return two code bytes at position pc as an unsigned int.
  1.1156 +     */
  1.1157 +    private int get2(int pc) {
  1.1158 +        return (get1(pc) << 8) | get1(pc+1);
  1.1159 +    }
  1.1160 +
  1.1161 +    /** Return four code bytes at position pc as an int.
  1.1162 +     */
  1.1163 +    public int get4(int pc) {
  1.1164 +        // pre: pc + 4 <= cp
  1.1165 +        return
  1.1166 +            (get1(pc) << 24) |
  1.1167 +            (get1(pc+1) << 16) |
  1.1168 +            (get1(pc+2) << 8) |
  1.1169 +            (get1(pc+3));
  1.1170 +    }
  1.1171 +
  1.1172 +    /** Is code generation currently enabled?
  1.1173 +     */
  1.1174 +    public boolean isAlive() {
  1.1175 +        return alive || pendingJumps != null;
  1.1176 +    }
  1.1177 +
  1.1178 +    /** Switch code generation on/off.
  1.1179 +     */
  1.1180 +    public void markDead() {
  1.1181 +        alive = false;
  1.1182 +    }
  1.1183 +
  1.1184 +    /** Declare an entry point; return current code pointer
  1.1185 +     */
  1.1186 +    public int entryPoint() {
  1.1187 +        int pc = curCP();
  1.1188 +        alive = true;
  1.1189 +        pendingStackMap = needStackMap;
  1.1190 +        return pc;
  1.1191 +    }
  1.1192 +
  1.1193 +    /** Declare an entry point with initial state;
  1.1194 +     *  return current code pointer
  1.1195 +     */
  1.1196 +    public int entryPoint(State state) {
  1.1197 +        int pc = curCP();
  1.1198 +        alive = true;
  1.1199 +        this.state = state.dup();
  1.1200 +        Assert.check(state.stacksize <= max_stack);
  1.1201 +        if (debugCode) System.err.println("entry point " + state);
  1.1202 +        pendingStackMap = needStackMap;
  1.1203 +        return pc;
  1.1204 +    }
  1.1205 +
  1.1206 +    /** Declare an entry point with initial state plus a pushed value;
  1.1207 +     *  return current code pointer
  1.1208 +     */
  1.1209 +    public int entryPoint(State state, Type pushed) {
  1.1210 +        int pc = curCP();
  1.1211 +        alive = true;
  1.1212 +        this.state = state.dup();
  1.1213 +        Assert.check(state.stacksize <= max_stack);
  1.1214 +        this.state.push(pushed);
  1.1215 +        if (debugCode) System.err.println("entry point " + state);
  1.1216 +        pendingStackMap = needStackMap;
  1.1217 +        return pc;
  1.1218 +    }
  1.1219 +
  1.1220 +
  1.1221 +/**************************************************************************
  1.1222 + * Stack map generation
  1.1223 + *************************************************************************/
  1.1224 +
  1.1225 +    /** An entry in the stack map. */
  1.1226 +    static class StackMapFrame {
  1.1227 +        int pc;
  1.1228 +        Type[] locals;
  1.1229 +        Type[] stack;
  1.1230 +    }
  1.1231 +
  1.1232 +    /** A buffer of cldc stack map entries. */
  1.1233 +    StackMapFrame[] stackMapBuffer = null;
  1.1234 +
  1.1235 +    /** A buffer of compressed StackMapTable entries. */
  1.1236 +    StackMapTableFrame[] stackMapTableBuffer = null;
  1.1237 +    int stackMapBufferSize = 0;
  1.1238 +
  1.1239 +    /** The last PC at which we generated a stack map. */
  1.1240 +    int lastStackMapPC = -1;
  1.1241 +
  1.1242 +    /** The last stack map frame in StackMapTable. */
  1.1243 +    StackMapFrame lastFrame = null;
  1.1244 +
  1.1245 +    /** The stack map frame before the last one. */
  1.1246 +    StackMapFrame frameBeforeLast = null;
  1.1247 +
  1.1248 +    /** Emit a stack map entry.  */
  1.1249 +    public void emitStackMap() {
  1.1250 +        int pc = curCP();
  1.1251 +        if (!needStackMap) return;
  1.1252 +
  1.1253 +
  1.1254 +
  1.1255 +        switch (stackMap) {
  1.1256 +            case CLDC:
  1.1257 +                emitCLDCStackMap(pc, getLocalsSize());
  1.1258 +                break;
  1.1259 +            case JSR202:
  1.1260 +                emitStackMapFrame(pc, getLocalsSize());
  1.1261 +                break;
  1.1262 +            default:
  1.1263 +                throw new AssertionError("Should have chosen a stackmap format");
  1.1264 +        }
  1.1265 +        // DEBUG code follows
  1.1266 +        if (debugCode) state.dump(pc);
  1.1267 +    }
  1.1268 +
  1.1269 +    private int getLocalsSize() {
  1.1270 +        int nextLocal = 0;
  1.1271 +        for (int i=max_locals-1; i>=0; i--) {
  1.1272 +            if (state.defined.isMember(i) && lvar[i] != null) {
  1.1273 +                nextLocal = i + width(lvar[i].sym.erasure(types));
  1.1274 +                break;
  1.1275 +            }
  1.1276 +        }
  1.1277 +        return nextLocal;
  1.1278 +    }
  1.1279 +
  1.1280 +    /** Emit a CLDC stack map frame. */
  1.1281 +    void emitCLDCStackMap(int pc, int localsSize) {
  1.1282 +        if (lastStackMapPC == pc) {
  1.1283 +            // drop existing stackmap at this offset
  1.1284 +            stackMapBuffer[--stackMapBufferSize] = null;
  1.1285 +        }
  1.1286 +        lastStackMapPC = pc;
  1.1287 +
  1.1288 +        if (stackMapBuffer == null) {
  1.1289 +            stackMapBuffer = new StackMapFrame[20];
  1.1290 +        } else {
  1.1291 +            stackMapBuffer = ArrayUtils.ensureCapacity(stackMapBuffer, stackMapBufferSize);
  1.1292 +        }
  1.1293 +        StackMapFrame frame =
  1.1294 +            stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
  1.1295 +        frame.pc = pc;
  1.1296 +
  1.1297 +        frame.locals = new Type[localsSize];
  1.1298 +        for (int i=0; i<localsSize; i++) {
  1.1299 +            if (state.defined.isMember(i) && lvar[i] != null) {
  1.1300 +                Type vtype = lvar[i].sym.type;
  1.1301 +                if (!(vtype instanceof UninitializedType))
  1.1302 +                    vtype = types.erasure(vtype);
  1.1303 +                frame.locals[i] = vtype;
  1.1304 +            }
  1.1305 +        }
  1.1306 +        frame.stack = new Type[state.stacksize];
  1.1307 +        for (int i=0; i<state.stacksize; i++)
  1.1308 +            frame.stack[i] = state.stack[i];
  1.1309 +    }
  1.1310 +
  1.1311 +    void emitStackMapFrame(int pc, int localsSize) {
  1.1312 +        if (lastFrame == null) {
  1.1313 +            // first frame
  1.1314 +            lastFrame = getInitialFrame();
  1.1315 +        } else if (lastFrame.pc == pc) {
  1.1316 +            // drop existing stackmap at this offset
  1.1317 +            stackMapTableBuffer[--stackMapBufferSize] = null;
  1.1318 +            lastFrame = frameBeforeLast;
  1.1319 +            frameBeforeLast = null;
  1.1320 +        }
  1.1321 +
  1.1322 +        StackMapFrame frame = new StackMapFrame();
  1.1323 +        frame.pc = pc;
  1.1324 +
  1.1325 +        int localCount = 0;
  1.1326 +        Type[] locals = new Type[localsSize];
  1.1327 +        for (int i=0; i<localsSize; i++, localCount++) {
  1.1328 +            if (state.defined.isMember(i) && lvar[i] != null) {
  1.1329 +                Type vtype = lvar[i].sym.type;
  1.1330 +                if (!(vtype instanceof UninitializedType))
  1.1331 +                    vtype = types.erasure(vtype);
  1.1332 +                locals[i] = vtype;
  1.1333 +                if (width(vtype) > 1) i++;
  1.1334 +            }
  1.1335 +        }
  1.1336 +        frame.locals = new Type[localCount];
  1.1337 +        for (int i=0, j=0; i<localsSize; i++, j++) {
  1.1338 +            Assert.check(j < localCount);
  1.1339 +            frame.locals[j] = locals[i];
  1.1340 +            if (width(locals[i]) > 1) i++;
  1.1341 +        }
  1.1342 +
  1.1343 +        int stackCount = 0;
  1.1344 +        for (int i=0; i<state.stacksize; i++) {
  1.1345 +            if (state.stack[i] != null) {
  1.1346 +                stackCount++;
  1.1347 +            }
  1.1348 +        }
  1.1349 +        frame.stack = new Type[stackCount];
  1.1350 +        stackCount = 0;
  1.1351 +        for (int i=0; i<state.stacksize; i++) {
  1.1352 +            if (state.stack[i] != null) {
  1.1353 +                frame.stack[stackCount++] = types.erasure(state.stack[i]);
  1.1354 +            }
  1.1355 +        }
  1.1356 +
  1.1357 +        if (stackMapTableBuffer == null) {
  1.1358 +            stackMapTableBuffer = new StackMapTableFrame[20];
  1.1359 +        } else {
  1.1360 +            stackMapTableBuffer = ArrayUtils.ensureCapacity(
  1.1361 +                                    stackMapTableBuffer,
  1.1362 +                                    stackMapBufferSize);
  1.1363 +        }
  1.1364 +        stackMapTableBuffer[stackMapBufferSize++] =
  1.1365 +                StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
  1.1366 +
  1.1367 +        frameBeforeLast = lastFrame;
  1.1368 +        lastFrame = frame;
  1.1369 +    }
  1.1370 +
  1.1371 +    StackMapFrame getInitialFrame() {
  1.1372 +        StackMapFrame frame = new StackMapFrame();
  1.1373 +        List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
  1.1374 +        int len = arg_types.length();
  1.1375 +        int count = 0;
  1.1376 +        if (!meth.isStatic()) {
  1.1377 +            Type thisType = meth.owner.type;
  1.1378 +            frame.locals = new Type[len+1];
  1.1379 +            if (meth.isConstructor() && thisType != syms.objectType) {
  1.1380 +                frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
  1.1381 +            } else {
  1.1382 +                frame.locals[count++] = types.erasure(thisType);
  1.1383 +            }
  1.1384 +        } else {
  1.1385 +            frame.locals = new Type[len];
  1.1386 +        }
  1.1387 +        for (Type arg_type : arg_types) {
  1.1388 +            frame.locals[count++] = types.erasure(arg_type);
  1.1389 +        }
  1.1390 +        frame.pc = -1;
  1.1391 +        frame.stack = null;
  1.1392 +        return frame;
  1.1393 +    }
  1.1394 +
  1.1395 +
  1.1396 +/**************************************************************************
  1.1397 + * Operations having to do with jumps
  1.1398 + *************************************************************************/
  1.1399 +
  1.1400 +    /** A chain represents a list of unresolved jumps. Jump locations
  1.1401 +     *  are sorted in decreasing order.
  1.1402 +     */
  1.1403 +    public static class Chain {
  1.1404 +
  1.1405 +        /** The position of the jump instruction.
  1.1406 +         */
  1.1407 +        public final int pc;
  1.1408 +
  1.1409 +        /** The machine state after the jump instruction.
  1.1410 +         *  Invariant: all elements of a chain list have the same stacksize
  1.1411 +         *  and compatible stack and register contents.
  1.1412 +         */
  1.1413 +        Code.State state;
  1.1414 +
  1.1415 +        /** The next jump in the list.
  1.1416 +         */
  1.1417 +        public final Chain next;
  1.1418 +
  1.1419 +        /** Construct a chain from its jump position, stacksize, previous
  1.1420 +         *  chain, and machine state.
  1.1421 +         */
  1.1422 +        public Chain(int pc, Chain next, Code.State state) {
  1.1423 +            this.pc = pc;
  1.1424 +            this.next = next;
  1.1425 +            this.state = state;
  1.1426 +        }
  1.1427 +    }
  1.1428 +
  1.1429 +    /** Negate a branch opcode.
  1.1430 +     */
  1.1431 +    public static int negate(int opcode) {
  1.1432 +        if (opcode == if_acmp_null) return if_acmp_nonnull;
  1.1433 +        else if (opcode == if_acmp_nonnull) return if_acmp_null;
  1.1434 +        else return ((opcode + 1) ^ 1) - 1;
  1.1435 +    }
  1.1436 +
  1.1437 +    /** Emit a jump instruction.
  1.1438 +     *  Return code pointer of instruction to be patched.
  1.1439 +     */
  1.1440 +    public int emitJump(int opcode) {
  1.1441 +        if (fatcode) {
  1.1442 +            if (opcode == goto_ || opcode == jsr) {
  1.1443 +                emitop4(opcode + goto_w - goto_, 0);
  1.1444 +            } else {
  1.1445 +                emitop2(negate(opcode), 8);
  1.1446 +                emitop4(goto_w, 0);
  1.1447 +                alive = true;
  1.1448 +                pendingStackMap = needStackMap;
  1.1449 +            }
  1.1450 +            return cp - 5;
  1.1451 +        } else {
  1.1452 +            emitop2(opcode, 0);
  1.1453 +            return cp - 3;
  1.1454 +        }
  1.1455 +    }
  1.1456 +
  1.1457 +    /** Emit a branch with given opcode; return its chain.
  1.1458 +     *  branch differs from jump in that jsr is treated as no-op.
  1.1459 +     */
  1.1460 +    public Chain branch(int opcode) {
  1.1461 +        Chain result = null;
  1.1462 +        if (opcode == goto_) {
  1.1463 +            result = pendingJumps;
  1.1464 +            pendingJumps = null;
  1.1465 +        }
  1.1466 +        if (opcode != dontgoto && isAlive()) {
  1.1467 +            result = new Chain(emitJump(opcode),
  1.1468 +                               result,
  1.1469 +                               state.dup());
  1.1470 +            fixedPc = fatcode;
  1.1471 +            if (opcode == goto_) alive = false;
  1.1472 +        }
  1.1473 +        return result;
  1.1474 +    }
  1.1475 +
  1.1476 +    /** Resolve chain to point to given target.
  1.1477 +     */
  1.1478 +    public void resolve(Chain chain, int target) {
  1.1479 +        boolean changed = false;
  1.1480 +        State newState = state;
  1.1481 +        for (; chain != null; chain = chain.next) {
  1.1482 +            Assert.check(state != chain.state
  1.1483 +                    && (target > chain.pc || state.stacksize == 0));
  1.1484 +            if (target >= cp) {
  1.1485 +                target = cp;
  1.1486 +            } else if (get1(target) == goto_) {
  1.1487 +                if (fatcode) target = target + get4(target + 1);
  1.1488 +                else target = target + get2(target + 1);
  1.1489 +            }
  1.1490 +            if (get1(chain.pc) == goto_ &&
  1.1491 +                chain.pc + 3 == target && target == cp && !fixedPc) {
  1.1492 +                // If goto the next instruction, the jump is not needed:
  1.1493 +                // compact the code.
  1.1494 +                if (varDebugInfo) {
  1.1495 +                    adjustAliveRanges(cp, -3);
  1.1496 +                }
  1.1497 +                cp = cp - 3;
  1.1498 +                target = target - 3;
  1.1499 +                if (chain.next == null) {
  1.1500 +                    // This is the only jump to the target. Exit the loop
  1.1501 +                    // without setting new state. The code is reachable
  1.1502 +                    // from the instruction before goto_.
  1.1503 +                    alive = true;
  1.1504 +                    break;
  1.1505 +                }
  1.1506 +            } else {
  1.1507 +                if (fatcode)
  1.1508 +                    put4(chain.pc + 1, target - chain.pc);
  1.1509 +                else if (target - chain.pc < Short.MIN_VALUE ||
  1.1510 +                         target - chain.pc > Short.MAX_VALUE)
  1.1511 +                    fatcode = true;
  1.1512 +                else
  1.1513 +                    put2(chain.pc + 1, target - chain.pc);
  1.1514 +                Assert.check(!alive ||
  1.1515 +                    chain.state.stacksize == newState.stacksize &&
  1.1516 +                    chain.state.nlocks == newState.nlocks);
  1.1517 +            }
  1.1518 +            fixedPc = true;
  1.1519 +            if (cp == target) {
  1.1520 +                changed = true;
  1.1521 +                if (debugCode)
  1.1522 +                    System.err.println("resolving chain state=" + chain.state);
  1.1523 +                if (alive) {
  1.1524 +                    newState = chain.state.join(newState);
  1.1525 +                } else {
  1.1526 +                    newState = chain.state;
  1.1527 +                    alive = true;
  1.1528 +                }
  1.1529 +            }
  1.1530 +        }
  1.1531 +        Assert.check(!changed || state != newState);
  1.1532 +        if (state != newState) {
  1.1533 +            setDefined(newState.defined);
  1.1534 +            state = newState;
  1.1535 +            pendingStackMap = needStackMap;
  1.1536 +        }
  1.1537 +    }
  1.1538 +
  1.1539 +    /** Resolve chain to point to current code pointer.
  1.1540 +     */
  1.1541 +    public void resolve(Chain chain) {
  1.1542 +        Assert.check(
  1.1543 +            !alive ||
  1.1544 +            chain==null ||
  1.1545 +            state.stacksize == chain.state.stacksize &&
  1.1546 +            state.nlocks == chain.state.nlocks);
  1.1547 +        pendingJumps = mergeChains(chain, pendingJumps);
  1.1548 +    }
  1.1549 +
  1.1550 +    /** Resolve any pending jumps.
  1.1551 +     */
  1.1552 +    public void resolvePending() {
  1.1553 +        Chain x = pendingJumps;
  1.1554 +        pendingJumps = null;
  1.1555 +        resolve(x, cp);
  1.1556 +    }
  1.1557 +
  1.1558 +    /** Merge the jumps in of two chains into one.
  1.1559 +     */
  1.1560 +    public static Chain mergeChains(Chain chain1, Chain chain2) {
  1.1561 +        // recursive merge sort
  1.1562 +        if (chain2 == null) return chain1;
  1.1563 +        if (chain1 == null) return chain2;
  1.1564 +        Assert.check(
  1.1565 +            chain1.state.stacksize == chain2.state.stacksize &&
  1.1566 +            chain1.state.nlocks == chain2.state.nlocks);
  1.1567 +        if (chain1.pc < chain2.pc)
  1.1568 +            return new Chain(
  1.1569 +                chain2.pc,
  1.1570 +                mergeChains(chain1, chain2.next),
  1.1571 +                chain2.state);
  1.1572 +        return new Chain(
  1.1573 +                chain1.pc,
  1.1574 +                mergeChains(chain1.next, chain2),
  1.1575 +                chain1.state);
  1.1576 +    }
  1.1577 +
  1.1578 +
  1.1579 +/* **************************************************************************
  1.1580 + * Catch clauses
  1.1581 + ****************************************************************************/
  1.1582 +
  1.1583 +    /** Add a catch clause to code.
  1.1584 +     */
  1.1585 +    public void addCatch(
  1.1586 +        char startPc, char endPc, char handlerPc, char catchType) {
  1.1587 +            catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
  1.1588 +        }
  1.1589 +
  1.1590 +
  1.1591 +    public void compressCatchTable() {
  1.1592 +        ListBuffer<char[]> compressedCatchInfo = new ListBuffer<>();
  1.1593 +        List<Integer> handlerPcs = List.nil();
  1.1594 +        for (char[] catchEntry : catchInfo) {
  1.1595 +            handlerPcs = handlerPcs.prepend((int)catchEntry[2]);
  1.1596 +        }
  1.1597 +        for (char[] catchEntry : catchInfo) {
  1.1598 +            int startpc = catchEntry[0];
  1.1599 +            int endpc = catchEntry[1];
  1.1600 +            if (startpc == endpc ||
  1.1601 +                    (startpc == (endpc - 1) &&
  1.1602 +                    handlerPcs.contains(startpc))) {
  1.1603 +                continue;
  1.1604 +            } else {
  1.1605 +                compressedCatchInfo.append(catchEntry);
  1.1606 +            }
  1.1607 +        }
  1.1608 +        catchInfo = compressedCatchInfo;
  1.1609 +    }
  1.1610 +
  1.1611 +
  1.1612 +/* **************************************************************************
  1.1613 + * Line numbers
  1.1614 + ****************************************************************************/
  1.1615 +
  1.1616 +    /** Add a line number entry.
  1.1617 +     */
  1.1618 +    public void addLineNumber(char startPc, char lineNumber) {
  1.1619 +        if (lineDebugInfo) {
  1.1620 +            if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
  1.1621 +                lineInfo = lineInfo.tail;
  1.1622 +            if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
  1.1623 +                lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
  1.1624 +        }
  1.1625 +    }
  1.1626 +
  1.1627 +    /** Mark beginning of statement.
  1.1628 +     */
  1.1629 +    public void statBegin(int pos) {
  1.1630 +        if (pos != Position.NOPOS) {
  1.1631 +            pendingStatPos = pos;
  1.1632 +        }
  1.1633 +    }
  1.1634 +
  1.1635 +    /** Force stat begin eagerly
  1.1636 +     */
  1.1637 +    public void markStatBegin() {
  1.1638 +        if (alive && lineDebugInfo) {
  1.1639 +            int line = lineMap.getLineNumber(pendingStatPos);
  1.1640 +            char cp1 = (char)cp;
  1.1641 +            char line1 = (char)line;
  1.1642 +            if (cp1 == cp && line1 == line)
  1.1643 +                addLineNumber(cp1, line1);
  1.1644 +        }
  1.1645 +        pendingStatPos = Position.NOPOS;
  1.1646 +    }
  1.1647 +
  1.1648 +
  1.1649 +/* **************************************************************************
  1.1650 + * Simulated VM machine state
  1.1651 + ****************************************************************************/
  1.1652 +
  1.1653 +    class State implements Cloneable {
  1.1654 +        /** The set of registers containing values. */
  1.1655 +        Bits defined;
  1.1656 +
  1.1657 +        /** The (types of the) contents of the machine stack. */
  1.1658 +        Type[] stack;
  1.1659 +
  1.1660 +        /** The first stack position currently unused. */
  1.1661 +        int stacksize;
  1.1662 +
  1.1663 +        /** The numbers of registers containing locked monitors. */
  1.1664 +        int[] locks;
  1.1665 +        int nlocks;
  1.1666 +
  1.1667 +        State() {
  1.1668 +            defined = new Bits();
  1.1669 +            stack = new Type[16];
  1.1670 +        }
  1.1671 +
  1.1672 +        State dup() {
  1.1673 +            try {
  1.1674 +                State state = (State)super.clone();
  1.1675 +                state.defined = new Bits(defined);
  1.1676 +                state.stack = stack.clone();
  1.1677 +                if (locks != null) state.locks = locks.clone();
  1.1678 +                if (debugCode) {
  1.1679 +                    System.err.println("duping state " + this);
  1.1680 +                    dump();
  1.1681 +                }
  1.1682 +                return state;
  1.1683 +            } catch (CloneNotSupportedException ex) {
  1.1684 +                throw new AssertionError(ex);
  1.1685 +            }
  1.1686 +        }
  1.1687 +
  1.1688 +        void lock(int register) {
  1.1689 +            if (locks == null) {
  1.1690 +                locks = new int[20];
  1.1691 +            } else {
  1.1692 +                locks = ArrayUtils.ensureCapacity(locks, nlocks);
  1.1693 +            }
  1.1694 +            locks[nlocks] = register;
  1.1695 +            nlocks++;
  1.1696 +        }
  1.1697 +
  1.1698 +        void unlock(int register) {
  1.1699 +            nlocks--;
  1.1700 +            Assert.check(locks[nlocks] == register);
  1.1701 +            locks[nlocks] = -1;
  1.1702 +        }
  1.1703 +
  1.1704 +        void push(Type t) {
  1.1705 +            if (debugCode) System.err.println("   pushing " + t);
  1.1706 +            switch (t.getTag()) {
  1.1707 +            case VOID:
  1.1708 +                return;
  1.1709 +            case BYTE:
  1.1710 +            case CHAR:
  1.1711 +            case SHORT:
  1.1712 +            case BOOLEAN:
  1.1713 +                t = syms.intType;
  1.1714 +                break;
  1.1715 +            default:
  1.1716 +                break;
  1.1717 +            }
  1.1718 +            stack = ArrayUtils.ensureCapacity(stack, stacksize+2);
  1.1719 +            stack[stacksize++] = t;
  1.1720 +            switch (width(t)) {
  1.1721 +            case 1:
  1.1722 +                break;
  1.1723 +            case 2:
  1.1724 +                stack[stacksize++] = null;
  1.1725 +                break;
  1.1726 +            default:
  1.1727 +                throw new AssertionError(t);
  1.1728 +            }
  1.1729 +            if (stacksize > max_stack)
  1.1730 +                max_stack = stacksize;
  1.1731 +        }
  1.1732 +
  1.1733 +        Type pop1() {
  1.1734 +            if (debugCode) System.err.println("   popping " + 1);
  1.1735 +            stacksize--;
  1.1736 +            Type result = stack[stacksize];
  1.1737 +            stack[stacksize] = null;
  1.1738 +            Assert.check(result != null && width(result) == 1);
  1.1739 +            return result;
  1.1740 +        }
  1.1741 +
  1.1742 +        Type peek() {
  1.1743 +            return stack[stacksize-1];
  1.1744 +        }
  1.1745 +
  1.1746 +        Type pop2() {
  1.1747 +            if (debugCode) System.err.println("   popping " + 2);
  1.1748 +            stacksize -= 2;
  1.1749 +            Type result = stack[stacksize];
  1.1750 +            stack[stacksize] = null;
  1.1751 +            Assert.check(stack[stacksize+1] == null
  1.1752 +                    && result != null && width(result) == 2);
  1.1753 +            return result;
  1.1754 +        }
  1.1755 +
  1.1756 +        void pop(int n) {
  1.1757 +            if (debugCode) System.err.println("   popping " + n);
  1.1758 +            while (n > 0) {
  1.1759 +                stack[--stacksize] = null;
  1.1760 +                n--;
  1.1761 +            }
  1.1762 +        }
  1.1763 +
  1.1764 +        void pop(Type t) {
  1.1765 +            pop(width(t));
  1.1766 +        }
  1.1767 +
  1.1768 +        /** Force the top of the stack to be treated as this supertype
  1.1769 +         *  of its current type. */
  1.1770 +        void forceStackTop(Type t) {
  1.1771 +            if (!alive) return;
  1.1772 +            switch (t.getTag()) {
  1.1773 +            case CLASS:
  1.1774 +            case ARRAY:
  1.1775 +                int width = width(t);
  1.1776 +                Type old = stack[stacksize-width];
  1.1777 +                Assert.check(types.isSubtype(types.erasure(old),
  1.1778 +                                       types.erasure(t)));
  1.1779 +                stack[stacksize-width] = t;
  1.1780 +                break;
  1.1781 +            default:
  1.1782 +            }
  1.1783 +        }
  1.1784 +
  1.1785 +        void markInitialized(UninitializedType old) {
  1.1786 +            Type newtype = old.initializedType();
  1.1787 +            for (int i=0; i<stacksize; i++) {
  1.1788 +                if (stack[i] == old) stack[i] = newtype;
  1.1789 +            }
  1.1790 +            for (int i=0; i<lvar.length; i++) {
  1.1791 +                LocalVar lv = lvar[i];
  1.1792 +                if (lv != null && lv.sym.type == old) {
  1.1793 +                    VarSymbol sym = lv.sym;
  1.1794 +                    sym = sym.clone(sym.owner);
  1.1795 +                    sym.type = newtype;
  1.1796 +                    LocalVar newlv = lvar[i] = new LocalVar(sym);
  1.1797 +                    newlv.aliveRanges = lv.aliveRanges;
  1.1798 +                }
  1.1799 +            }
  1.1800 +        }
  1.1801 +
  1.1802 +        State join(State other) {
  1.1803 +            defined.andSet(other.defined);
  1.1804 +            Assert.check(stacksize == other.stacksize
  1.1805 +                    && nlocks == other.nlocks);
  1.1806 +            for (int i=0; i<stacksize; ) {
  1.1807 +                Type t = stack[i];
  1.1808 +                Type tother = other.stack[i];
  1.1809 +                Type result =
  1.1810 +                    t==tother ? t :
  1.1811 +                    types.isSubtype(t, tother) ? tother :
  1.1812 +                    types.isSubtype(tother, t) ? t :
  1.1813 +                    error();
  1.1814 +                int w = width(result);
  1.1815 +                stack[i] = result;
  1.1816 +                if (w == 2) Assert.checkNull(stack[i+1]);
  1.1817 +                i += w;
  1.1818 +            }
  1.1819 +            return this;
  1.1820 +        }
  1.1821 +
  1.1822 +        Type error() {
  1.1823 +            throw new AssertionError("inconsistent stack types at join point");
  1.1824 +        }
  1.1825 +
  1.1826 +        void dump() {
  1.1827 +            dump(-1);
  1.1828 +        }
  1.1829 +
  1.1830 +        void dump(int pc) {
  1.1831 +            System.err.print("stackMap for " + meth.owner + "." + meth);
  1.1832 +            if (pc == -1)
  1.1833 +                System.out.println();
  1.1834 +            else
  1.1835 +                System.out.println(" at " + pc);
  1.1836 +            System.err.println(" stack (from bottom):");
  1.1837 +            for (int i=0; i<stacksize; i++)
  1.1838 +                System.err.println("  " + i + ": " + stack[i]);
  1.1839 +
  1.1840 +            int lastLocal = 0;
  1.1841 +            for (int i=max_locals-1; i>=0; i--) {
  1.1842 +                if (defined.isMember(i)) {
  1.1843 +                    lastLocal = i;
  1.1844 +                    break;
  1.1845 +                }
  1.1846 +            }
  1.1847 +            if (lastLocal >= 0)
  1.1848 +                System.err.println(" locals:");
  1.1849 +            for (int i=0; i<=lastLocal; i++) {
  1.1850 +                System.err.print("  " + i + ": ");
  1.1851 +                if (defined.isMember(i)) {
  1.1852 +                    LocalVar var = lvar[i];
  1.1853 +                    if (var == null) {
  1.1854 +                        System.err.println("(none)");
  1.1855 +                    } else if (var.sym == null)
  1.1856 +                        System.err.println("UNKNOWN!");
  1.1857 +                    else
  1.1858 +                        System.err.println("" + var.sym + " of type " +
  1.1859 +                                           var.sym.erasure(types));
  1.1860 +                } else {
  1.1861 +                    System.err.println("undefined");
  1.1862 +                }
  1.1863 +            }
  1.1864 +            if (nlocks != 0) {
  1.1865 +                System.err.print(" locks:");
  1.1866 +                for (int i=0; i<nlocks; i++) {
  1.1867 +                    System.err.print(" " + locks[i]);
  1.1868 +                }
  1.1869 +                System.err.println();
  1.1870 +            }
  1.1871 +        }
  1.1872 +    }
  1.1873 +
  1.1874 +    static final Type jsrReturnValue = new JCPrimitiveType(INT, null);
  1.1875 +
  1.1876 +
  1.1877 +/* **************************************************************************
  1.1878 + * Local variables
  1.1879 + ****************************************************************************/
  1.1880 +
  1.1881 +    /** A live range of a local variable. */
  1.1882 +    static class LocalVar {
  1.1883 +        final VarSymbol sym;
  1.1884 +        final char reg;
  1.1885 +
  1.1886 +        class Range {
  1.1887 +            char start_pc = Character.MAX_VALUE;
  1.1888 +            char length = Character.MAX_VALUE;
  1.1889 +
  1.1890 +            Range() {}
  1.1891 +
  1.1892 +            Range(char start) {
  1.1893 +                this.start_pc = start;
  1.1894 +            }
  1.1895 +
  1.1896 +            Range(char start, char length) {
  1.1897 +                this.start_pc = start;
  1.1898 +                this.length = length;
  1.1899 +            }
  1.1900 +
  1.1901 +            boolean closed() {
  1.1902 +                return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE;
  1.1903 +            }
  1.1904 +
  1.1905 +            @Override
  1.1906 +            public String toString() {
  1.1907 +                int currentStartPC = start_pc;
  1.1908 +                int currentLength = length;
  1.1909 +                return "startpc = " + currentStartPC + " length " + currentLength;
  1.1910 +            }
  1.1911 +        }
  1.1912 +
  1.1913 +        java.util.List<Range> aliveRanges = new java.util.ArrayList<>();
  1.1914 +
  1.1915 +        LocalVar(VarSymbol v) {
  1.1916 +            this.sym = v;
  1.1917 +            this.reg = (char)v.adr;
  1.1918 +        }
  1.1919 +        public LocalVar dup() {
  1.1920 +            return new LocalVar(sym);
  1.1921 +        }
  1.1922 +
  1.1923 +        Range firstRange() {
  1.1924 +            return aliveRanges.isEmpty() ? null : aliveRanges.get(0);
  1.1925 +        }
  1.1926 +
  1.1927 +        Range lastRange() {
  1.1928 +            return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
  1.1929 +        }
  1.1930 +
  1.1931 +        void removeLastRange() {
  1.1932 +            Range lastRange = lastRange();
  1.1933 +            if (lastRange != null) {
  1.1934 +                aliveRanges.remove(lastRange);
  1.1935 +            }
  1.1936 +        }
  1.1937 +
  1.1938 +        @Override
  1.1939 +        public String toString() {
  1.1940 +            if (aliveRanges == null) {
  1.1941 +                return "empty local var";
  1.1942 +            }
  1.1943 +            StringBuilder sb = new StringBuilder().append(sym)
  1.1944 +                    .append(" in register ").append((int)reg).append(" \n");
  1.1945 +            for (Range r : aliveRanges) {
  1.1946 +                sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc)))
  1.1947 +                    .append(" length=").append(Integer.toString(((int)r.length)))
  1.1948 +                    .append("\n");
  1.1949 +            }
  1.1950 +            return sb.toString();
  1.1951 +        }
  1.1952 +
  1.1953 +        public void openRange(char start) {
  1.1954 +            if (!hasOpenRange()) {
  1.1955 +                aliveRanges.add(new Range(start));
  1.1956 +            }
  1.1957 +        }
  1.1958 +
  1.1959 +        public void closeRange(char end) {
  1.1960 +            if (isLastRangeInitialized()) {
  1.1961 +                Range range = lastRange();
  1.1962 +                if (range != null) {
  1.1963 +                    if (range.length == Character.MAX_VALUE) {
  1.1964 +                        range.length = end;
  1.1965 +                    }
  1.1966 +                }
  1.1967 +            } else {
  1.1968 +                removeLastRange();
  1.1969 +            }
  1.1970 +        }
  1.1971 +
  1.1972 +        public boolean hasOpenRange() {
  1.1973 +            if (aliveRanges.isEmpty()) {
  1.1974 +                return false;
  1.1975 +            }
  1.1976 +            return lastRange().length == Character.MAX_VALUE;
  1.1977 +        }
  1.1978 +
  1.1979 +        public boolean isLastRangeInitialized() {
  1.1980 +            if (aliveRanges.isEmpty()) {
  1.1981 +                return false;
  1.1982 +            }
  1.1983 +            return lastRange().start_pc != Character.MAX_VALUE;
  1.1984 +        }
  1.1985 +
  1.1986 +        public Range getWidestRange() {
  1.1987 +            if (aliveRanges.isEmpty()) {
  1.1988 +                return new Range();
  1.1989 +            } else {
  1.1990 +                Range firstRange = firstRange();
  1.1991 +                Range lastRange = lastRange();
  1.1992 +                char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc));
  1.1993 +                return new Range(firstRange.start_pc, length);
  1.1994 +            }
  1.1995 +         }
  1.1996 +
  1.1997 +    };
  1.1998 +
  1.1999 +    /** Local variables, indexed by register. */
  1.2000 +    LocalVar[] lvar;
  1.2001 +
  1.2002 +    /** Add a new local variable. */
  1.2003 +    private void addLocalVar(VarSymbol v) {
  1.2004 +        int adr = v.adr;
  1.2005 +        lvar = ArrayUtils.ensureCapacity(lvar, adr+1);
  1.2006 +        Assert.checkNull(lvar[adr]);
  1.2007 +        if (pendingJumps != null) {
  1.2008 +            resolvePending();
  1.2009 +        }
  1.2010 +        lvar[adr] = new LocalVar(v);
  1.2011 +        state.defined.excl(adr);
  1.2012 +    }
  1.2013 +
  1.2014 +
  1.2015 +    public void closeAliveRanges(JCTree tree) {
  1.2016 +        closeAliveRanges(tree, cp);
  1.2017 +    }
  1.2018 +
  1.2019 +    public void closeAliveRanges(JCTree tree, int closingCP) {
  1.2020 +        List<VarSymbol> locals = lvtRanges.getVars(meth, tree);
  1.2021 +        for (LocalVar localVar: lvar) {
  1.2022 +            for (VarSymbol aliveLocal : locals) {
  1.2023 +                if (localVar == null) {
  1.2024 +                    return;
  1.2025 +                }
  1.2026 +                if (localVar.sym == aliveLocal && localVar.lastRange() != null) {
  1.2027 +                    char length = (char)(closingCP - localVar.lastRange().start_pc);
  1.2028 +                    if (length > 0 && length < Character.MAX_VALUE) {
  1.2029 +                        localVar.closeRange(length);
  1.2030 +                    }
  1.2031 +                }
  1.2032 +            }
  1.2033 +        }
  1.2034 +    }
  1.2035 +
  1.2036 +    void adjustAliveRanges(int oldCP, int delta) {
  1.2037 +        for (LocalVar localVar: lvar) {
  1.2038 +            if (localVar == null) {
  1.2039 +                return;
  1.2040 +            }
  1.2041 +            for (LocalVar.Range range: localVar.aliveRanges) {
  1.2042 +                if (range.closed() && range.start_pc + range.length >= oldCP) {
  1.2043 +                    range.length += delta;
  1.2044 +                }
  1.2045 +            }
  1.2046 +        }
  1.2047 +    }
  1.2048 +
  1.2049 +    /**
  1.2050 +     * Calculates the size of the LocalVariableTable.
  1.2051 +     */
  1.2052 +    public int getLVTSize() {
  1.2053 +        int result = varBufferSize;
  1.2054 +        for (int i = 0; i < varBufferSize; i++) {
  1.2055 +            LocalVar var = varBuffer[i];
  1.2056 +            result += var.aliveRanges.size() - 1;
  1.2057 +        }
  1.2058 +        return result;
  1.2059 +    }
  1.2060 +
  1.2061 +    /** Set the current variable defined state. */
  1.2062 +    public void setDefined(Bits newDefined) {
  1.2063 +        if (alive && newDefined != state.defined) {
  1.2064 +            Bits diff = new Bits(state.defined).xorSet(newDefined);
  1.2065 +            for (int adr = diff.nextBit(0);
  1.2066 +                 adr >= 0;
  1.2067 +                 adr = diff.nextBit(adr+1)) {
  1.2068 +                if (adr >= nextreg)
  1.2069 +                    state.defined.excl(adr);
  1.2070 +                else if (state.defined.isMember(adr))
  1.2071 +                    setUndefined(adr);
  1.2072 +                else
  1.2073 +                    setDefined(adr);
  1.2074 +            }
  1.2075 +        }
  1.2076 +    }
  1.2077 +
  1.2078 +    /** Mark a register as being (possibly) defined. */
  1.2079 +    public void setDefined(int adr) {
  1.2080 +        LocalVar v = lvar[adr];
  1.2081 +        if (v == null) {
  1.2082 +            state.defined.excl(adr);
  1.2083 +        } else {
  1.2084 +            state.defined.incl(adr);
  1.2085 +            if (cp < Character.MAX_VALUE) {
  1.2086 +                v.openRange((char)cp);
  1.2087 +            }
  1.2088 +        }
  1.2089 +    }
  1.2090 +
  1.2091 +    /** Mark a register as being undefined. */
  1.2092 +    public void setUndefined(int adr) {
  1.2093 +        state.defined.excl(adr);
  1.2094 +        if (adr < lvar.length &&
  1.2095 +            lvar[adr] != null &&
  1.2096 +            lvar[adr].isLastRangeInitialized()) {
  1.2097 +            LocalVar v = lvar[adr];
  1.2098 +            char length = (char)(curCP() - v.lastRange().start_pc);
  1.2099 +            if (length > 0 && length < Character.MAX_VALUE) {
  1.2100 +                lvar[adr] = v.dup();
  1.2101 +                v.closeRange(length);
  1.2102 +                putVar(v);
  1.2103 +            } else {
  1.2104 +                v.removeLastRange();
  1.2105 +            }
  1.2106 +        }
  1.2107 +    }
  1.2108 +
  1.2109 +    /** End the scope of a variable. */
  1.2110 +    private void endScope(int adr) {
  1.2111 +        LocalVar v = lvar[adr];
  1.2112 +        if (v != null) {
  1.2113 +            if (v.isLastRangeInitialized()) {
  1.2114 +                char length = (char)(curCP() - v.lastRange().start_pc);
  1.2115 +                if (length < Character.MAX_VALUE) {
  1.2116 +                    v.closeRange(length);
  1.2117 +                    putVar(v);
  1.2118 +                    fillLocalVarPosition(v);
  1.2119 +                }
  1.2120 +            }
  1.2121 +            /** the call to curCP() can implicitly adjust the current cp, if so
  1.2122 +             * the alive range of local variables may be modified. Thus we need
  1.2123 +             * all of them. For this reason assigning null to the given address
  1.2124 +             * should be the last action to do.
  1.2125 +             */
  1.2126 +            lvar[adr] = null;
  1.2127 +        }
  1.2128 +        state.defined.excl(adr);
  1.2129 +    }
  1.2130 +
  1.2131 +    private void fillLocalVarPosition(LocalVar lv) {
  1.2132 +        if (lv == null || lv.sym == null || !lv.sym.hasTypeAnnotations())
  1.2133 +            return;
  1.2134 +        for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
  1.2135 +            TypeAnnotationPosition p = ta.position;
  1.2136 +            LocalVar.Range widestRange = lv.getWidestRange();
  1.2137 +            p.lvarOffset = new int[] { (int)widestRange.start_pc };
  1.2138 +            p.lvarLength = new int[] { (int)widestRange.length };
  1.2139 +            p.lvarIndex = new int[] { (int)lv.reg };
  1.2140 +            p.isValidOffset = true;
  1.2141 +        }
  1.2142 +    }
  1.2143 +
  1.2144 +    // Method to be called after compressCatchTable to
  1.2145 +    // fill in the exception table index for type
  1.2146 +    // annotations on exception parameters.
  1.2147 +    public void fillExceptionParameterPositions() {
  1.2148 +        for (int i = 0; i < varBufferSize; ++i) {
  1.2149 +            LocalVar lv = varBuffer[i];
  1.2150 +            if (lv == null || lv.sym == null
  1.2151 +                    || !lv.sym.hasTypeAnnotations()
  1.2152 +                    || !lv.sym.isExceptionParameter())
  1.2153 +                continue;
  1.2154 +
  1.2155 +            for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
  1.2156 +                TypeAnnotationPosition p = ta.position;
  1.2157 +                // At this point p.type_index contains the catch type index.
  1.2158 +                // Use that index to determine the exception table index.
  1.2159 +                // We can afterwards discard the type_index.
  1.2160 +                // A TA position is shared for all type annotations in the
  1.2161 +                // same location; updating one is enough.
  1.2162 +                // Use -666 as a marker that the exception_index was already updated.
  1.2163 +                if (p.type_index != -666) {
  1.2164 +                    p.exception_index = findExceptionIndex(p.type_index);
  1.2165 +                    p.type_index = -666;
  1.2166 +                }
  1.2167 +            }
  1.2168 +        }
  1.2169 +    }
  1.2170 +
  1.2171 +    private int findExceptionIndex(int catchType) {
  1.2172 +        if (catchType == Integer.MIN_VALUE) {
  1.2173 +            // We didn't set the catch type index correctly.
  1.2174 +            // This shouldn't happen.
  1.2175 +            // TODO: issue error?
  1.2176 +            return -1;
  1.2177 +        }
  1.2178 +        List<char[]> iter = catchInfo.toList();
  1.2179 +        int len = catchInfo.length();
  1.2180 +        for (int i = 0; i < len; ++i) {
  1.2181 +            char[] catchEntry = iter.head;
  1.2182 +            iter = iter.tail;
  1.2183 +            char ct = catchEntry[3];
  1.2184 +            if (catchType == ct) {
  1.2185 +                return i;
  1.2186 +            }
  1.2187 +        }
  1.2188 +        return -1;
  1.2189 +    }
  1.2190 +
  1.2191 +    /** Put a live variable range into the buffer to be output to the
  1.2192 +     *  class file.
  1.2193 +     */
  1.2194 +    void putVar(LocalVar var) {
  1.2195 +        // Keep local variables if
  1.2196 +        // 1) we need them for debug information
  1.2197 +        // 2) it is an exception type and it contains type annotations
  1.2198 +        boolean keepLocalVariables = varDebugInfo ||
  1.2199 +            (var.sym.isExceptionParameter() && var.sym.hasTypeAnnotations());
  1.2200 +        if (!keepLocalVariables) return;
  1.2201 +        if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return;
  1.2202 +        if (varBuffer == null)
  1.2203 +            varBuffer = new LocalVar[20];
  1.2204 +        else
  1.2205 +            varBuffer = ArrayUtils.ensureCapacity(varBuffer, varBufferSize);
  1.2206 +        varBuffer[varBufferSize++] = var;
  1.2207 +    }
  1.2208 +
  1.2209 +    /** Previously live local variables, to be put into the variable table. */
  1.2210 +    LocalVar[] varBuffer;
  1.2211 +    int varBufferSize;
  1.2212 +
  1.2213 +    /** Create a new local variable address and return it.
  1.2214 +     */
  1.2215 +    private int newLocal(int typecode) {
  1.2216 +        int reg = nextreg;
  1.2217 +        int w = width(typecode);
  1.2218 +        nextreg = reg + w;
  1.2219 +        if (nextreg > max_locals) max_locals = nextreg;
  1.2220 +        return reg;
  1.2221 +    }
  1.2222 +
  1.2223 +    private int newLocal(Type type) {
  1.2224 +        return newLocal(typecode(type));
  1.2225 +    }
  1.2226 +
  1.2227 +    public int newLocal(VarSymbol v) {
  1.2228 +        int reg = v.adr = newLocal(v.erasure(types));
  1.2229 +        addLocalVar(v);
  1.2230 +        return reg;
  1.2231 +    }
  1.2232 +
  1.2233 +    /** Start a set of fresh registers.
  1.2234 +     */
  1.2235 +    public void newRegSegment() {
  1.2236 +        nextreg = max_locals;
  1.2237 +    }
  1.2238 +
  1.2239 +    /** End scopes of all variables with registers &ge; first.
  1.2240 +     */
  1.2241 +    public void endScopes(int first) {
  1.2242 +        int prevNextReg = nextreg;
  1.2243 +        nextreg = first;
  1.2244 +        for (int i = nextreg; i < prevNextReg; i++) endScope(i);
  1.2245 +    }
  1.2246 +
  1.2247 +/**************************************************************************
  1.2248 + * static tables
  1.2249 + *************************************************************************/
  1.2250 +
  1.2251 +    public static String mnem(int opcode) {
  1.2252 +        return Mneumonics.mnem[opcode];
  1.2253 +    }
  1.2254 +
  1.2255 +    private static class Mneumonics {
  1.2256 +        private final static String[] mnem = new String[ByteCodeCount];
  1.2257 +        static {
  1.2258 +            mnem[nop] = "nop";
  1.2259 +            mnem[aconst_null] = "aconst_null";
  1.2260 +            mnem[iconst_m1] = "iconst_m1";
  1.2261 +            mnem[iconst_0] = "iconst_0";
  1.2262 +            mnem[iconst_1] = "iconst_1";
  1.2263 +            mnem[iconst_2] = "iconst_2";
  1.2264 +            mnem[iconst_3] = "iconst_3";
  1.2265 +            mnem[iconst_4] = "iconst_4";
  1.2266 +            mnem[iconst_5] = "iconst_5";
  1.2267 +            mnem[lconst_0] = "lconst_0";
  1.2268 +            mnem[lconst_1] = "lconst_1";
  1.2269 +            mnem[fconst_0] = "fconst_0";
  1.2270 +            mnem[fconst_1] = "fconst_1";
  1.2271 +            mnem[fconst_2] = "fconst_2";
  1.2272 +            mnem[dconst_0] = "dconst_0";
  1.2273 +            mnem[dconst_1] = "dconst_1";
  1.2274 +            mnem[bipush] = "bipush";
  1.2275 +            mnem[sipush] = "sipush";
  1.2276 +            mnem[ldc1] = "ldc1";
  1.2277 +            mnem[ldc2] = "ldc2";
  1.2278 +            mnem[ldc2w] = "ldc2w";
  1.2279 +            mnem[iload] = "iload";
  1.2280 +            mnem[lload] = "lload";
  1.2281 +            mnem[fload] = "fload";
  1.2282 +            mnem[dload] = "dload";
  1.2283 +            mnem[aload] = "aload";
  1.2284 +            mnem[iload_0] = "iload_0";
  1.2285 +            mnem[lload_0] = "lload_0";
  1.2286 +            mnem[fload_0] = "fload_0";
  1.2287 +            mnem[dload_0] = "dload_0";
  1.2288 +            mnem[aload_0] = "aload_0";
  1.2289 +            mnem[iload_1] = "iload_1";
  1.2290 +            mnem[lload_1] = "lload_1";
  1.2291 +            mnem[fload_1] = "fload_1";
  1.2292 +            mnem[dload_1] = "dload_1";
  1.2293 +            mnem[aload_1] = "aload_1";
  1.2294 +            mnem[iload_2] = "iload_2";
  1.2295 +            mnem[lload_2] = "lload_2";
  1.2296 +            mnem[fload_2] = "fload_2";
  1.2297 +            mnem[dload_2] = "dload_2";
  1.2298 +            mnem[aload_2] = "aload_2";
  1.2299 +            mnem[iload_3] = "iload_3";
  1.2300 +            mnem[lload_3] = "lload_3";
  1.2301 +            mnem[fload_3] = "fload_3";
  1.2302 +            mnem[dload_3] = "dload_3";
  1.2303 +            mnem[aload_3] = "aload_3";
  1.2304 +            mnem[iaload] = "iaload";
  1.2305 +            mnem[laload] = "laload";
  1.2306 +            mnem[faload] = "faload";
  1.2307 +            mnem[daload] = "daload";
  1.2308 +            mnem[aaload] = "aaload";
  1.2309 +            mnem[baload] = "baload";
  1.2310 +            mnem[caload] = "caload";
  1.2311 +            mnem[saload] = "saload";
  1.2312 +            mnem[istore] = "istore";
  1.2313 +            mnem[lstore] = "lstore";
  1.2314 +            mnem[fstore] = "fstore";
  1.2315 +            mnem[dstore] = "dstore";
  1.2316 +            mnem[astore] = "astore";
  1.2317 +            mnem[istore_0] = "istore_0";
  1.2318 +            mnem[lstore_0] = "lstore_0";
  1.2319 +            mnem[fstore_0] = "fstore_0";
  1.2320 +            mnem[dstore_0] = "dstore_0";
  1.2321 +            mnem[astore_0] = "astore_0";
  1.2322 +            mnem[istore_1] = "istore_1";
  1.2323 +            mnem[lstore_1] = "lstore_1";
  1.2324 +            mnem[fstore_1] = "fstore_1";
  1.2325 +            mnem[dstore_1] = "dstore_1";
  1.2326 +            mnem[astore_1] = "astore_1";
  1.2327 +            mnem[istore_2] = "istore_2";
  1.2328 +            mnem[lstore_2] = "lstore_2";
  1.2329 +            mnem[fstore_2] = "fstore_2";
  1.2330 +            mnem[dstore_2] = "dstore_2";
  1.2331 +            mnem[astore_2] = "astore_2";
  1.2332 +            mnem[istore_3] = "istore_3";
  1.2333 +            mnem[lstore_3] = "lstore_3";
  1.2334 +            mnem[fstore_3] = "fstore_3";
  1.2335 +            mnem[dstore_3] = "dstore_3";
  1.2336 +            mnem[astore_3] = "astore_3";
  1.2337 +            mnem[iastore] = "iastore";
  1.2338 +            mnem[lastore] = "lastore";
  1.2339 +            mnem[fastore] = "fastore";
  1.2340 +            mnem[dastore] = "dastore";
  1.2341 +            mnem[aastore] = "aastore";
  1.2342 +            mnem[bastore] = "bastore";
  1.2343 +            mnem[castore] = "castore";
  1.2344 +            mnem[sastore] = "sastore";
  1.2345 +            mnem[pop] = "pop";
  1.2346 +            mnem[pop2] = "pop2";
  1.2347 +            mnem[dup] = "dup";
  1.2348 +            mnem[dup_x1] = "dup_x1";
  1.2349 +            mnem[dup_x2] = "dup_x2";
  1.2350 +            mnem[dup2] = "dup2";
  1.2351 +            mnem[dup2_x1] = "dup2_x1";
  1.2352 +            mnem[dup2_x2] = "dup2_x2";
  1.2353 +            mnem[swap] = "swap";
  1.2354 +            mnem[iadd] = "iadd";
  1.2355 +            mnem[ladd] = "ladd";
  1.2356 +            mnem[fadd] = "fadd";
  1.2357 +            mnem[dadd] = "dadd";
  1.2358 +            mnem[isub] = "isub";
  1.2359 +            mnem[lsub] = "lsub";
  1.2360 +            mnem[fsub] = "fsub";
  1.2361 +            mnem[dsub] = "dsub";
  1.2362 +            mnem[imul] = "imul";
  1.2363 +            mnem[lmul] = "lmul";
  1.2364 +            mnem[fmul] = "fmul";
  1.2365 +            mnem[dmul] = "dmul";
  1.2366 +            mnem[idiv] = "idiv";
  1.2367 +            mnem[ldiv] = "ldiv";
  1.2368 +            mnem[fdiv] = "fdiv";
  1.2369 +            mnem[ddiv] = "ddiv";
  1.2370 +            mnem[imod] = "imod";
  1.2371 +            mnem[lmod] = "lmod";
  1.2372 +            mnem[fmod] = "fmod";
  1.2373 +            mnem[dmod] = "dmod";
  1.2374 +            mnem[ineg] = "ineg";
  1.2375 +            mnem[lneg] = "lneg";
  1.2376 +            mnem[fneg] = "fneg";
  1.2377 +            mnem[dneg] = "dneg";
  1.2378 +            mnem[ishl] = "ishl";
  1.2379 +            mnem[lshl] = "lshl";
  1.2380 +            mnem[ishr] = "ishr";
  1.2381 +            mnem[lshr] = "lshr";
  1.2382 +            mnem[iushr] = "iushr";
  1.2383 +            mnem[lushr] = "lushr";
  1.2384 +            mnem[iand] = "iand";
  1.2385 +            mnem[land] = "land";
  1.2386 +            mnem[ior] = "ior";
  1.2387 +            mnem[lor] = "lor";
  1.2388 +            mnem[ixor] = "ixor";
  1.2389 +            mnem[lxor] = "lxor";
  1.2390 +            mnem[iinc] = "iinc";
  1.2391 +            mnem[i2l] = "i2l";
  1.2392 +            mnem[i2f] = "i2f";
  1.2393 +            mnem[i2d] = "i2d";
  1.2394 +            mnem[l2i] = "l2i";
  1.2395 +            mnem[l2f] = "l2f";
  1.2396 +            mnem[l2d] = "l2d";
  1.2397 +            mnem[f2i] = "f2i";
  1.2398 +            mnem[f2l] = "f2l";
  1.2399 +            mnem[f2d] = "f2d";
  1.2400 +            mnem[d2i] = "d2i";
  1.2401 +            mnem[d2l] = "d2l";
  1.2402 +            mnem[d2f] = "d2f";
  1.2403 +            mnem[int2byte] = "int2byte";
  1.2404 +            mnem[int2char] = "int2char";
  1.2405 +            mnem[int2short] = "int2short";
  1.2406 +            mnem[lcmp] = "lcmp";
  1.2407 +            mnem[fcmpl] = "fcmpl";
  1.2408 +            mnem[fcmpg] = "fcmpg";
  1.2409 +            mnem[dcmpl] = "dcmpl";
  1.2410 +            mnem[dcmpg] = "dcmpg";
  1.2411 +            mnem[ifeq] = "ifeq";
  1.2412 +            mnem[ifne] = "ifne";
  1.2413 +            mnem[iflt] = "iflt";
  1.2414 +            mnem[ifge] = "ifge";
  1.2415 +            mnem[ifgt] = "ifgt";
  1.2416 +            mnem[ifle] = "ifle";
  1.2417 +            mnem[if_icmpeq] = "if_icmpeq";
  1.2418 +            mnem[if_icmpne] = "if_icmpne";
  1.2419 +            mnem[if_icmplt] = "if_icmplt";
  1.2420 +            mnem[if_icmpge] = "if_icmpge";
  1.2421 +            mnem[if_icmpgt] = "if_icmpgt";
  1.2422 +            mnem[if_icmple] = "if_icmple";
  1.2423 +            mnem[if_acmpeq] = "if_acmpeq";
  1.2424 +            mnem[if_acmpne] = "if_acmpne";
  1.2425 +            mnem[goto_] = "goto_";
  1.2426 +            mnem[jsr] = "jsr";
  1.2427 +            mnem[ret] = "ret";
  1.2428 +            mnem[tableswitch] = "tableswitch";
  1.2429 +            mnem[lookupswitch] = "lookupswitch";
  1.2430 +            mnem[ireturn] = "ireturn";
  1.2431 +            mnem[lreturn] = "lreturn";
  1.2432 +            mnem[freturn] = "freturn";
  1.2433 +            mnem[dreturn] = "dreturn";
  1.2434 +            mnem[areturn] = "areturn";
  1.2435 +            mnem[return_] = "return_";
  1.2436 +            mnem[getstatic] = "getstatic";
  1.2437 +            mnem[putstatic] = "putstatic";
  1.2438 +            mnem[getfield] = "getfield";
  1.2439 +            mnem[putfield] = "putfield";
  1.2440 +            mnem[invokevirtual] = "invokevirtual";
  1.2441 +            mnem[invokespecial] = "invokespecial";
  1.2442 +            mnem[invokestatic] = "invokestatic";
  1.2443 +            mnem[invokeinterface] = "invokeinterface";
  1.2444 +            mnem[invokedynamic] = "invokedynamic";
  1.2445 +            mnem[new_] = "new_";
  1.2446 +            mnem[newarray] = "newarray";
  1.2447 +            mnem[anewarray] = "anewarray";
  1.2448 +            mnem[arraylength] = "arraylength";
  1.2449 +            mnem[athrow] = "athrow";
  1.2450 +            mnem[checkcast] = "checkcast";
  1.2451 +            mnem[instanceof_] = "instanceof_";
  1.2452 +            mnem[monitorenter] = "monitorenter";
  1.2453 +            mnem[monitorexit] = "monitorexit";
  1.2454 +            mnem[wide] = "wide";
  1.2455 +            mnem[multianewarray] = "multianewarray";
  1.2456 +            mnem[if_acmp_null] = "if_acmp_null";
  1.2457 +            mnem[if_acmp_nonnull] = "if_acmp_nonnull";
  1.2458 +            mnem[goto_w] = "goto_w";
  1.2459 +            mnem[jsr_w] = "jsr_w";
  1.2460 +            mnem[breakpoint] = "breakpoint";
  1.2461 +        }
  1.2462 +    }
  1.2463 +}

mercurial