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> result = types.closureMin(
1858                         types.intersect(
1859                             t1.hasTag(ARRAY) ?
1860                                     List.of(syms.serializableType, syms.cloneableType, syms.objectType) :
1861                                     types.erasedSupertypes(t1),
1862                             t2.hasTag(ARRAY) ?
1863                                     List.of(syms.serializableType, syms.cloneableType, syms.objectType) :
1864                                     types.erasedSupertypes(t2)
1865                         )
1866                 );
1867                 return result.head;
1868             }
1869         }
1870 
1871         void dump() {
1872             dump(-1);
1873         }
1874 
1875         void dump(int pc) {
1876             System.err.print("stackMap for " + meth.owner + "." + meth);
1877             if (pc == -1)
1878                 System.out.println();
1879             else
1880                 System.out.println(" at " + pc);
1881             System.err.println(" stack (from bottom):");
1882             for (int i=0; i<stacksize; i++)
1883                 System.err.println("  " + i + ": " + stack[i]);
1884 
1885             int lastLocal = 0;
1886             for (int i=max_locals-1; i>=0; i--) {
1887                 if (defined.isMember(i)) {
1888                     lastLocal = i;
1889                     break;
1890                 }
1891             }
1892             if (lastLocal >= 0)
1893                 System.err.println(" locals:");
1894             for (int i=0; i<=lastLocal; i++) {
1895                 System.err.print("  " + i + ": ");
1896                 if (defined.isMember(i)) {
1897                     LocalVar var = lvar[i];
1898                     if (var == null) {
1899                         System.err.println("(none)");
1900                     } else if (var.sym == null)
1901                         System.err.println("UNKNOWN!");
1902                     else
1903                         System.err.println("" + var.sym + " of type " +
1904                                            var.sym.erasure(types));
1905                 } else {
1906                     System.err.println("undefined");
1907                 }
1908             }
1909             if (nlocks != 0) {
1910                 System.err.print(" locks:");
1911                 for (int i=0; i<nlocks; i++) {
1912                     System.err.print(" " + locks[i]);
1913                 }
1914                 System.err.println();
1915             }
1916         }
1917     }
1918 
1919     static final Type jsrReturnValue = new JCPrimitiveType(INT, null);
1920 
1921 
1922 /* **************************************************************************
1923  * Local variables
1924  ****************************************************************************/
1925 
1926     /** A live range of a local variable. */
1927     static class LocalVar {
1928         final VarSymbol sym;
1929         final char reg;
1930 
1931         class Range {
1932             char start_pc = Character.MAX_VALUE;
1933             char length = Character.MAX_VALUE;
1934 
1935             Range() {}
1936 
1937             Range(char start) {
1938                 this.start_pc = start;
1939             }
1940 
1941             Range(char start, char length) {
1942                 this.start_pc = start;
1943                 this.length = length;
1944             }
1945 
1946             boolean closed() {
1947                 return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE;
1948             }
1949 
1950             @Override
1951             public String toString() {
1952                 int currentStartPC = start_pc;
1953                 int currentLength = length;
1954                 return "startpc = " + currentStartPC + " length " + currentLength;
1955             }
1956         }
1957 
1958         java.util.List<Range> aliveRanges = new java.util.ArrayList<>();
1959 
1960         LocalVar(VarSymbol v) {
1961             this.sym = v;
1962             this.reg = (char)v.adr;
1963         }
1964         public LocalVar dup() {
1965             return new LocalVar(sym);
1966         }
1967 
1968         Range firstRange() {
1969             return aliveRanges.isEmpty() ? null : aliveRanges.get(0);
1970         }
1971 
1972         Range lastRange() {
1973             return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
1974         }
1975 
1976         void removeLastRange() {
1977             Range lastRange = lastRange();
1978             if (lastRange != null) {
1979                 aliveRanges.remove(lastRange);
1980             }
1981         }
1982 
1983         @Override
1984         public String toString() {
1985             if (aliveRanges == null) {
1986                 return "empty local var";
1987             }
1988             StringBuilder sb = new StringBuilder().append(sym)
1989                     .append(" in register ").append((int)reg).append(" \n");
1990             for (Range r : aliveRanges) {
1991                 sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc)))
1992                     .append(" length=").append(Integer.toString(((int)r.length)))
1993                     .append("\n");
1994             }
1995             return sb.toString();
1996         }
1997 
1998         public void openRange(char start) {
1999             if (!hasOpenRange()) {
2000                 aliveRanges.add(new Range(start));
2001             }
2002         }
2003 
2004         public void closeRange(char length) {
2005             if (isLastRangeInitialized() && length > 0) {
2006                 Range range = lastRange();
2007                 if (range != null) {
2008                     if (range.length == Character.MAX_VALUE) {
2009                         range.length = length;
2010                     }
2011                 }
2012             } else {
2013                 removeLastRange();
2014             }
2015         }
2016 
2017         public boolean hasOpenRange() {
2018             if (aliveRanges.isEmpty()) {
2019                 return false;
2020             }
2021             return lastRange().length == Character.MAX_VALUE;
2022         }
2023 
2024         public boolean isLastRangeInitialized() {
2025             if (aliveRanges.isEmpty()) {
2026                 return false;
2027             }
2028             return lastRange().start_pc != Character.MAX_VALUE;
2029         }
2030 
2031         public Range getWidestRange() {
2032             if (aliveRanges.isEmpty()) {
2033                 return new Range();
2034             } else {
2035                 Range firstRange = firstRange();
2036                 Range lastRange = lastRange();
2037                 char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc));
2038                 return new Range(firstRange.start_pc, length);
2039             }
2040          }
2041 
2042     }
2043 
2044     /** Local variables, indexed by register. */
2045     LocalVar[] lvar;
2046 
2047     /** Add a new local variable. */
2048     private void addLocalVar(VarSymbol v) {
2049         int adr = v.adr;
2050         lvar = ArrayUtils.ensureCapacity(lvar, adr+1);
2051         Assert.checkNull(lvar[adr]);
2052         if (pendingJumps != null) {
2053             resolvePending();
2054         }
2055         lvar[adr] = new LocalVar(v);
2056         state.defined.excl(adr);
2057     }
2058 
2059     void adjustAliveRanges(int oldCP, int delta) {
2060         for (LocalVar localVar: lvar) {
2061             if (localVar != null) {
2062                 for (LocalVar.Range range: localVar.aliveRanges) {
2063                     if (range.closed() && range.start_pc + range.length >= oldCP) {
2064                         range.length += (char)delta;
2065                     }
2066                 }
2067             }
2068         }
2069     }
2070 
2071     /**
2072      * Calculates the size of the LocalVariableTable.
2073      */
2074     public int getLVTSize() {
2075         int result = varBufferSize;
2076         for (int i = 0; i < varBufferSize; i++) {
2077             LocalVar var = varBuffer[i];
2078             result += var.aliveRanges.size() - 1;
2079         }
2080         return result;
2081     }
2082 
2083     /** Set the current variable defined state. */
2084     public void setDefined(Bits newDefined) {
2085         if (alive && newDefined != state.defined) {
2086             Bits diff = new Bits(state.defined).xorSet(newDefined);
2087             for (int adr = diff.nextBit(0);
2088                  adr >= 0;
2089                  adr = diff.nextBit(adr+1)) {
2090                 if (adr >= nextreg)
2091                     state.defined.excl(adr);
2092                 else if (state.defined.isMember(adr))
2093                     setUndefined(adr);
2094                 else
2095                     setDefined(adr);
2096             }
2097         }
2098     }
2099 
2100     /** Mark a register as being (possibly) defined. */
2101     public void setDefined(int adr) {
2102         LocalVar v = lvar[adr];
2103         if (v == null) {
2104             state.defined.excl(adr);
2105         } else {
2106             state.defined.incl(adr);
2107             if (cp < Character.MAX_VALUE) {
2108                 v.openRange((char)cp);
2109             }
2110         }
2111     }
2112 
2113     /** Mark a register as being undefined. */
2114     public void setUndefined(int adr) {
2115         state.defined.excl(adr);
2116         if (adr < lvar.length &&
2117             lvar[adr] != null &&
2118             lvar[adr].isLastRangeInitialized()) {
2119             LocalVar v = lvar[adr];
2120             char length = (char)(curCP() - v.lastRange().start_pc);
2121             if (length < Character.MAX_VALUE) {
2122                 lvar[adr] = v.dup();
2123                 v.closeRange(length);
2124                 putVar(v);
2125                 fillLocalVarPosition(v);
2126             } else {
2127                 v.removeLastRange();
2128             }
2129         }
2130     }
2131 
2132     /** End the scope of a variable. */
2133     private void endScope(int adr) {
2134         LocalVar v = lvar[adr];
2135         if (v != null) {
2136             if (v.isLastRangeInitialized()) {
2137                 char length = (char)(curCP() - v.lastRange().start_pc);
2138                 if (length < Character.MAX_VALUE) {
2139                     v.closeRange(length);
2140                     putVar(v);
2141                     fillLocalVarPosition(v);
2142                 }
2143             }
2144             /** the call to curCP() can implicitly adjust the current cp, if so
2145              * the alive range of local variables may be modified. Thus we need
2146              * all of them. For this reason assigning null to the given address
2147              * should be the last action to do.
2148              */
2149             lvar[adr] = null;
2150         }
2151         state.defined.excl(adr);
2152     }
2153 
2154     private void fillLocalVarPosition(LocalVar lv) {
2155         if (lv == null || lv.sym == null || lv.sym.isExceptionParameter()|| !lv.sym.hasTypeAnnotations())
2156             return;
2157         LocalVar.Range[] validRanges = lv.aliveRanges.stream().filter(r -> r.closed() && r.length > 0).toArray(s -> new LocalVar.Range[s]);
2158         if (validRanges.length == 0)
2159             return ;
2160         int[] lvarOffset = Arrays.stream(validRanges).mapToInt(r -> r.start_pc).toArray();
2161         int[] lvarLength = Arrays.stream(validRanges).mapToInt(r -> r.length).toArray();
2162         int[] lvarIndex = Arrays.stream(validRanges).mapToInt(r -> lv.reg).toArray();
2163         for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
2164             TypeAnnotationPosition p = ta.position;
2165             p.lvarOffset = appendArray(p.lvarOffset, lvarOffset);
2166             p.lvarLength = appendArray(p.lvarLength, lvarLength);
2167             p.lvarIndex = appendArray(p.lvarIndex, lvarIndex);
2168             p.isValidOffset = true;
2169         }
2170     }
2171 
2172     private int[] appendArray(int[] source, int[] append) {
2173         if (source == null || source.length == 0) return append;
2174 
2175         int[] result = new int[source.length + append.length];
2176 
2177         System.arraycopy(source, 0, result, 0, source.length);
2178         System.arraycopy(append, 0, result, source.length, append.length);
2179         return result;
2180     }
2181 
2182     // Method to be called after compressCatchTable to
2183     // fill in the exception table index for type
2184     // annotations on exception parameters.
2185     public void fillExceptionParameterPositions() {
2186         for (int i = 0; i < varBufferSize; ++i) {
2187             LocalVar lv = varBuffer[i];
2188             if (lv == null || lv.sym == null
2189                     || !lv.sym.hasTypeAnnotations()
2190                     || !lv.sym.isExceptionParameter())
2191                 continue;
2192 
2193             for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
2194                 TypeAnnotationPosition p = ta.position;
2195                 if (p.hasCatchType()) {
2196                     final int idx = findExceptionIndex(p);
2197                     if (idx == -1)
2198                         Assert.error("Could not find exception index for type annotation " +
2199                                      ta + " on exception parameter");
2200                     p.setExceptionIndex(idx);
2201                 }
2202             }
2203         }
2204     }
2205 
2206     private int findExceptionIndex(TypeAnnotationPosition p) {
2207         final int catchType = p.getCatchType();
2208         final int startPos = p.getStartPos();
2209         final int len = catchInfo.length();
2210         List<char[]> iter = catchInfo.toList();
2211         for (int i = 0; i < len; ++i) {
2212             char[] catchEntry = iter.head;
2213             iter = iter.tail;
2214             int ct = catchEntry[3];
2215             int sp = catchEntry[0];
2216             if (catchType == ct && sp == startPos) {
2217                 return i;
2218             }
2219         }
2220         return -1;
2221     }
2222 
2223     /** Put a live variable range into the buffer to be output to the
2224      *  class file.
2225      */
2226     void putVar(LocalVar var) {
2227         // Keep local variables if
2228         // 1) we need them for debug information
2229         // 2) it is an exception type and it contains type annotations
2230         boolean keepLocalVariables = varDebugInfo ||
2231             (var.sym.isExceptionParameter() && var.sym.hasTypeAnnotations());
2232         if (!keepLocalVariables) return;
2233         //don't keep synthetic vars, unless they are lambda method parameters
2234         boolean ignoredSyntheticVar = (var.sym.flags() & Flags.SYNTHETIC) != 0 &&
2235                 ((var.sym.owner.flags() & Flags.LAMBDA_METHOD) == 0 ||
2236                  (var.sym.flags() & Flags.PARAMETER) == 0);
2237         if (ignoredSyntheticVar) return;
2238         //don't include unnamed variables:
2239         if (var.sym.name == var.sym.name.table.names.empty) return ;
2240         if (varBuffer == null)
2241             varBuffer = new LocalVar[20];
2242         else
2243             varBuffer = ArrayUtils.ensureCapacity(varBuffer, varBufferSize);
2244         varBuffer[varBufferSize++] = var;
2245     }
2246 
2247     /** Previously live local variables, to be put into the variable table. */
2248     LocalVar[] varBuffer;
2249     int varBufferSize;
2250 
2251     /** Create a new local variable address and return it.
2252      */
2253     private int newLocal(int typecode) {
2254         int reg = nextreg;
2255         int w = width(typecode);
2256         nextreg = reg + w;
2257         if (nextreg > max_locals) max_locals = nextreg;
2258         return reg;
2259     }
2260 
2261     private int newLocal(Type type) {
2262         return newLocal(typecode(type));
2263     }
2264 
2265     public int newLocal(VarSymbol v) {
2266         int reg = v.adr = newLocal(v.erasure(types));
2267         addLocalVar(v);
2268         return reg;
2269     }
2270 
2271     /** Start a set of fresh registers.
2272      */
2273     public void newRegSegment() {
2274         nextreg = max_locals;
2275     }
2276 
2277     /** End scopes of all variables with registers &ge; first.
2278      */
2279     public void endScopes(int first) {
2280         int prevNextReg = nextreg;
2281         nextreg = first;
2282         for (int i = nextreg; i < prevNextReg; i++) endScope(i);
2283     }
2284 
2285 /* ************************************************************************
2286  * static tables
2287  *************************************************************************/
2288 
2289     public static String mnem(int opcode) {
2290         return Mneumonics.mnem[opcode];
2291     }
2292 
2293     private static class Mneumonics {
2294         private static final String[] mnem = new String[ByteCodeCount];
2295         static {
2296             mnem[nop] = "nop";
2297             mnem[aconst_null] = "aconst_null";
2298             mnem[iconst_m1] = "iconst_m1";
2299             mnem[iconst_0] = "iconst_0";
2300             mnem[iconst_1] = "iconst_1";
2301             mnem[iconst_2] = "iconst_2";
2302             mnem[iconst_3] = "iconst_3";
2303             mnem[iconst_4] = "iconst_4";
2304             mnem[iconst_5] = "iconst_5";
2305             mnem[lconst_0] = "lconst_0";
2306             mnem[lconst_1] = "lconst_1";
2307             mnem[fconst_0] = "fconst_0";
2308             mnem[fconst_1] = "fconst_1";
2309             mnem[fconst_2] = "fconst_2";
2310             mnem[dconst_0] = "dconst_0";
2311             mnem[dconst_1] = "dconst_1";
2312             mnem[bipush] = "bipush";
2313             mnem[sipush] = "sipush";
2314             mnem[ldc1] = "ldc1";
2315             mnem[ldc2] = "ldc2";
2316             mnem[ldc2w] = "ldc2w";
2317             mnem[iload] = "iload";
2318             mnem[lload] = "lload";
2319             mnem[fload] = "fload";
2320             mnem[dload] = "dload";
2321             mnem[aload] = "aload";
2322             mnem[iload_0] = "iload_0";
2323             mnem[lload_0] = "lload_0";
2324             mnem[fload_0] = "fload_0";
2325             mnem[dload_0] = "dload_0";
2326             mnem[aload_0] = "aload_0";
2327             mnem[iload_1] = "iload_1";
2328             mnem[lload_1] = "lload_1";
2329             mnem[fload_1] = "fload_1";
2330             mnem[dload_1] = "dload_1";
2331             mnem[aload_1] = "aload_1";
2332             mnem[iload_2] = "iload_2";
2333             mnem[lload_2] = "lload_2";
2334             mnem[fload_2] = "fload_2";
2335             mnem[dload_2] = "dload_2";
2336             mnem[aload_2] = "aload_2";
2337             mnem[iload_3] = "iload_3";
2338             mnem[lload_3] = "lload_3";
2339             mnem[fload_3] = "fload_3";
2340             mnem[dload_3] = "dload_3";
2341             mnem[aload_3] = "aload_3";
2342             mnem[iaload] = "iaload";
2343             mnem[laload] = "laload";
2344             mnem[faload] = "faload";
2345             mnem[daload] = "daload";
2346             mnem[aaload] = "aaload";
2347             mnem[baload] = "baload";
2348             mnem[caload] = "caload";
2349             mnem[saload] = "saload";
2350             mnem[istore] = "istore";
2351             mnem[lstore] = "lstore";
2352             mnem[fstore] = "fstore";
2353             mnem[dstore] = "dstore";
2354             mnem[astore] = "astore";
2355             mnem[istore_0] = "istore_0";
2356             mnem[lstore_0] = "lstore_0";
2357             mnem[fstore_0] = "fstore_0";
2358             mnem[dstore_0] = "dstore_0";
2359             mnem[astore_0] = "astore_0";
2360             mnem[istore_1] = "istore_1";
2361             mnem[lstore_1] = "lstore_1";
2362             mnem[fstore_1] = "fstore_1";
2363             mnem[dstore_1] = "dstore_1";
2364             mnem[astore_1] = "astore_1";
2365             mnem[istore_2] = "istore_2";
2366             mnem[lstore_2] = "lstore_2";
2367             mnem[fstore_2] = "fstore_2";
2368             mnem[dstore_2] = "dstore_2";
2369             mnem[astore_2] = "astore_2";
2370             mnem[istore_3] = "istore_3";
2371             mnem[lstore_3] = "lstore_3";
2372             mnem[fstore_3] = "fstore_3";
2373             mnem[dstore_3] = "dstore_3";
2374             mnem[astore_3] = "astore_3";
2375             mnem[iastore] = "iastore";
2376             mnem[lastore] = "lastore";
2377             mnem[fastore] = "fastore";
2378             mnem[dastore] = "dastore";
2379             mnem[aastore] = "aastore";
2380             mnem[bastore] = "bastore";
2381             mnem[castore] = "castore";
2382             mnem[sastore] = "sastore";
2383             mnem[pop] = "pop";
2384             mnem[pop2] = "pop2";
2385             mnem[dup] = "dup";
2386             mnem[dup_x1] = "dup_x1";
2387             mnem[dup_x2] = "dup_x2";
2388             mnem[dup2] = "dup2";
2389             mnem[dup2_x1] = "dup2_x1";
2390             mnem[dup2_x2] = "dup2_x2";
2391             mnem[swap] = "swap";
2392             mnem[iadd] = "iadd";
2393             mnem[ladd] = "ladd";
2394             mnem[fadd] = "fadd";
2395             mnem[dadd] = "dadd";
2396             mnem[isub] = "isub";
2397             mnem[lsub] = "lsub";
2398             mnem[fsub] = "fsub";
2399             mnem[dsub] = "dsub";
2400             mnem[imul] = "imul";
2401             mnem[lmul] = "lmul";
2402             mnem[fmul] = "fmul";
2403             mnem[dmul] = "dmul";
2404             mnem[idiv] = "idiv";
2405             mnem[ldiv] = "ldiv";
2406             mnem[fdiv] = "fdiv";
2407             mnem[ddiv] = "ddiv";
2408             mnem[imod] = "imod";
2409             mnem[lmod] = "lmod";
2410             mnem[fmod] = "fmod";
2411             mnem[dmod] = "dmod";
2412             mnem[ineg] = "ineg";
2413             mnem[lneg] = "lneg";
2414             mnem[fneg] = "fneg";
2415             mnem[dneg] = "dneg";
2416             mnem[ishl] = "ishl";
2417             mnem[lshl] = "lshl";
2418             mnem[ishr] = "ishr";
2419             mnem[lshr] = "lshr";
2420             mnem[iushr] = "iushr";
2421             mnem[lushr] = "lushr";
2422             mnem[iand] = "iand";
2423             mnem[land] = "land";
2424             mnem[ior] = "ior";
2425             mnem[lor] = "lor";
2426             mnem[ixor] = "ixor";
2427             mnem[lxor] = "lxor";
2428             mnem[iinc] = "iinc";
2429             mnem[i2l] = "i2l";
2430             mnem[i2f] = "i2f";
2431             mnem[i2d] = "i2d";
2432             mnem[l2i] = "l2i";
2433             mnem[l2f] = "l2f";
2434             mnem[l2d] = "l2d";
2435             mnem[f2i] = "f2i";
2436             mnem[f2l] = "f2l";
2437             mnem[f2d] = "f2d";
2438             mnem[d2i] = "d2i";
2439             mnem[d2l] = "d2l";
2440             mnem[d2f] = "d2f";
2441             mnem[int2byte] = "int2byte";
2442             mnem[int2char] = "int2char";
2443             mnem[int2short] = "int2short";
2444             mnem[lcmp] = "lcmp";
2445             mnem[fcmpl] = "fcmpl";
2446             mnem[fcmpg] = "fcmpg";
2447             mnem[dcmpl] = "dcmpl";
2448             mnem[dcmpg] = "dcmpg";
2449             mnem[ifeq] = "ifeq";
2450             mnem[ifne] = "ifne";
2451             mnem[iflt] = "iflt";
2452             mnem[ifge] = "ifge";
2453             mnem[ifgt] = "ifgt";
2454             mnem[ifle] = "ifle";
2455             mnem[if_icmpeq] = "if_icmpeq";
2456             mnem[if_icmpne] = "if_icmpne";
2457             mnem[if_icmplt] = "if_icmplt";
2458             mnem[if_icmpge] = "if_icmpge";
2459             mnem[if_icmpgt] = "if_icmpgt";
2460             mnem[if_icmple] = "if_icmple";
2461             mnem[if_acmpeq] = "if_acmpeq";
2462             mnem[if_acmpne] = "if_acmpne";
2463             mnem[goto_] = "goto_";
2464             mnem[jsr] = "jsr";
2465             mnem[ret] = "ret";
2466             mnem[tableswitch] = "tableswitch";
2467             mnem[lookupswitch] = "lookupswitch";
2468             mnem[ireturn] = "ireturn";
2469             mnem[lreturn] = "lreturn";
2470             mnem[freturn] = "freturn";
2471             mnem[dreturn] = "dreturn";
2472             mnem[areturn] = "areturn";
2473             mnem[return_] = "return_";
2474             mnem[getstatic] = "getstatic";
2475             mnem[putstatic] = "putstatic";
2476             mnem[getfield] = "getfield";
2477             mnem[putfield] = "putfield";
2478             mnem[invokevirtual] = "invokevirtual";
2479             mnem[invokespecial] = "invokespecial";
2480             mnem[invokestatic] = "invokestatic";
2481             mnem[invokeinterface] = "invokeinterface";
2482             mnem[invokedynamic] = "invokedynamic";
2483             mnem[new_] = "new_";
2484             mnem[newarray] = "newarray";
2485             mnem[anewarray] = "anewarray";
2486             mnem[arraylength] = "arraylength";
2487             mnem[athrow] = "athrow";
2488             mnem[checkcast] = "checkcast";
2489             mnem[instanceof_] = "instanceof_";
2490             mnem[monitorenter] = "monitorenter";
2491             mnem[monitorexit] = "monitorexit";
2492             mnem[wide] = "wide";
2493             mnem[multianewarray] = "multianewarray";
2494             mnem[if_acmp_null] = "if_acmp_null";
2495             mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2496             mnem[goto_w] = "goto_w";
2497             mnem[jsr_w] = "jsr_w";
2498             mnem[breakpoint] = "breakpoint";
2499         }
2500     }
2501 }