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