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