1 /*
   2  * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.jvm;
  27 
  28 import com.sun.tools.javac.code.*;
  29 import com.sun.tools.javac.code.Symbol.*;
  30 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  31 import com.sun.tools.javac.util.*;
  32 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  33 
  34 import java.util.function.ToIntBiFunction;
  35 import java.util.function.ToIntFunction;
  36 
  37 import static com.sun.tools.javac.code.TypeTag.ARRAY;
  38 import static com.sun.tools.javac.code.TypeTag.BOT;
  39 import static com.sun.tools.javac.code.TypeTag.DOUBLE;
  40 import static com.sun.tools.javac.code.TypeTag.INT;
  41 import static com.sun.tools.javac.code.TypeTag.LONG;
  42 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
  43 import static com.sun.tools.javac.jvm.ByteCodes.*;
  44 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Class;
  45 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Double;
  46 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Fieldref;
  47 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Float;
  48 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Integer;
  49 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_InterfaceMethodref;
  50 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Long;
  51 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodHandle;
  52 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodType;
  53 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Methodref;
  54 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_String;
  55 import static com.sun.tools.javac.jvm.UninitializedType.*;
  56 import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
  57 import java.util.Arrays;
  58 
  59 /** An internal structure that corresponds to the code attribute of
  60  *  methods in a classfile. The class also provides some utility operations to
  61  *  generate bytecode instructions.
  62  *
  63  *  <p><b>This is NOT part of any supported API.
  64  *  If you write code that depends on this, you do so at your own risk.
  65  *  This code and its internal interfaces are subject to change or
  66  *  deletion without notice.</b>
  67  */
  68 public class Code {
  69 
  70     public final boolean debugCode;
  71     public final boolean needStackMap;
  72 
  73     public enum StackMapFormat {
  74         NONE,
  75         CLDC {
  76             Name getAttributeName(Names names) {
  77                 return names.StackMap;
  78             }
  79         },
  80         JSR202 {
  81             Name getAttributeName(Names names) {
  82                 return names.StackMapTable;
  83             }
  84         };
  85         Name getAttributeName(Names names) {
  86             return names.empty;
  87         }
  88     }
  89 
  90     final Types types;
  91     final Symtab syms;
  92     final PoolWriter poolWriter;
  93 
  94 /*---------- classfile fields: --------------- */
  95 
  96     /** The maximum stack size.
  97      */
  98     public int max_stack = 0;
  99 
 100     /** The maximum number of local variable slots.
 101      */
 102     public int max_locals = 0;
 103 
 104     /** The code buffer.
 105      */
 106     public byte[] code = new byte[64];
 107 
 108     /** the current code pointer.
 109      */
 110     public int cp = 0;
 111 
 112     /** Check the code against VM spec limits; if
 113      *  problems report them and return true.
 114      */
 115     public boolean checkLimits(DiagnosticPosition pos, Log log) {
 116         if (cp > ClassFile.MAX_CODE) {
 117             log.error(pos, Errors.LimitCode);
 118             return true;
 119         }
 120         if (max_locals > ClassFile.MAX_LOCALS) {
 121             log.error(pos, Errors.LimitLocals);
 122             return true;
 123         }
 124         if (max_stack > ClassFile.MAX_STACK) {
 125             log.error(pos, Errors.LimitStack);
 126             return true;
 127         }
 128         return false;
 129     }
 130 
 131     /** A buffer for expression catch data. Each enter is a vector
 132      *  of four unsigned shorts.
 133      */
 134     ListBuffer<char[]> catchInfo = new ListBuffer<>();
 135 
 136     /** A buffer for line number information. Each entry is a vector
 137      *  of two unsigned shorts.
 138      */
 139     List<char[]> lineInfo = List.nil(); // handled in stack fashion
 140 
 141     /** The CharacterRangeTable
 142      */
 143     public CRTable crt;
 144 
 145 /*---------- internal fields: --------------- */
 146 
 147     /** Are we generating code with jumps &ge; 32K?
 148      */
 149     public boolean fatcode;
 150 
 151     /** Code generation enabled?
 152      */
 153     private boolean alive = true;
 154 
 155     /** The current machine state (registers and stack).
 156      */
 157     State state;
 158 
 159     /** Is it forbidden to compactify code, because something is
 160      *  pointing to current location?
 161      */
 162     private boolean fixedPc = false;
 163 
 164     /** The next available register.
 165      */
 166     public int nextreg = 0;
 167 
 168     /** A chain for jumps to be resolved before the next opcode is emitted.
 169      *  We do this lazily to avoid jumps to jumps.
 170      */
 171     Chain pendingJumps = null;
 172 
 173     /** The position of the currently statement, if we are at the
 174      *  start of this statement, NOPOS otherwise.
 175      *  We need this to emit line numbers lazily, which we need to do
 176      *  because of jump-to-jump optimization.
 177      */
 178     int pendingStatPos = Position.NOPOS;
 179 
 180     /** Set true when a stackMap is needed at the current PC. */
 181     boolean pendingStackMap = false;
 182 
 183     /** The stack map format to be generated. */
 184     StackMapFormat stackMap;
 185 
 186     /** Switch: emit variable debug info.
 187      */
 188     boolean varDebugInfo;
 189 
 190     /** Switch: emit line number info.
 191      */
 192     boolean lineDebugInfo;
 193 
 194     /** Emit line number info if map supplied
 195      */
 196     Position.LineMap lineMap;
 197 
 198     final MethodSymbol meth;
 199 
 200     private int letExprStackPos = 0;
 201 
 202     /** Construct a code object, given the settings of the fatcode,
 203      *  debugging info switches and the CharacterRangeTable.
 204      */
 205     public Code(MethodSymbol meth,
 206                 boolean fatcode,
 207                 Position.LineMap lineMap,
 208                 boolean varDebugInfo,
 209                 StackMapFormat stackMap,
 210                 boolean debugCode,
 211                 CRTable crt,
 212                 Symtab syms,
 213                 Types types,
 214                 PoolWriter poolWriter) {
 215         this.meth = meth;
 216         this.fatcode = fatcode;
 217         this.lineMap = lineMap;
 218         this.lineDebugInfo = lineMap != null;
 219         this.varDebugInfo = varDebugInfo;
 220         this.crt = crt;
 221         this.syms = syms;
 222         this.types = types;
 223         this.poolWriter = poolWriter;
 224         this.debugCode = debugCode;
 225         this.stackMap = stackMap;
 226         switch (stackMap) {
 227         case CLDC:
 228         case JSR202:
 229             this.needStackMap = true;
 230             break;
 231         default:
 232             this.needStackMap = false;
 233         }
 234         state = new State();
 235         lvar = new LocalVar[20];
 236     }
 237 
 238 
 239 /* **************************************************************************
 240  * Typecodes & related stuff
 241  ****************************************************************************/
 242 
 243     /** Given a type, return its type code (used implicitly in the
 244      *  JVM architecture).
 245      */
 246     public static int typecode(Type type) {
 247         switch (type.getTag()) {
 248         case BYTE: return BYTEcode;
 249         case SHORT: return SHORTcode;
 250         case CHAR: return CHARcode;
 251         case INT: return INTcode;
 252         case LONG: return LONGcode;
 253         case FLOAT: return FLOATcode;
 254         case DOUBLE: return DOUBLEcode;
 255         case BOOLEAN: return BYTEcode;
 256         case VOID: return VOIDcode;
 257         case CLASS:
 258         case ARRAY:
 259         case METHOD:
 260         case BOT:
 261         case TYPEVAR:
 262         case UNINITIALIZED_THIS:
 263         case UNINITIALIZED_OBJECT:
 264             return OBJECTcode;
 265         default: throw new AssertionError("typecode " + type.getTag());
 266         }
 267     }
 268 
 269     /** Collapse type code for subtypes of int to INTcode.
 270      */
 271     public static int truncate(int tc) {
 272         switch (tc) {
 273         case BYTEcode: case SHORTcode: case CHARcode: return INTcode;
 274         default: return tc;
 275         }
 276     }
 277 
 278     /** The width in bytes of objects of the type.
 279      */
 280     public static int width(int typecode) {
 281         switch (typecode) {
 282         case LONGcode: case DOUBLEcode: return 2;
 283         case VOIDcode: return 0;
 284         default: return 1;
 285         }
 286     }
 287 
 288     public static int width(Type type) {
 289         return type == null ? 1 : width(typecode(type));
 290     }
 291 
 292     /** The total width taken up by a vector of objects.
 293      */
 294     public static int width(List<Type> types) {
 295         int w = 0;
 296         for (List<Type> l = types; l.nonEmpty(); l = l.tail)
 297             w = w + width(l.head);
 298         return w;
 299     }
 300 
 301     /** Given a type, return its code for allocating arrays of that type.
 302      */
 303     public static int arraycode(Type type) {
 304         switch (type.getTag()) {
 305         case BYTE: return 8;
 306         case BOOLEAN: return 4;
 307         case SHORT: return 9;
 308         case CHAR: return 5;
 309         case INT: return 10;
 310         case LONG: return 11;
 311         case FLOAT: return 6;
 312         case DOUBLE: return 7;
 313         case CLASS: return 0;
 314         case ARRAY: return 1;
 315         default: throw new AssertionError("arraycode " + type);
 316         }
 317     }
 318 
 319 
 320 /* **************************************************************************
 321  * Emit code
 322  ****************************************************************************/
 323 
 324     /** The current output code pointer.
 325      */
 326     public int curCP() {
 327         /*
 328          * This method has side-effects because calling it can indirectly provoke
 329          *  extra code generation, like goto instructions, depending on the context
 330          *  where it's called.
 331          *  Use with care or even better avoid using it.
 332          */
 333         if (pendingJumps != null) {
 334             resolvePending();
 335         }
 336         if (pendingStatPos != Position.NOPOS) {
 337             markStatBegin();
 338         }
 339         fixedPc = true;
 340         return cp;
 341     }
 342 
 343     /** Emit a byte of code.
 344      */
 345     private  void emit1(int od) {
 346         if (!alive) return;
 347         code = ArrayUtils.ensureCapacity(code, cp);
 348         code[cp++] = (byte)od;
 349     }
 350 
 351     /** Emit two bytes of code.
 352      */
 353     private void emit2(int od) {
 354         if (!alive) return;
 355         if (cp + 2 > code.length) {
 356             emit1(od >> 8);
 357             emit1(od);
 358         } else {
 359             code[cp++] = (byte)(od >> 8);
 360             code[cp++] = (byte)od;
 361         }
 362     }
 363 
 364     /** Emit four bytes of code.
 365      */
 366     public void emit4(int od) {
 367         if (!alive) return;
 368         if (cp + 4 > code.length) {
 369             emit1(od >> 24);
 370             emit1(od >> 16);
 371             emit1(od >> 8);
 372             emit1(od);
 373         } else {
 374             code[cp++] = (byte)(od >> 24);
 375             code[cp++] = (byte)(od >> 16);
 376             code[cp++] = (byte)(od >> 8);
 377             code[cp++] = (byte)od;
 378         }
 379     }
 380 
 381     /** Emit an opcode.
 382      */
 383     private void emitop(int op) {
 384         if (pendingJumps != null) resolvePending();
 385         if (alive) {
 386             if (pendingStatPos != Position.NOPOS)
 387                 markStatBegin();
 388             if (pendingStackMap) {
 389                 pendingStackMap = false;
 390                 emitStackMap();
 391             }
 392             if (debugCode)
 393                 System.err.println("emit@" + cp + " stack=" +
 394                                    state.stacksize + ": " +
 395                                    mnem(op));
 396             emit1(op);
 397         }
 398     }
 399 
 400     void postop() {
 401         Assert.check(alive || isStatementStart());
 402     }
 403 
 404     /** Emit a ldc (or ldc_w) instruction, taking into account operand size
 405     */
 406     public void emitLdc(LoadableConstant constant) {
 407         int od = poolWriter.putConstant(constant);
 408         Type constantType = types.constantType(constant);
 409         if (constantType.hasTag(LONG) || constantType.hasTag(DOUBLE)) {
 410             emitop2(ldc2w, od, constant);
 411         } else if (od <= 255) {
 412             emitop1(ldc1, od, constant);
 413         } else {
 414             emitop2(ldc2, od, constant);
 415         }
 416     }
 417 
 418     /** Emit a multinewarray instruction.
 419      */
 420     public void emitMultianewarray(int ndims, int type, Type arrayType) {
 421         emitop(multianewarray);
 422         if (!alive) return;
 423         emit2(type);
 424         emit1(ndims);
 425         state.pop(ndims);
 426         state.push(arrayType);
 427     }
 428 
 429     /** Emit newarray.
 430      */
 431     public void emitNewarray(int elemcode, Type arrayType) {
 432         emitop(newarray);
 433         if (!alive) return;
 434         emit1(elemcode);
 435         state.pop(1); // count
 436         state.push(arrayType);
 437     }
 438 
 439     /** Emit anewarray.
 440      */
 441     public void emitAnewarray(int od, Type arrayType) {
 442         emitop(anewarray);
 443         if (!alive) return;
 444         emit2(od);
 445         state.pop(1);
 446         state.push(arrayType);
 447     }
 448 
 449     /** Emit an invokeinterface instruction.
 450      */
 451     public void emitInvokeinterface(Symbol member, Type mtype) {
 452         int argsize = width(mtype.getParameterTypes());
 453         emitop(invokeinterface);
 454         if (!alive) return;
 455         emit2(poolWriter.putMember(member));
 456         emit1(argsize + 1);
 457         emit1(0);
 458         state.pop(argsize + 1);
 459         state.push(mtype.getReturnType());
 460     }
 461 
 462     /** Emit an invokespecial instruction.
 463      */
 464     public void emitInvokespecial(Symbol member, Type mtype) {
 465         int argsize = width(mtype.getParameterTypes());
 466         emitop(invokespecial);
 467         if (!alive) return;
 468         emit2(poolWriter.putMember(member));
 469         state.pop(argsize);
 470         if (member.isConstructor())
 471             state.markInitialized((UninitializedType)state.peek());
 472         state.pop(1);
 473         state.push(mtype.getReturnType());
 474     }
 475 
 476     /** Emit an invokestatic instruction.
 477      */
 478     public void emitInvokestatic(Symbol member, Type mtype) {
 479         int argsize = width(mtype.getParameterTypes());
 480         emitop(invokestatic);
 481         if (!alive) return;
 482         emit2(poolWriter.putMember(member));
 483         state.pop(argsize);
 484         state.push(mtype.getReturnType());
 485     }
 486 
 487     /** Emit an invokevirtual instruction.
 488      */
 489     public void emitInvokevirtual(Symbol member, Type mtype) {
 490         int argsize = width(mtype.getParameterTypes());
 491         emitop(invokevirtual);
 492         if (!alive) return;
 493         emit2(poolWriter.putMember(member));
 494         state.pop(argsize + 1);
 495         state.push(mtype.getReturnType());
 496     }
 497 
 498     /** Emit an invokedynamic instruction.
 499      */
 500     public void emitInvokedynamic(DynamicMethodSymbol dynMember, Type mtype) {
 501         int argsize = width(mtype.getParameterTypes());
 502         emitop(invokedynamic);
 503         if (!alive) return;
 504         emit2(poolWriter.putDynamic(dynMember));
 505         emit2(0);
 506         state.pop(argsize);
 507         state.push(mtype.getReturnType());
 508     }
 509 
 510     /** Emit an opcode with no operand field.
 511      */
 512     public void emitop0(int op) {
 513         emitop(op);
 514         if (!alive) return;
 515         switch (op) {
 516         case aaload: {
 517             state.pop(1);// index
 518             Type a = state.stack[state.stacksize-1];
 519             Assert.check(!a.hasTag(BOT)); // null type as is cannot be indexed.
 520             state.pop(1);
 521             state.push(types.erasure(types.elemtype(a))); }
 522             break;
 523         case goto_:
 524             markDead();
 525             break;
 526         case nop:
 527         case ineg:
 528         case lneg:
 529         case fneg:
 530         case dneg:
 531             break;
 532         case aconst_null:
 533             state.push(syms.botType);
 534             break;
 535         case iconst_m1:
 536         case iconst_0:
 537         case iconst_1:
 538         case iconst_2:
 539         case iconst_3:
 540         case iconst_4:
 541         case iconst_5:
 542         case iload_0:
 543         case iload_1:
 544         case iload_2:
 545         case iload_3:
 546             state.push(syms.intType);
 547             break;
 548         case lconst_0:
 549         case lconst_1:
 550         case lload_0:
 551         case lload_1:
 552         case lload_2:
 553         case lload_3:
 554             state.push(syms.longType);
 555             break;
 556         case fconst_0:
 557         case fconst_1:
 558         case fconst_2:
 559         case fload_0:
 560         case fload_1:
 561         case fload_2:
 562         case fload_3:
 563             state.push(syms.floatType);
 564             break;
 565         case dconst_0:
 566         case dconst_1:
 567         case dload_0:
 568         case dload_1:
 569         case dload_2:
 570         case dload_3:
 571             state.push(syms.doubleType);
 572             break;
 573         case aload_0:
 574             state.push(lvar[0].sym.type);
 575             break;
 576         case aload_1:
 577             state.push(lvar[1].sym.type);
 578             break;
 579         case aload_2:
 580             state.push(lvar[2].sym.type);
 581             break;
 582         case aload_3:
 583             state.push(lvar[3].sym.type);
 584             break;
 585         case iaload:
 586         case baload:
 587         case caload:
 588         case saload:
 589             state.pop(2);
 590             state.push(syms.intType);
 591             break;
 592         case laload:
 593             state.pop(2);
 594             state.push(syms.longType);
 595             break;
 596         case faload:
 597             state.pop(2);
 598             state.push(syms.floatType);
 599             break;
 600         case daload:
 601             state.pop(2);
 602             state.push(syms.doubleType);
 603             break;
 604         case istore_0:
 605         case istore_1:
 606         case istore_2:
 607         case istore_3:
 608         case fstore_0:
 609         case fstore_1:
 610         case fstore_2:
 611         case fstore_3:
 612         case astore_0:
 613         case astore_1:
 614         case astore_2:
 615         case astore_3:
 616         case pop:
 617         case lshr:
 618         case lshl:
 619         case lushr:
 620             state.pop(1);
 621             break;
 622         case areturn:
 623         case ireturn:
 624         case freturn:
 625             Assert.check(state.nlocks == 0);
 626             state.pop(1);
 627             markDead();
 628             break;
 629         case athrow:
 630             state.pop(state.stacksize);
 631             markDead();
 632             break;
 633         case lstore_0:
 634         case lstore_1:
 635         case lstore_2:
 636         case lstore_3:
 637         case dstore_0:
 638         case dstore_1:
 639         case dstore_2:
 640         case dstore_3:
 641         case pop2:
 642             state.pop(2);
 643             break;
 644         case lreturn:
 645         case dreturn:
 646             Assert.check(state.nlocks == 0);
 647             state.pop(2);
 648             markDead();
 649             break;
 650         case dup:
 651             state.push(state.stack[state.stacksize-1]);
 652             break;
 653         case return_:
 654             Assert.check(state.nlocks == 0);
 655             markDead();
 656             break;
 657         case arraylength:
 658             state.pop(1);
 659             state.push(syms.intType);
 660             break;
 661         case isub:
 662         case iadd:
 663         case imul:
 664         case idiv:
 665         case imod:
 666         case ishl:
 667         case ishr:
 668         case iushr:
 669         case iand:
 670         case ior:
 671         case ixor:
 672             state.pop(1);
 673             // state.pop(1);
 674             // state.push(syms.intType);
 675             break;
 676         case aastore:
 677             state.pop(3);
 678             break;
 679         case land:
 680         case lor:
 681         case lxor:
 682         case lmod:
 683         case ldiv:
 684         case lmul:
 685         case lsub:
 686         case ladd:
 687             state.pop(2);
 688             break;
 689         case lcmp:
 690             state.pop(4);
 691             state.push(syms.intType);
 692             break;
 693         case l2i:
 694             state.pop(2);
 695             state.push(syms.intType);
 696             break;
 697         case i2l:
 698             state.pop(1);
 699             state.push(syms.longType);
 700             break;
 701         case i2f:
 702             state.pop(1);
 703             state.push(syms.floatType);
 704             break;
 705         case i2d:
 706             state.pop(1);
 707             state.push(syms.doubleType);
 708             break;
 709         case l2f:
 710             state.pop(2);
 711             state.push(syms.floatType);
 712             break;
 713         case l2d:
 714             state.pop(2);
 715             state.push(syms.doubleType);
 716             break;
 717         case f2i:
 718             state.pop(1);
 719             state.push(syms.intType);
 720             break;
 721         case f2l:
 722             state.pop(1);
 723             state.push(syms.longType);
 724             break;
 725         case f2d:
 726             state.pop(1);
 727             state.push(syms.doubleType);
 728             break;
 729         case d2i:
 730             state.pop(2);
 731             state.push(syms.intType);
 732             break;
 733         case d2l:
 734             state.pop(2);
 735             state.push(syms.longType);
 736             break;
 737         case d2f:
 738             state.pop(2);
 739             state.push(syms.floatType);
 740             break;
 741         case tableswitch:
 742         case lookupswitch:
 743             state.pop(1);
 744             // the caller is responsible for patching up the state
 745             break;
 746         case dup_x1: {
 747             Type val1 = state.pop1();
 748             Type val2 = state.pop1();
 749             state.push(val1);
 750             state.push(val2);
 751             state.push(val1);
 752             break;
 753         }
 754         case bastore:
 755             state.pop(3);
 756             break;
 757         case int2byte:
 758         case int2char:
 759         case int2short:
 760             break;
 761         case fmul:
 762         case fadd:
 763         case fsub:
 764         case fdiv:
 765         case fmod:
 766             state.pop(1);
 767             break;
 768         case castore:
 769         case iastore:
 770         case fastore:
 771         case sastore:
 772             state.pop(3);
 773             break;
 774         case lastore:
 775         case dastore:
 776             state.pop(4);
 777             break;
 778         case dup2:
 779             if (state.stack[state.stacksize-1] != null) {
 780                 Type value1 = state.pop1();
 781                 Type value2 = state.pop1();
 782                 state.push(value2);
 783                 state.push(value1);
 784                 state.push(value2);
 785                 state.push(value1);
 786             } else {
 787                 Type value = state.pop2();
 788                 state.push(value);
 789                 state.push(value);
 790             }
 791             break;
 792         case dup2_x1:
 793             if (state.stack[state.stacksize-1] != null) {
 794                 Type value1 = state.pop1();
 795                 Type value2 = state.pop1();
 796                 Type value3 = state.pop1();
 797                 state.push(value2);
 798                 state.push(value1);
 799                 state.push(value3);
 800                 state.push(value2);
 801                 state.push(value1);
 802             } else {
 803                 Type value1 = state.pop2();
 804                 Type value2 = state.pop1();
 805                 state.push(value1);
 806                 state.push(value2);
 807                 state.push(value1);
 808             }
 809             break;
 810         case dup2_x2:
 811             if (state.stack[state.stacksize-1] != null) {
 812                 Type value1 = state.pop1();
 813                 Type value2 = state.pop1();
 814                 if (state.stack[state.stacksize-1] != null) {
 815                     // form 1
 816                     Type value3 = state.pop1();
 817                     Type value4 = state.pop1();
 818                     state.push(value2);
 819                     state.push(value1);
 820                     state.push(value4);
 821                     state.push(value3);
 822                     state.push(value2);
 823                     state.push(value1);
 824                 } else {
 825                     // form 3
 826                     Type value3 = state.pop2();
 827                     state.push(value2);
 828                     state.push(value1);
 829                     state.push(value3);
 830                     state.push(value2);
 831                     state.push(value1);
 832                 }
 833             } else {
 834                 Type value1 = state.pop2();
 835                 if (state.stack[state.stacksize-1] != null) {
 836                     // form 2
 837                     Type value2 = state.pop1();
 838                     Type value3 = state.pop1();
 839                     state.push(value1);
 840                     state.push(value3);
 841                     state.push(value2);
 842                     state.push(value1);
 843                 } else {
 844                     // form 4
 845                     Type value2 = state.pop2();
 846                     state.push(value1);
 847                     state.push(value2);
 848                     state.push(value1);
 849                 }
 850             }
 851             break;
 852         case dup_x2: {
 853             Type value1 = state.pop1();
 854             if (state.stack[state.stacksize-1] != null) {
 855                 // form 1
 856                 Type value2 = state.pop1();
 857                 Type value3 = state.pop1();
 858                 state.push(value1);
 859                 state.push(value3);
 860                 state.push(value2);
 861                 state.push(value1);
 862             } else {
 863                 // form 2
 864                 Type value2 = state.pop2();
 865                 state.push(value1);
 866                 state.push(value2);
 867                 state.push(value1);
 868             }
 869         }
 870             break;
 871         case fcmpl:
 872         case fcmpg:
 873             state.pop(2);
 874             state.push(syms.intType);
 875             break;
 876         case dcmpl:
 877         case dcmpg:
 878             state.pop(4);
 879             state.push(syms.intType);
 880             break;
 881         case swap: {
 882             Type value1 = state.pop1();
 883             Type value2 = state.pop1();
 884             state.push(value1);
 885             state.push(value2);
 886             break;
 887         }
 888         case dadd:
 889         case dsub:
 890         case dmul:
 891         case ddiv:
 892         case dmod:
 893             state.pop(2);
 894             break;
 895         case ret:
 896             markDead();
 897             break;
 898         case wide:
 899             // must be handled by the caller.
 900             return;
 901         case monitorenter:
 902         case monitorexit:
 903             state.pop(1);
 904             break;
 905 
 906         default:
 907             throw new AssertionError(mnem(op));
 908         }
 909         postop();
 910     }
 911 
 912     /** Emit an opcode with a one-byte operand field.
 913      */
 914     public void emitop1(int op, int od) {
 915         emitop1(op, od, null);
 916     }
 917 
 918     public void emitop1(int op, int od, PoolConstant data) {
 919         emitop(op);
 920         if (!alive) return;
 921         emit1(od);
 922         switch (op) {
 923         case bipush:
 924             state.push(syms.intType);
 925             break;
 926         case ldc1:
 927             state.push(types.constantType((LoadableConstant)data));
 928             break;
 929         default:
 930             throw new AssertionError(mnem(op));
 931         }
 932         postop();
 933     }
 934 
 935     /** Emit an opcode with a one-byte operand field;
 936      *  widen if field does not fit in a byte.
 937      */
 938     public void emitop1w(int op, int od) {
 939         if (od > 0xFF) {
 940             emitop(wide);
 941             emitop(op);
 942             emit2(od);
 943         } else {
 944             emitop(op);
 945             emit1(od);
 946         }
 947         if (!alive) return;
 948         switch (op) {
 949         case iload:
 950             state.push(syms.intType);
 951             break;
 952         case lload:
 953             state.push(syms.longType);
 954             break;
 955         case fload:
 956             state.push(syms.floatType);
 957             break;
 958         case dload:
 959             state.push(syms.doubleType);
 960             break;
 961         case aload:
 962             state.push(lvar[od].sym.type);
 963             break;
 964         case lstore:
 965         case dstore:
 966             state.pop(2);
 967             break;
 968         case istore:
 969         case fstore:
 970         case astore:
 971             state.pop(1);
 972             break;
 973         case ret:
 974             markDead();
 975             break;
 976         default:
 977             throw new AssertionError(mnem(op));
 978         }
 979         postop();
 980     }
 981 
 982     /** Emit an opcode with two one-byte operand fields;
 983      *  widen if either field does not fit in a byte.
 984      */
 985     public void emitop1w(int op, int od1, int od2) {
 986         if (od1 > 0xFF || od2 < -128 || od2 > 127) {
 987             emitop(wide);
 988             emitop(op);
 989             emit2(od1);
 990             emit2(od2);
 991         } else {
 992             emitop(op);
 993             emit1(od1);
 994             emit1(od2);
 995         }
 996         if (!alive) return;
 997         switch (op) {
 998         case iinc:
 999             break;
1000         default:
1001             throw new AssertionError(mnem(op));
1002         }
1003     }
1004 
1005     /** Emit an opcode with a two-byte operand field.
1006      */
1007     public <P extends PoolConstant> void emitop2(int op, P constant, ToIntBiFunction<PoolWriter, P> poolFunc) {
1008         int od = poolFunc.applyAsInt(poolWriter, constant);
1009         emitop2(op, od, constant);
1010     }
1011 
1012     public void emitop2(int op, int od) {
1013         emitop2(op, od, null);
1014     }
1015 
1016     public void emitop2(int op, int od, PoolConstant data) {
1017         emitop(op);
1018         if (!alive) return;
1019         emit2(od);
1020         switch (op) {
1021         case getstatic:
1022             state.push(((Symbol)data).erasure(types));
1023             break;
1024         case putstatic:
1025             state.pop(((Symbol)data).erasure(types));
1026             break;
1027         case new_: {
1028             Type t = (Type)data;
1029             state.push(uninitializedObject(t.tsym.erasure(types), cp-3));
1030             break;
1031         }
1032         case sipush:
1033             state.push(syms.intType);
1034             break;
1035         case if_acmp_null:
1036         case if_acmp_nonnull:
1037         case ifeq:
1038         case ifne:
1039         case iflt:
1040         case ifge:
1041         case ifgt:
1042         case ifle:
1043             state.pop(1);
1044             break;
1045         case if_icmpeq:
1046         case if_icmpne:
1047         case if_icmplt:
1048         case if_icmpge:
1049         case if_icmpgt:
1050         case if_icmple:
1051         case if_acmpeq:
1052         case if_acmpne:
1053             state.pop(2);
1054             break;
1055         case goto_:
1056             markDead();
1057             break;
1058         case putfield:
1059             state.pop(((Symbol)data).erasure(types));
1060             state.pop(1); // object ref
1061             break;
1062         case getfield:
1063             state.pop(1); // object ref
1064             state.push(((Symbol)data).erasure(types));
1065             break;
1066         case checkcast: {
1067             state.pop(1); // object ref
1068             Type t = types.erasure((Type)data);
1069             state.push(t);
1070             break; }
1071         case ldc2:
1072         case ldc2w:
1073             state.push(types.constantType((LoadableConstant)data));
1074             break;
1075         case instanceof_:
1076             state.pop(1);
1077             state.push(syms.intType);
1078             break;
1079         case jsr:
1080             break;
1081         default:
1082             throw new AssertionError(mnem(op));
1083         }
1084         // postop();
1085     }
1086 
1087     /** Emit an opcode with a four-byte operand field.
1088      */
1089     public void emitop4(int op, int od) {
1090         emitop(op);
1091         if (!alive) return;
1092         emit4(od);
1093         switch (op) {
1094         case goto_w:
1095             markDead();
1096             break;
1097         case jsr_w:
1098             break;
1099         default:
1100             throw new AssertionError(mnem(op));
1101         }
1102         // postop();
1103     }
1104 
1105     /** Align code pointer to next `incr' boundary.
1106      */
1107     public void align(int incr) {
1108         if (alive)
1109             while (cp % incr != 0) emitop0(nop);
1110     }
1111 
1112     /** Place a byte into code at address pc.
1113      *  Pre: {@literal pc + 1 <= cp }.
1114      */
1115     private void put1(int pc, int op) {
1116         code[pc] = (byte)op;
1117     }
1118 
1119     /** Place two bytes into code at address pc.
1120      *  Pre: {@literal pc + 2 <= cp }.
1121      */
1122     private void put2(int pc, int od) {
1123         // pre: pc + 2 <= cp
1124         put1(pc, od >> 8);
1125         put1(pc+1, od);
1126     }
1127 
1128     /** Place four  bytes into code at address pc.
1129      *  Pre: {@literal pc + 4 <= cp }.
1130      */
1131     public void put4(int pc, int od) {
1132         // pre: pc + 4 <= cp
1133         put1(pc  , od >> 24);
1134         put1(pc+1, od >> 16);
1135         put1(pc+2, od >> 8);
1136         put1(pc+3, od);
1137     }
1138 
1139     /** Return code byte at position pc as an unsigned int.
1140      */
1141     private int get1(int pc) {
1142         return code[pc] & 0xFF;
1143     }
1144 
1145     /** Return two code bytes at position pc as an unsigned int.
1146      */
1147     private int get2(int pc) {
1148         return (get1(pc) << 8) | get1(pc+1);
1149     }
1150 
1151     /** Return four code bytes at position pc as an int.
1152      */
1153     public int get4(int pc) {
1154         // pre: pc + 4 <= cp
1155         return
1156             (get1(pc) << 24) |
1157             (get1(pc+1) << 16) |
1158             (get1(pc+2) << 8) |
1159             (get1(pc+3));
1160     }
1161 
1162     /** Is code generation currently enabled?
1163      */
1164     public boolean isAlive() {
1165         return alive || pendingJumps != null;
1166     }
1167 
1168     /** Switch code generation on/off.
1169      */
1170     public void markDead() {
1171         alive = false;
1172     }
1173 
1174     /** Declare an entry point; return current code pointer
1175      */
1176     public int entryPoint() {
1177         int pc = curCP();
1178         alive = true;
1179         pendingStackMap = needStackMap;
1180         return pc;
1181     }
1182 
1183     /** Declare an entry point with initial state;
1184      *  return current code pointer
1185      */
1186     public int entryPoint(State state) {
1187         int pc = curCP();
1188         alive = true;
1189         State newState = state.dup();
1190         setDefined(newState.defined);
1191         this.state = newState;
1192         Assert.check(state.stacksize <= max_stack);
1193         if (debugCode) System.err.println("entry point " + state);
1194         pendingStackMap = needStackMap;
1195         return pc;
1196     }
1197 
1198     /** Declare an entry point with initial state plus a pushed value;
1199      *  return current code pointer
1200      */
1201     public int entryPoint(State state, Type pushed) {
1202         int pc = curCP();
1203         alive = true;
1204         State newState = state.dup();
1205         setDefined(newState.defined);
1206         this.state = newState;
1207         Assert.check(state.stacksize <= max_stack);
1208         this.state.push(pushed);
1209         if (debugCode) System.err.println("entry point " + state);
1210         pendingStackMap = needStackMap;
1211         return pc;
1212     }
1213 
1214     public int setLetExprStackPos(int pos) {
1215         int res = letExprStackPos;
1216         letExprStackPos = pos;
1217         return res;
1218     }
1219 
1220     public boolean isStatementStart() {
1221         return !alive || state.stacksize == letExprStackPos;
1222     }
1223 
1224 /* ************************************************************************
1225  * Stack map generation
1226  *************************************************************************/
1227 
1228     /** An entry in the stack map. */
1229     static class StackMapFrame {
1230         int pc;
1231         Type[] locals;
1232         Type[] stack;
1233     }
1234 
1235     /** A buffer of cldc stack map entries. */
1236     StackMapFrame[] stackMapBuffer = null;
1237 
1238     /** A buffer of compressed StackMapTable entries. */
1239     StackMapTableFrame[] stackMapTableBuffer = null;
1240     int stackMapBufferSize = 0;
1241 
1242     /** The last PC at which we generated a stack map. */
1243     int lastStackMapPC = -1;
1244 
1245     /** The last stack map frame in StackMapTable. */
1246     StackMapFrame lastFrame = null;
1247 
1248     /** The stack map frame before the last one. */
1249     StackMapFrame frameBeforeLast = null;
1250 
1251     /** Emit a stack map entry.  */
1252     public void emitStackMap() {
1253         int pc = curCP();
1254         if (!needStackMap) return;
1255 
1256 
1257 
1258         switch (stackMap) {
1259             case CLDC:
1260                 emitCLDCStackMap(pc, getLocalsSize());
1261                 break;
1262             case JSR202:
1263                 emitStackMapFrame(pc, getLocalsSize());
1264                 break;
1265             default:
1266                 throw new AssertionError("Should have chosen a stackmap format");
1267         }
1268         // DEBUG code follows
1269         if (debugCode) state.dump(pc);
1270     }
1271 
1272     private int getLocalsSize() {
1273         int nextLocal = 0;
1274         for (int i=max_locals-1; i>=0; i--) {
1275             if (state.defined.isMember(i) && lvar[i] != null) {
1276                 nextLocal = i + width(lvar[i].sym.erasure(types));
1277                 break;
1278             }
1279         }
1280         return nextLocal;
1281     }
1282 
1283     /** Emit a CLDC stack map frame. */
1284     void emitCLDCStackMap(int pc, int localsSize) {
1285         if (lastStackMapPC == pc) {
1286             // drop existing stackmap at this offset
1287             stackMapBuffer[--stackMapBufferSize] = null;
1288         }
1289         lastStackMapPC = pc;
1290 
1291         if (stackMapBuffer == null) {
1292             stackMapBuffer = new StackMapFrame[20];
1293         } else {
1294             stackMapBuffer = ArrayUtils.ensureCapacity(stackMapBuffer, stackMapBufferSize);
1295         }
1296         StackMapFrame frame =
1297             stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
1298         frame.pc = pc;
1299 
1300         frame.locals = new Type[localsSize];
1301         for (int i=0; i<localsSize; i++) {
1302             if (state.defined.isMember(i) && lvar[i] != null) {
1303                 Type vtype = lvar[i].sym.type;
1304                 if (!(vtype instanceof UninitializedType))
1305                     vtype = types.erasure(vtype);
1306                 frame.locals[i] = vtype;
1307             }
1308         }
1309         frame.stack = new Type[state.stacksize];
1310         for (int i=0; i<state.stacksize; i++)
1311             frame.stack[i] = state.stack[i];
1312     }
1313 
1314     void emitStackMapFrame(int pc, int localsSize) {
1315         if (lastFrame == null) {
1316             // first frame
1317             lastFrame = getInitialFrame();
1318         } else if (lastFrame.pc == pc) {
1319             // drop existing stackmap at this offset
1320             stackMapTableBuffer[--stackMapBufferSize] = null;
1321             lastFrame = frameBeforeLast;
1322             frameBeforeLast = null;
1323         }
1324 
1325         StackMapFrame frame = new StackMapFrame();
1326         frame.pc = pc;
1327 
1328         int localCount = 0;
1329         Type[] locals = new Type[localsSize];
1330         for (int i=0; i<localsSize; i++, localCount++) {
1331             if (state.defined.isMember(i) && lvar[i] != null) {
1332                 Type vtype = lvar[i].sym.type;
1333                 if (!(vtype instanceof UninitializedType))
1334                     vtype = types.erasure(vtype);
1335                 locals[i] = vtype;
1336                 if (width(vtype) > 1) i++;
1337             }
1338         }
1339         frame.locals = new Type[localCount];
1340         for (int i=0, j=0; i<localsSize; i++, j++) {
1341             Assert.check(j < localCount);
1342             frame.locals[j] = locals[i];
1343             if (width(locals[i]) > 1) i++;
1344         }
1345 
1346         int stackCount = 0;
1347         for (int i=0; i<state.stacksize; i++) {
1348             if (state.stack[i] != null) {
1349                 stackCount++;
1350             }
1351         }
1352         frame.stack = new Type[stackCount];
1353         stackCount = 0;
1354         for (int i=0; i<state.stacksize; i++) {
1355             if (state.stack[i] != null) {
1356                 frame.stack[stackCount++] = types.erasure(state.stack[i]);
1357             }
1358         }
1359 
1360         if (stackMapTableBuffer == null) {
1361             stackMapTableBuffer = new StackMapTableFrame[20];
1362         } else {
1363             stackMapTableBuffer = ArrayUtils.ensureCapacity(
1364                                     stackMapTableBuffer,
1365                                     stackMapBufferSize);
1366         }
1367         stackMapTableBuffer[stackMapBufferSize++] =
1368                 StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
1369 
1370         frameBeforeLast = lastFrame;
1371         lastFrame = frame;
1372     }
1373 
1374     StackMapFrame getInitialFrame() {
1375         StackMapFrame frame = new StackMapFrame();
1376         List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
1377         int len = arg_types.length();
1378         int count = 0;
1379         if (!meth.isStatic()) {
1380             Type thisType = meth.owner.type;
1381             frame.locals = new Type[len+1];
1382             if (meth.isConstructor() && thisType != syms.objectType) {
1383                 frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
1384             } else {
1385                 frame.locals[count++] = types.erasure(thisType);
1386             }
1387         } else {
1388             frame.locals = new Type[len];
1389         }
1390         for (Type arg_type : arg_types) {
1391             frame.locals[count++] = types.erasure(arg_type);
1392         }
1393         frame.pc = -1;
1394         frame.stack = null;
1395         return frame;
1396     }
1397 
1398 
1399 /* ************************************************************************
1400  * Operations having to do with jumps
1401  *************************************************************************/
1402 
1403     /** A chain represents a list of unresolved jumps. Jump locations
1404      *  are sorted in decreasing order.
1405      */
1406     public static class Chain {
1407 
1408         /** The position of the jump instruction.
1409          */
1410         public final int pc;
1411 
1412         /** The machine state after the jump instruction.
1413          *  Invariant: all elements of a chain list have the same stacksize
1414          *  and compatible stack and register contents.
1415          */
1416         Code.State state;
1417 
1418         /** The next jump in the list.
1419          */
1420         public final Chain next;
1421 
1422         /** Construct a chain from its jump position, stacksize, previous
1423          *  chain, and machine state.
1424          */
1425         public Chain(int pc, Chain next, Code.State state) {
1426             this.pc = pc;
1427             this.next = next;
1428             this.state = state;
1429         }
1430     }
1431 
1432     /** Negate a branch opcode.
1433      */
1434     public static int negate(int opcode) {
1435         if (opcode == if_acmp_null) return if_acmp_nonnull;
1436         else if (opcode == if_acmp_nonnull) return if_acmp_null;
1437         else return ((opcode + 1) ^ 1) - 1;
1438     }
1439 
1440     /** Emit a jump instruction.
1441      *  Return code pointer of instruction to be patched.
1442      */
1443     public int emitJump(int opcode) {
1444         if (fatcode) {
1445             if (opcode == goto_ || opcode == jsr) {
1446                 emitop4(opcode + goto_w - goto_, 0);
1447             } else {
1448                 emitop2(negate(opcode), 8);
1449                 emitop4(goto_w, 0);
1450                 alive = true;
1451                 pendingStackMap = needStackMap;
1452             }
1453             return cp - 5;
1454         } else {
1455             emitop2(opcode, 0);
1456             return cp - 3;
1457         }
1458     }
1459 
1460     /** Emit a branch with given opcode; return its chain.
1461      *  branch differs from jump in that jsr is treated as no-op.
1462      */
1463     public Chain branch(int opcode) {
1464         Chain result = null;
1465         if (opcode == goto_) {
1466             result = pendingJumps;
1467             pendingJumps = null;
1468         }
1469         if (opcode != dontgoto && isAlive()) {
1470             result = new Chain(emitJump(opcode),
1471                                result,
1472                                state.dup());
1473             fixedPc = fatcode;
1474             if (opcode == goto_) alive = false;
1475         }
1476         return result;
1477     }
1478 
1479     /** Resolve chain to point to given target.
1480      */
1481     public void resolve(Chain chain, int target) {
1482         boolean changed = false;
1483         State newState = state;
1484         for (; chain != null; chain = chain.next) {
1485             Assert.check(state != chain.state
1486                     && (target > chain.pc || isStatementStart()));
1487             if (target >= cp) {
1488                 target = cp;
1489             } else if (get1(target) == goto_) {
1490                 if (fatcode) target = target + get4(target + 1);
1491                 else target = target + get2(target + 1);
1492             }
1493             if (get1(chain.pc) == goto_ &&
1494                 chain.pc + 3 == target && target == cp && !fixedPc) {
1495                 // If goto the next instruction, the jump is not needed:
1496                 // compact the code.
1497                 if (varDebugInfo) {
1498                     adjustAliveRanges(cp, -3);
1499                 }
1500                 cp = cp - 3;
1501                 target = target - 3;
1502                 if (chain.next == null) {
1503                     // This is the only jump to the target. Exit the loop
1504                     // without setting new state. The code is reachable
1505                     // from the instruction before goto_.
1506                     alive = true;
1507                     break;
1508                 }
1509             } else {
1510                 if (fatcode)
1511                     put4(chain.pc + 1, target - chain.pc);
1512                 else if (target - chain.pc < Short.MIN_VALUE ||
1513                          target - chain.pc > Short.MAX_VALUE)
1514                     fatcode = true;
1515                 else
1516                     put2(chain.pc + 1, target - chain.pc);
1517                 Assert.check(!alive ||
1518                     chain.state.stacksize == newState.stacksize &&
1519                     chain.state.nlocks == newState.nlocks);
1520             }
1521             fixedPc = true;
1522             if (cp == target) {
1523                 changed = true;
1524                 if (debugCode)
1525                     System.err.println("resolving chain state=" + chain.state);
1526                 if (alive) {
1527                     newState = chain.state.join(newState);
1528                 } else {
1529                     newState = chain.state;
1530                     alive = true;
1531                 }
1532             }
1533         }
1534         Assert.check(!changed || state != newState);
1535         if (state != newState) {
1536             setDefined(newState.defined);
1537             state = newState;
1538             pendingStackMap = needStackMap;
1539         }
1540     }
1541 
1542     /** Resolve chain to point to current code pointer.
1543      */
1544     public void resolve(Chain chain) {
1545         Assert.check(
1546             !alive ||
1547             chain==null ||
1548             state.stacksize == chain.state.stacksize &&
1549             state.nlocks == chain.state.nlocks);
1550         pendingJumps = mergeChains(chain, pendingJumps);
1551     }
1552 
1553     /** Resolve any pending jumps.
1554      */
1555     public void resolvePending() {
1556         Chain x = pendingJumps;
1557         pendingJumps = null;
1558         resolve(x, cp);
1559     }
1560 
1561     /** Merge the jumps in of two chains into one.
1562      */
1563     public static Chain mergeChains(Chain chain1, Chain chain2) {
1564         // recursive merge sort
1565         if (chain2 == null) return chain1;
1566         if (chain1 == null) return chain2;
1567         Assert.check(
1568             chain1.state.stacksize == chain2.state.stacksize &&
1569             chain1.state.nlocks == chain2.state.nlocks);
1570         if (chain1.pc < chain2.pc)
1571             return new Chain(
1572                 chain2.pc,
1573                 mergeChains(chain1, chain2.next),
1574                 chain2.state);
1575         return new Chain(
1576                 chain1.pc,
1577                 mergeChains(chain1.next, chain2),
1578                 chain1.state);
1579     }
1580 
1581 
1582 /* **************************************************************************
1583  * Catch clauses
1584  ****************************************************************************/
1585 
1586     /** Add a catch clause to code.
1587      */
1588     public void addCatch(char startPc, char endPc,
1589                          char handlerPc, char catchType) {
1590             catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
1591         }
1592 
1593 
1594     public void compressCatchTable() {
1595         ListBuffer<char[]> compressedCatchInfo = new ListBuffer<>();
1596         List<Integer> handlerPcs = List.nil();
1597         for (char[] catchEntry : catchInfo) {
1598             handlerPcs = handlerPcs.prepend((int)catchEntry[2]);
1599         }
1600         for (char[] catchEntry : catchInfo) {
1601             int startpc = catchEntry[0];
1602             int endpc = catchEntry[1];
1603             if (startpc == endpc ||
1604                     (startpc == (endpc - 1) &&
1605                     handlerPcs.contains(startpc))) {
1606                 continue;
1607             } else {
1608                 compressedCatchInfo.append(catchEntry);
1609             }
1610         }
1611         catchInfo = compressedCatchInfo;
1612     }
1613 
1614 
1615 /* **************************************************************************
1616  * Line numbers
1617  ****************************************************************************/
1618 
1619     /** Add a line number entry.
1620      */
1621     public void addLineNumber(char startPc, char lineNumber) {
1622         if (lineDebugInfo) {
1623             if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
1624                 lineInfo = lineInfo.tail;
1625             if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
1626                 lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
1627         }
1628     }
1629 
1630     /** Mark beginning of statement.
1631      */
1632     public void statBegin(int pos) {
1633         if (pos != Position.NOPOS) {
1634             pendingStatPos = pos;
1635         }
1636     }
1637 
1638     /** Force stat begin eagerly
1639      */
1640     public void markStatBegin() {
1641         if (alive && lineDebugInfo) {
1642             int line = lineMap.getLineNumber(pendingStatPos);
1643             char cp1 = (char)cp;
1644             char line1 = (char)line;
1645             if (cp1 == cp && line1 == line)
1646                 addLineNumber(cp1, line1);
1647         }
1648         pendingStatPos = Position.NOPOS;
1649     }
1650 
1651 
1652 /* **************************************************************************
1653  * Simulated VM machine state
1654  ****************************************************************************/
1655 
1656     class State implements Cloneable {
1657         /** The set of registers containing values. */
1658         Bits defined;
1659 
1660         /** The (types of the) contents of the machine stack. */
1661         Type[] stack;
1662 
1663         /** The first stack position currently unused. */
1664         int stacksize;
1665 
1666         /** The numbers of registers containing locked monitors. */
1667         int[] locks;
1668         int nlocks;
1669 
1670         State() {
1671             defined = new Bits();
1672             stack = new Type[16];
1673         }
1674 
1675         State dup() {
1676             try {
1677                 State state = (State)super.clone();
1678                 state.defined = new Bits(defined);
1679                 state.stack = stack.clone();
1680                 if (locks != null) state.locks = locks.clone();
1681                 if (debugCode) {
1682                     System.err.println("duping state " + this);
1683                     dump();
1684                 }
1685                 return state;
1686             } catch (CloneNotSupportedException ex) {
1687                 throw new AssertionError(ex);
1688             }
1689         }
1690 
1691         void lock(int register) {
1692             if (locks == null) {
1693                 locks = new int[20];
1694             } else {
1695                 locks = ArrayUtils.ensureCapacity(locks, nlocks);
1696             }
1697             locks[nlocks] = register;
1698             nlocks++;
1699         }
1700 
1701         void unlock(int register) {
1702             nlocks--;
1703             Assert.check(locks[nlocks] == register);
1704             locks[nlocks] = -1;
1705         }
1706 
1707         void push(Type t) {
1708             if (debugCode) System.err.println("   pushing " + t);
1709             switch (t.getTag()) {
1710             case VOID:
1711                 return;
1712             case BYTE:
1713             case CHAR:
1714             case SHORT:
1715             case BOOLEAN:
1716                 t = syms.intType;
1717                 break;
1718             default:
1719                 break;
1720             }
1721             stack = ArrayUtils.ensureCapacity(stack, stacksize+2);
1722             stack[stacksize++] = t;
1723             switch (width(t)) {
1724             case 1:
1725                 break;
1726             case 2:
1727                 stack[stacksize++] = null;
1728                 break;
1729             default:
1730                 throw new AssertionError(t);
1731             }
1732             if (stacksize > max_stack)
1733                 max_stack = stacksize;
1734         }
1735 
1736         Type pop1() {
1737             if (debugCode) System.err.println("   popping " + 1);
1738             stacksize--;
1739             Type result = stack[stacksize];
1740             stack[stacksize] = null;
1741             Assert.check(result != null && width(result) == 1);
1742             return result;
1743         }
1744 
1745         Type peek() {
1746             return stack[stacksize-1];
1747         }
1748 
1749         Type pop2() {
1750             if (debugCode) System.err.println("   popping " + 2);
1751             stacksize -= 2;
1752             Type result = stack[stacksize];
1753             stack[stacksize] = null;
1754             Assert.check(stack[stacksize+1] == null
1755                     && result != null && width(result) == 2);
1756             return result;
1757         }
1758 
1759         void pop(int n) {
1760             if (debugCode) System.err.println("   popping " + n);
1761             while (n > 0) {
1762                 stack[--stacksize] = null;
1763                 n--;
1764             }
1765         }
1766 
1767         void pop(Type t) {
1768             pop(width(t));
1769         }
1770 
1771         /** Force the top of the stack to be treated as this supertype
1772          *  of its current type. */
1773         void forceStackTop(Type t) {
1774             if (!alive) return;
1775             switch (t.getTag()) {
1776             case CLASS:
1777             case ARRAY:
1778                 int width = width(t);
1779                 Type old = stack[stacksize-width];
1780                 Assert.check(types.isSubtype(types.erasure(old),
1781                                        types.erasure(t)));
1782                 stack[stacksize-width] = t;
1783                 break;
1784             default:
1785             }
1786         }
1787 
1788         void markInitialized(UninitializedType old) {
1789             Type newtype = old.initializedType();
1790             for (int i=0; i<stacksize; i++) {
1791                 if (stack[i] == old) stack[i] = newtype;
1792             }
1793             for (int i=0; i<lvar.length; i++) {
1794                 LocalVar lv = lvar[i];
1795                 if (lv != null && lv.sym.type == old) {
1796                     VarSymbol sym = lv.sym;
1797                     sym = sym.clone(sym.owner);
1798                     sym.type = newtype;
1799                     LocalVar newlv = lvar[i] = new LocalVar(sym);
1800                     newlv.aliveRanges = lv.aliveRanges;
1801                 }
1802             }
1803         }
1804 
1805         State join(State other) {
1806             defined.andSet(other.defined);
1807             Assert.check(stacksize == other.stacksize
1808                     && nlocks == other.nlocks);
1809             for (int i=0; i<stacksize; ) {
1810                 Type t = stack[i];
1811                 Type tother = other.stack[i];
1812                 Type result = commonSuperClass(t, tother);
1813                 int w = width(result);
1814                 stack[i] = result;
1815                 if (w == 2) Assert.checkNull(stack[i+1]);
1816                 i += w;
1817             }
1818             return this;
1819         }
1820 
1821         private Type commonSuperClass(Type t1, Type t2) {
1822             if (t1 == t2) {
1823                 return t1;
1824             } else if (types.isSubtype(t1, t2)) {
1825                 return t2;
1826             } else if (types.isSubtype(t2, t1)) {
1827                 return t1;
1828             } else {
1829                 /* the most semantically correct approach here would be to invoke Types::lub
1830                  * and then erase the result.
1831                  * But this approach can be too slow for some complex cases, see JDK-8369654.
1832                  * This is why the method below leverages the fact that the result
1833                  * will be erased to produce a correct supertype using a simpler approach compared
1834                  * to a full blown lub.
1835                  */
1836                 Type es = erasedSuper(t1, t2);
1837                 if (es == null || es.hasTag(BOT)) {
1838                     throw Assert.error("Cannot find a common super class of: " +
1839                                        t1 + " and " + t2);
1840                 }
1841                 return es;
1842             }
1843         }
1844 
1845         private Type erasedSuper(Type t1, Type t2) {
1846             if (t1.hasTag(ARRAY) && t2.hasTag(ARRAY)) {
1847                 Type elem1 = types.elemtype(t1);
1848                 Type elem2 = types.elemtype(t2);
1849                 if (elem1.isPrimitive() || elem2.isPrimitive()) {
1850                     return (elem1.tsym == elem2.tsym) ? t1 : syms.serializableType;
1851                 } else { // both are arrays of references
1852                     return new ArrayType(erasedSuper(elem1, elem2), syms.arrayClass);
1853                 }
1854             } else {
1855                 t1 = types.skipTypeVars(t1, false);
1856                 t2 = types.skipTypeVars(t2, false);
1857                 List<Type> intersection = types.intersect(
1858                         t1.hasTag(ARRAY) ?
1859                                 List.of(syms.serializableType, syms.cloneableType, syms.objectType) :
1860                                 types.erasedSupertypes(t1),
1861                         t2.hasTag(ARRAY) ?
1862                                 List.of(syms.serializableType, syms.cloneableType, syms.objectType) :
1863                                 types.erasedSupertypes(t2));
1864                 return intersection.head;
1865             }
1866         }
1867 
1868         void dump() {
1869             dump(-1);
1870         }
1871 
1872         void dump(int pc) {
1873             System.err.print("stackMap for " + meth.owner + "." + meth);
1874             if (pc == -1)
1875                 System.out.println();
1876             else
1877                 System.out.println(" at " + pc);
1878             System.err.println(" stack (from bottom):");
1879             for (int i=0; i<stacksize; i++)
1880                 System.err.println("  " + i + ": " + stack[i]);
1881 
1882             int lastLocal = 0;
1883             for (int i=max_locals-1; i>=0; i--) {
1884                 if (defined.isMember(i)) {
1885                     lastLocal = i;
1886                     break;
1887                 }
1888             }
1889             if (lastLocal >= 0)
1890                 System.err.println(" locals:");
1891             for (int i=0; i<=lastLocal; i++) {
1892                 System.err.print("  " + i + ": ");
1893                 if (defined.isMember(i)) {
1894                     LocalVar var = lvar[i];
1895                     if (var == null) {
1896                         System.err.println("(none)");
1897                     } else if (var.sym == null)
1898                         System.err.println("UNKNOWN!");
1899                     else
1900                         System.err.println("" + var.sym + " of type " +
1901                                            var.sym.erasure(types));
1902                 } else {
1903                     System.err.println("undefined");
1904                 }
1905             }
1906             if (nlocks != 0) {
1907                 System.err.print(" locks:");
1908                 for (int i=0; i<nlocks; i++) {
1909                     System.err.print(" " + locks[i]);
1910                 }
1911                 System.err.println();
1912             }
1913         }
1914     }
1915 
1916     static final Type jsrReturnValue = new JCPrimitiveType(INT, null);
1917 
1918 
1919 /* **************************************************************************
1920  * Local variables
1921  ****************************************************************************/
1922 
1923     /** A live range of a local variable. */
1924     static class LocalVar {
1925         final VarSymbol sym;
1926         final char reg;
1927 
1928         class Range {
1929             char start_pc = Character.MAX_VALUE;
1930             char length = Character.MAX_VALUE;
1931 
1932             Range() {}
1933 
1934             Range(char start) {
1935                 this.start_pc = start;
1936             }
1937 
1938             Range(char start, char length) {
1939                 this.start_pc = start;
1940                 this.length = length;
1941             }
1942 
1943             boolean closed() {
1944                 return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE;
1945             }
1946 
1947             @Override
1948             public String toString() {
1949                 int currentStartPC = start_pc;
1950                 int currentLength = length;
1951                 return "startpc = " + currentStartPC + " length " + currentLength;
1952             }
1953         }
1954 
1955         java.util.List<Range> aliveRanges = new java.util.ArrayList<>();
1956 
1957         LocalVar(VarSymbol v) {
1958             this.sym = v;
1959             this.reg = (char)v.adr;
1960         }
1961         public LocalVar dup() {
1962             return new LocalVar(sym);
1963         }
1964 
1965         Range firstRange() {
1966             return aliveRanges.isEmpty() ? null : aliveRanges.get(0);
1967         }
1968 
1969         Range lastRange() {
1970             return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
1971         }
1972 
1973         void removeLastRange() {
1974             Range lastRange = lastRange();
1975             if (lastRange != null) {
1976                 aliveRanges.remove(lastRange);
1977             }
1978         }
1979 
1980         @Override
1981         public String toString() {
1982             if (aliveRanges == null) {
1983                 return "empty local var";
1984             }
1985             StringBuilder sb = new StringBuilder().append(sym)
1986                     .append(" in register ").append((int)reg).append(" \n");
1987             for (Range r : aliveRanges) {
1988                 sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc)))
1989                     .append(" length=").append(Integer.toString(((int)r.length)))
1990                     .append("\n");
1991             }
1992             return sb.toString();
1993         }
1994 
1995         public void openRange(char start) {
1996             if (!hasOpenRange()) {
1997                 aliveRanges.add(new Range(start));
1998             }
1999         }
2000 
2001         public void closeRange(char length) {
2002             if (isLastRangeInitialized() && length > 0) {
2003                 Range range = lastRange();
2004                 if (range != null) {
2005                     if (range.length == Character.MAX_VALUE) {
2006                         range.length = length;
2007                     }
2008                 }
2009             } else {
2010                 removeLastRange();
2011             }
2012         }
2013 
2014         public boolean hasOpenRange() {
2015             if (aliveRanges.isEmpty()) {
2016                 return false;
2017             }
2018             return lastRange().length == Character.MAX_VALUE;
2019         }
2020 
2021         public boolean isLastRangeInitialized() {
2022             if (aliveRanges.isEmpty()) {
2023                 return false;
2024             }
2025             return lastRange().start_pc != Character.MAX_VALUE;
2026         }
2027 
2028         public Range getWidestRange() {
2029             if (aliveRanges.isEmpty()) {
2030                 return new Range();
2031             } else {
2032                 Range firstRange = firstRange();
2033                 Range lastRange = lastRange();
2034                 char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc));
2035                 return new Range(firstRange.start_pc, length);
2036             }
2037          }
2038 
2039     }
2040 
2041     /** Local variables, indexed by register. */
2042     LocalVar[] lvar;
2043 
2044     /** Add a new local variable. */
2045     private void addLocalVar(VarSymbol v) {
2046         int adr = v.adr;
2047         lvar = ArrayUtils.ensureCapacity(lvar, adr+1);
2048         Assert.checkNull(lvar[adr]);
2049         if (pendingJumps != null) {
2050             resolvePending();
2051         }
2052         lvar[adr] = new LocalVar(v);
2053         state.defined.excl(adr);
2054     }
2055 
2056     void adjustAliveRanges(int oldCP, int delta) {
2057         for (LocalVar localVar: lvar) {
2058             if (localVar != null) {
2059                 for (LocalVar.Range range: localVar.aliveRanges) {
2060                     if (range.closed() && range.start_pc + range.length >= oldCP) {
2061                         range.length += (char)delta;
2062                     }
2063                 }
2064             }
2065         }
2066     }
2067 
2068     /**
2069      * Calculates the size of the LocalVariableTable.
2070      */
2071     public int getLVTSize() {
2072         int result = varBufferSize;
2073         for (int i = 0; i < varBufferSize; i++) {
2074             LocalVar var = varBuffer[i];
2075             result += var.aliveRanges.size() - 1;
2076         }
2077         return result;
2078     }
2079 
2080     /** Set the current variable defined state. */
2081     public void setDefined(Bits newDefined) {
2082         if (alive && newDefined != state.defined) {
2083             Bits diff = new Bits(state.defined).xorSet(newDefined);
2084             for (int adr = diff.nextBit(0);
2085                  adr >= 0;
2086                  adr = diff.nextBit(adr+1)) {
2087                 if (adr >= nextreg)
2088                     state.defined.excl(adr);
2089                 else if (state.defined.isMember(adr))
2090                     setUndefined(adr);
2091                 else
2092                     setDefined(adr);
2093             }
2094         }
2095     }
2096 
2097     /** Mark a register as being (possibly) defined. */
2098     public void setDefined(int adr) {
2099         LocalVar v = lvar[adr];
2100         if (v == null) {
2101             state.defined.excl(adr);
2102         } else {
2103             state.defined.incl(adr);
2104             if (cp < Character.MAX_VALUE) {
2105                 v.openRange((char)cp);
2106             }
2107         }
2108     }
2109 
2110     /** Mark a register as being undefined. */
2111     public void setUndefined(int adr) {
2112         state.defined.excl(adr);
2113         if (adr < lvar.length &&
2114             lvar[adr] != null &&
2115             lvar[adr].isLastRangeInitialized()) {
2116             LocalVar v = lvar[adr];
2117             char length = (char)(curCP() - v.lastRange().start_pc);
2118             if (length < Character.MAX_VALUE) {
2119                 lvar[adr] = v.dup();
2120                 v.closeRange(length);
2121                 putVar(v);
2122                 fillLocalVarPosition(v);
2123             } else {
2124                 v.removeLastRange();
2125             }
2126         }
2127     }
2128 
2129     /** End the scope of a variable. */
2130     private void endScope(int adr) {
2131         LocalVar v = lvar[adr];
2132         if (v != null) {
2133             if (v.isLastRangeInitialized()) {
2134                 char length = (char)(curCP() - v.lastRange().start_pc);
2135                 if (length < Character.MAX_VALUE) {
2136                     v.closeRange(length);
2137                     putVar(v);
2138                     fillLocalVarPosition(v);
2139                 }
2140             }
2141             /** the call to curCP() can implicitly adjust the current cp, if so
2142              * the alive range of local variables may be modified. Thus we need
2143              * all of them. For this reason assigning null to the given address
2144              * should be the last action to do.
2145              */
2146             lvar[adr] = null;
2147         }
2148         state.defined.excl(adr);
2149     }
2150 
2151     private void fillLocalVarPosition(LocalVar lv) {
2152         if (lv == null || lv.sym == null || lv.sym.isExceptionParameter()|| !lv.sym.hasTypeAnnotations())
2153             return;
2154         LocalVar.Range[] validRanges = lv.aliveRanges.stream().filter(r -> r.closed() && r.length > 0).toArray(s -> new LocalVar.Range[s]);
2155         if (validRanges.length == 0)
2156             return ;
2157         int[] lvarOffset = Arrays.stream(validRanges).mapToInt(r -> r.start_pc).toArray();
2158         int[] lvarLength = Arrays.stream(validRanges).mapToInt(r -> r.length).toArray();
2159         int[] lvarIndex = Arrays.stream(validRanges).mapToInt(r -> lv.reg).toArray();
2160         for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
2161             TypeAnnotationPosition p = ta.position;
2162             p.lvarOffset = appendArray(p.lvarOffset, lvarOffset);
2163             p.lvarLength = appendArray(p.lvarLength, lvarLength);
2164             p.lvarIndex = appendArray(p.lvarIndex, lvarIndex);
2165             p.isValidOffset = true;
2166         }
2167     }
2168 
2169     private int[] appendArray(int[] source, int[] append) {
2170         if (source == null || source.length == 0) return append;
2171 
2172         int[] result = new int[source.length + append.length];
2173 
2174         System.arraycopy(source, 0, result, 0, source.length);
2175         System.arraycopy(append, 0, result, source.length, append.length);
2176         return result;
2177     }
2178 
2179     // Method to be called after compressCatchTable to
2180     // fill in the exception table index for type
2181     // annotations on exception parameters.
2182     public void fillExceptionParameterPositions() {
2183         for (int i = 0; i < varBufferSize; ++i) {
2184             LocalVar lv = varBuffer[i];
2185             if (lv == null || lv.sym == null
2186                     || !lv.sym.hasTypeAnnotations()
2187                     || !lv.sym.isExceptionParameter())
2188                 continue;
2189 
2190             for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
2191                 TypeAnnotationPosition p = ta.position;
2192                 if (p.hasCatchType()) {
2193                     final int idx = findExceptionIndex(p);
2194                     if (idx == -1)
2195                         Assert.error("Could not find exception index for type annotation " +
2196                                      ta + " on exception parameter");
2197                     p.setExceptionIndex(idx);
2198                 }
2199             }
2200         }
2201     }
2202 
2203     private int findExceptionIndex(TypeAnnotationPosition p) {
2204         final int catchType = p.getCatchType();
2205         final int startPos = p.getStartPos();
2206         final int len = catchInfo.length();
2207         List<char[]> iter = catchInfo.toList();
2208         for (int i = 0; i < len; ++i) {
2209             char[] catchEntry = iter.head;
2210             iter = iter.tail;
2211             int ct = catchEntry[3];
2212             int sp = catchEntry[0];
2213             if (catchType == ct && sp == startPos) {
2214                 return i;
2215             }
2216         }
2217         return -1;
2218     }
2219 
2220     /** Put a live variable range into the buffer to be output to the
2221      *  class file.
2222      */
2223     void putVar(LocalVar var) {
2224         // Keep local variables if
2225         // 1) we need them for debug information
2226         // 2) it is an exception type and it contains type annotations
2227         boolean keepLocalVariables = varDebugInfo ||
2228             (var.sym.isExceptionParameter() && var.sym.hasTypeAnnotations());
2229         if (!keepLocalVariables) return;
2230         //don't keep synthetic vars, unless they are lambda method parameters
2231         boolean ignoredSyntheticVar = (var.sym.flags() & Flags.SYNTHETIC) != 0 &&
2232                 ((var.sym.owner.flags() & Flags.LAMBDA_METHOD) == 0 ||
2233                  (var.sym.flags() & Flags.PARAMETER) == 0);
2234         if (ignoredSyntheticVar) return;
2235         //don't include unnamed variables:
2236         if (var.sym.name == var.sym.name.table.names.empty) return ;
2237         if (varBuffer == null)
2238             varBuffer = new LocalVar[20];
2239         else
2240             varBuffer = ArrayUtils.ensureCapacity(varBuffer, varBufferSize);
2241         varBuffer[varBufferSize++] = var;
2242     }
2243 
2244     /** Previously live local variables, to be put into the variable table. */
2245     LocalVar[] varBuffer;
2246     int varBufferSize;
2247 
2248     /** Create a new local variable address and return it.
2249      */
2250     private int newLocal(int typecode) {
2251         int reg = nextreg;
2252         int w = width(typecode);
2253         nextreg = reg + w;
2254         if (nextreg > max_locals) max_locals = nextreg;
2255         return reg;
2256     }
2257 
2258     private int newLocal(Type type) {
2259         return newLocal(typecode(type));
2260     }
2261 
2262     public int newLocal(VarSymbol v) {
2263         int reg = v.adr = newLocal(v.erasure(types));
2264         addLocalVar(v);
2265         return reg;
2266     }
2267 
2268     /** Start a set of fresh registers.
2269      */
2270     public void newRegSegment() {
2271         nextreg = max_locals;
2272     }
2273 
2274     /** End scopes of all variables with registers &ge; first.
2275      */
2276     public void endScopes(int first) {
2277         int prevNextReg = nextreg;
2278         nextreg = first;
2279         for (int i = nextreg; i < prevNextReg; i++) endScope(i);
2280     }
2281 
2282 /* ************************************************************************
2283  * static tables
2284  *************************************************************************/
2285 
2286     public static String mnem(int opcode) {
2287         return Mneumonics.mnem[opcode];
2288     }
2289 
2290     private static class Mneumonics {
2291         private static final String[] mnem = new String[ByteCodeCount];
2292         static {
2293             mnem[nop] = "nop";
2294             mnem[aconst_null] = "aconst_null";
2295             mnem[iconst_m1] = "iconst_m1";
2296             mnem[iconst_0] = "iconst_0";
2297             mnem[iconst_1] = "iconst_1";
2298             mnem[iconst_2] = "iconst_2";
2299             mnem[iconst_3] = "iconst_3";
2300             mnem[iconst_4] = "iconst_4";
2301             mnem[iconst_5] = "iconst_5";
2302             mnem[lconst_0] = "lconst_0";
2303             mnem[lconst_1] = "lconst_1";
2304             mnem[fconst_0] = "fconst_0";
2305             mnem[fconst_1] = "fconst_1";
2306             mnem[fconst_2] = "fconst_2";
2307             mnem[dconst_0] = "dconst_0";
2308             mnem[dconst_1] = "dconst_1";
2309             mnem[bipush] = "bipush";
2310             mnem[sipush] = "sipush";
2311             mnem[ldc1] = "ldc1";
2312             mnem[ldc2] = "ldc2";
2313             mnem[ldc2w] = "ldc2w";
2314             mnem[iload] = "iload";
2315             mnem[lload] = "lload";
2316             mnem[fload] = "fload";
2317             mnem[dload] = "dload";
2318             mnem[aload] = "aload";
2319             mnem[iload_0] = "iload_0";
2320             mnem[lload_0] = "lload_0";
2321             mnem[fload_0] = "fload_0";
2322             mnem[dload_0] = "dload_0";
2323             mnem[aload_0] = "aload_0";
2324             mnem[iload_1] = "iload_1";
2325             mnem[lload_1] = "lload_1";
2326             mnem[fload_1] = "fload_1";
2327             mnem[dload_1] = "dload_1";
2328             mnem[aload_1] = "aload_1";
2329             mnem[iload_2] = "iload_2";
2330             mnem[lload_2] = "lload_2";
2331             mnem[fload_2] = "fload_2";
2332             mnem[dload_2] = "dload_2";
2333             mnem[aload_2] = "aload_2";
2334             mnem[iload_3] = "iload_3";
2335             mnem[lload_3] = "lload_3";
2336             mnem[fload_3] = "fload_3";
2337             mnem[dload_3] = "dload_3";
2338             mnem[aload_3] = "aload_3";
2339             mnem[iaload] = "iaload";
2340             mnem[laload] = "laload";
2341             mnem[faload] = "faload";
2342             mnem[daload] = "daload";
2343             mnem[aaload] = "aaload";
2344             mnem[baload] = "baload";
2345             mnem[caload] = "caload";
2346             mnem[saload] = "saload";
2347             mnem[istore] = "istore";
2348             mnem[lstore] = "lstore";
2349             mnem[fstore] = "fstore";
2350             mnem[dstore] = "dstore";
2351             mnem[astore] = "astore";
2352             mnem[istore_0] = "istore_0";
2353             mnem[lstore_0] = "lstore_0";
2354             mnem[fstore_0] = "fstore_0";
2355             mnem[dstore_0] = "dstore_0";
2356             mnem[astore_0] = "astore_0";
2357             mnem[istore_1] = "istore_1";
2358             mnem[lstore_1] = "lstore_1";
2359             mnem[fstore_1] = "fstore_1";
2360             mnem[dstore_1] = "dstore_1";
2361             mnem[astore_1] = "astore_1";
2362             mnem[istore_2] = "istore_2";
2363             mnem[lstore_2] = "lstore_2";
2364             mnem[fstore_2] = "fstore_2";
2365             mnem[dstore_2] = "dstore_2";
2366             mnem[astore_2] = "astore_2";
2367             mnem[istore_3] = "istore_3";
2368             mnem[lstore_3] = "lstore_3";
2369             mnem[fstore_3] = "fstore_3";
2370             mnem[dstore_3] = "dstore_3";
2371             mnem[astore_3] = "astore_3";
2372             mnem[iastore] = "iastore";
2373             mnem[lastore] = "lastore";
2374             mnem[fastore] = "fastore";
2375             mnem[dastore] = "dastore";
2376             mnem[aastore] = "aastore";
2377             mnem[bastore] = "bastore";
2378             mnem[castore] = "castore";
2379             mnem[sastore] = "sastore";
2380             mnem[pop] = "pop";
2381             mnem[pop2] = "pop2";
2382             mnem[dup] = "dup";
2383             mnem[dup_x1] = "dup_x1";
2384             mnem[dup_x2] = "dup_x2";
2385             mnem[dup2] = "dup2";
2386             mnem[dup2_x1] = "dup2_x1";
2387             mnem[dup2_x2] = "dup2_x2";
2388             mnem[swap] = "swap";
2389             mnem[iadd] = "iadd";
2390             mnem[ladd] = "ladd";
2391             mnem[fadd] = "fadd";
2392             mnem[dadd] = "dadd";
2393             mnem[isub] = "isub";
2394             mnem[lsub] = "lsub";
2395             mnem[fsub] = "fsub";
2396             mnem[dsub] = "dsub";
2397             mnem[imul] = "imul";
2398             mnem[lmul] = "lmul";
2399             mnem[fmul] = "fmul";
2400             mnem[dmul] = "dmul";
2401             mnem[idiv] = "idiv";
2402             mnem[ldiv] = "ldiv";
2403             mnem[fdiv] = "fdiv";
2404             mnem[ddiv] = "ddiv";
2405             mnem[imod] = "imod";
2406             mnem[lmod] = "lmod";
2407             mnem[fmod] = "fmod";
2408             mnem[dmod] = "dmod";
2409             mnem[ineg] = "ineg";
2410             mnem[lneg] = "lneg";
2411             mnem[fneg] = "fneg";
2412             mnem[dneg] = "dneg";
2413             mnem[ishl] = "ishl";
2414             mnem[lshl] = "lshl";
2415             mnem[ishr] = "ishr";
2416             mnem[lshr] = "lshr";
2417             mnem[iushr] = "iushr";
2418             mnem[lushr] = "lushr";
2419             mnem[iand] = "iand";
2420             mnem[land] = "land";
2421             mnem[ior] = "ior";
2422             mnem[lor] = "lor";
2423             mnem[ixor] = "ixor";
2424             mnem[lxor] = "lxor";
2425             mnem[iinc] = "iinc";
2426             mnem[i2l] = "i2l";
2427             mnem[i2f] = "i2f";
2428             mnem[i2d] = "i2d";
2429             mnem[l2i] = "l2i";
2430             mnem[l2f] = "l2f";
2431             mnem[l2d] = "l2d";
2432             mnem[f2i] = "f2i";
2433             mnem[f2l] = "f2l";
2434             mnem[f2d] = "f2d";
2435             mnem[d2i] = "d2i";
2436             mnem[d2l] = "d2l";
2437             mnem[d2f] = "d2f";
2438             mnem[int2byte] = "int2byte";
2439             mnem[int2char] = "int2char";
2440             mnem[int2short] = "int2short";
2441             mnem[lcmp] = "lcmp";
2442             mnem[fcmpl] = "fcmpl";
2443             mnem[fcmpg] = "fcmpg";
2444             mnem[dcmpl] = "dcmpl";
2445             mnem[dcmpg] = "dcmpg";
2446             mnem[ifeq] = "ifeq";
2447             mnem[ifne] = "ifne";
2448             mnem[iflt] = "iflt";
2449             mnem[ifge] = "ifge";
2450             mnem[ifgt] = "ifgt";
2451             mnem[ifle] = "ifle";
2452             mnem[if_icmpeq] = "if_icmpeq";
2453             mnem[if_icmpne] = "if_icmpne";
2454             mnem[if_icmplt] = "if_icmplt";
2455             mnem[if_icmpge] = "if_icmpge";
2456             mnem[if_icmpgt] = "if_icmpgt";
2457             mnem[if_icmple] = "if_icmple";
2458             mnem[if_acmpeq] = "if_acmpeq";
2459             mnem[if_acmpne] = "if_acmpne";
2460             mnem[goto_] = "goto_";
2461             mnem[jsr] = "jsr";
2462             mnem[ret] = "ret";
2463             mnem[tableswitch] = "tableswitch";
2464             mnem[lookupswitch] = "lookupswitch";
2465             mnem[ireturn] = "ireturn";
2466             mnem[lreturn] = "lreturn";
2467             mnem[freturn] = "freturn";
2468             mnem[dreturn] = "dreturn";
2469             mnem[areturn] = "areturn";
2470             mnem[return_] = "return_";
2471             mnem[getstatic] = "getstatic";
2472             mnem[putstatic] = "putstatic";
2473             mnem[getfield] = "getfield";
2474             mnem[putfield] = "putfield";
2475             mnem[invokevirtual] = "invokevirtual";
2476             mnem[invokespecial] = "invokespecial";
2477             mnem[invokestatic] = "invokestatic";
2478             mnem[invokeinterface] = "invokeinterface";
2479             mnem[invokedynamic] = "invokedynamic";
2480             mnem[new_] = "new_";
2481             mnem[newarray] = "newarray";
2482             mnem[anewarray] = "anewarray";
2483             mnem[arraylength] = "arraylength";
2484             mnem[athrow] = "athrow";
2485             mnem[checkcast] = "checkcast";
2486             mnem[instanceof_] = "instanceof_";
2487             mnem[monitorenter] = "monitorenter";
2488             mnem[monitorexit] = "monitorexit";
2489             mnem[wide] = "wide";
2490             mnem[multianewarray] = "multianewarray";
2491             mnem[if_acmp_null] = "if_acmp_null";
2492             mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2493             mnem[goto_w] = "goto_w";
2494             mnem[jsr_w] = "jsr_w";
2495             mnem[breakpoint] = "breakpoint";
2496         }
2497     }
2498 }