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