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