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