src/share/classes/com/sun/tools/javac/jvm/Code.java

Mon, 16 Oct 2017 16:07:48 +0800

author
aoqi
date
Mon, 16 Oct 2017 16:07:48 +0800
changeset 2893
ca5783d9a597
parent 2734
ba758e1ffa69
parent 2702
9ca8d8713094
permissions
-rw-r--r--

merge

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

mercurial