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