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