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