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