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

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

     1 /*
     2  * Copyright (c) 1999, 2014, 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     final LVTRanges lvtRanges;
   187     /** Construct a code object, given the settings of the fatcode,
   188      *  debugging info switches and the CharacterRangeTable.
   189      */
   190     public Code(MethodSymbol meth,
   191                 boolean fatcode,
   192                 Position.LineMap lineMap,
   193                 boolean varDebugInfo,
   194                 StackMapFormat stackMap,
   195                 boolean debugCode,
   196                 CRTable crt,
   197                 Symtab syms,
   198                 Types types,
   199                 Pool pool,
   200                 LVTRanges lvtRanges) {
   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         this.lvtRanges = lvtRanges;
   223     }
   226 /* **************************************************************************
   227  * Typecodes & related stuff
   228  ****************************************************************************/
   230     /** Given a type, return its type code (used implicitly in the
   231      *  JVM architecture).
   232      */
   233     public static int typecode(Type type) {
   234         switch (type.getTag()) {
   235         case BYTE: return BYTEcode;
   236         case SHORT: return SHORTcode;
   237         case CHAR: return CHARcode;
   238         case INT: return INTcode;
   239         case LONG: return LONGcode;
   240         case FLOAT: return FLOATcode;
   241         case DOUBLE: return DOUBLEcode;
   242         case BOOLEAN: return BYTEcode;
   243         case VOID: return VOIDcode;
   244         case CLASS:
   245         case ARRAY:
   246         case METHOD:
   247         case BOT:
   248         case TYPEVAR:
   249         case UNINITIALIZED_THIS:
   250         case UNINITIALIZED_OBJECT:
   251             return OBJECTcode;
   252         default: throw new AssertionError("typecode " + type.getTag());
   253         }
   254     }
   256     /** Collapse type code for subtypes of int to INTcode.
   257      */
   258     public static int truncate(int tc) {
   259         switch (tc) {
   260         case BYTEcode: case SHORTcode: case CHARcode: return INTcode;
   261         default: return tc;
   262         }
   263     }
   265     /** The width in bytes of objects of the type.
   266      */
   267     public static int width(int typecode) {
   268         switch (typecode) {
   269         case LONGcode: case DOUBLEcode: return 2;
   270         case VOIDcode: return 0;
   271         default: return 1;
   272         }
   273     }
   275     public static int width(Type type) {
   276         return type == null ? 1 : width(typecode(type));
   277     }
   279     /** The total width taken up by a vector of objects.
   280      */
   281     public static int width(List<Type> types) {
   282         int w = 0;
   283         for (List<Type> l = types; l.nonEmpty(); l = l.tail)
   284             w = w + width(l.head);
   285         return w;
   286     }
   288     /** Given a type, return its code for allocating arrays of that type.
   289      */
   290     public static int arraycode(Type type) {
   291         switch (type.getTag()) {
   292         case BYTE: return 8;
   293         case BOOLEAN: return 4;
   294         case SHORT: return 9;
   295         case CHAR: return 5;
   296         case INT: return 10;
   297         case LONG: return 11;
   298         case FLOAT: return 6;
   299         case DOUBLE: return 7;
   300         case CLASS: return 0;
   301         case ARRAY: return 1;
   302         default: throw new AssertionError("arraycode " + type);
   303         }
   304     }
   307 /* **************************************************************************
   308  * Emit code
   309  ****************************************************************************/
   311     /** The current output code pointer.
   312      */
   313     public int curCP() {
   314         /*
   315          * This method has side-effects because calling it can indirectly provoke
   316          *  extra code generation, like goto instructions, depending on the context
   317          *  where it's called.
   318          *  Use with care or even better avoid using it.
   319          */
   320         if (pendingJumps != null) {
   321             resolvePending();
   322         }
   323         if (pendingStatPos != Position.NOPOS) {
   324             markStatBegin();
   325         }
   326         fixedPc = true;
   327         return cp;
   328     }
   330     /** Emit a byte of code.
   331      */
   332     private  void emit1(int od) {
   333         if (!alive) return;
   334         code = ArrayUtils.ensureCapacity(code, cp);
   335         code[cp++] = (byte)od;
   336     }
   338     /** Emit two bytes of code.
   339      */
   340     private void emit2(int od) {
   341         if (!alive) return;
   342         if (cp + 2 > code.length) {
   343             emit1(od >> 8);
   344             emit1(od);
   345         } else {
   346             code[cp++] = (byte)(od >> 8);
   347             code[cp++] = (byte)od;
   348         }
   349     }
   351     /** Emit four bytes of code.
   352      */
   353     public void emit4(int od) {
   354         if (!alive) return;
   355         if (cp + 4 > code.length) {
   356             emit1(od >> 24);
   357             emit1(od >> 16);
   358             emit1(od >> 8);
   359             emit1(od);
   360         } else {
   361             code[cp++] = (byte)(od >> 24);
   362             code[cp++] = (byte)(od >> 16);
   363             code[cp++] = (byte)(od >> 8);
   364             code[cp++] = (byte)od;
   365         }
   366     }
   368     /** Emit an opcode.
   369      */
   370     private void emitop(int op) {
   371         if (pendingJumps != null) resolvePending();
   372         if (alive) {
   373             if (pendingStatPos != Position.NOPOS)
   374                 markStatBegin();
   375             if (pendingStackMap) {
   376                 pendingStackMap = false;
   377                 emitStackMap();
   378             }
   379             if (debugCode)
   380                 System.err.println("emit@" + cp + " stack=" +
   381                                    state.stacksize + ": " +
   382                                    mnem(op));
   383             emit1(op);
   384         }
   385     }
   387     void postop() {
   388         Assert.check(alive || state.stacksize == 0);
   389     }
   391     /** Emit a ldc (or ldc_w) instruction, taking into account operand size
   392     */
   393     public void emitLdc(int od) {
   394         if (od <= 255) {
   395             emitop1(ldc1, od);
   396         }
   397         else {
   398             emitop2(ldc2, od);
   399         }
   400     }
   402     /** Emit a multinewarray instruction.
   403      */
   404     public void emitMultianewarray(int ndims, int type, Type arrayType) {
   405         emitop(multianewarray);
   406         if (!alive) return;
   407         emit2(type);
   408         emit1(ndims);
   409         state.pop(ndims);
   410         state.push(arrayType);
   411     }
   413     /** Emit newarray.
   414      */
   415     public void emitNewarray(int elemcode, Type arrayType) {
   416         emitop(newarray);
   417         if (!alive) return;
   418         emit1(elemcode);
   419         state.pop(1); // count
   420         state.push(arrayType);
   421     }
   423     /** Emit anewarray.
   424      */
   425     public void emitAnewarray(int od, Type arrayType) {
   426         emitop(anewarray);
   427         if (!alive) return;
   428         emit2(od);
   429         state.pop(1);
   430         state.push(arrayType);
   431     }
   433     /** Emit an invokeinterface instruction.
   434      */
   435     public void emitInvokeinterface(int meth, Type mtype) {
   436         int argsize = width(mtype.getParameterTypes());
   437         emitop(invokeinterface);
   438         if (!alive) return;
   439         emit2(meth);
   440         emit1(argsize + 1);
   441         emit1(0);
   442         state.pop(argsize + 1);
   443         state.push(mtype.getReturnType());
   444     }
   446     /** Emit an invokespecial instruction.
   447      */
   448     public void emitInvokespecial(int meth, Type mtype) {
   449         int argsize = width(mtype.getParameterTypes());
   450         emitop(invokespecial);
   451         if (!alive) return;
   452         emit2(meth);
   453         Symbol sym = (Symbol)pool.pool[meth];
   454         state.pop(argsize);
   455         if (sym.isConstructor())
   456             state.markInitialized((UninitializedType)state.peek());
   457         state.pop(1);
   458         state.push(mtype.getReturnType());
   459     }
   461     /** Emit an invokestatic instruction.
   462      */
   463     public void emitInvokestatic(int meth, Type mtype) {
   464         int argsize = width(mtype.getParameterTypes());
   465         emitop(invokestatic);
   466         if (!alive) return;
   467         emit2(meth);
   468         state.pop(argsize);
   469         state.push(mtype.getReturnType());
   470     }
   472     /** Emit an invokevirtual instruction.
   473      */
   474     public void emitInvokevirtual(int meth, Type mtype) {
   475         int argsize = width(mtype.getParameterTypes());
   476         emitop(invokevirtual);
   477         if (!alive) return;
   478         emit2(meth);
   479         state.pop(argsize + 1);
   480         state.push(mtype.getReturnType());
   481     }
   483     /** Emit an invokedynamic instruction.
   484      */
   485     public void emitInvokedynamic(int desc, Type mtype) {
   486         int argsize = width(mtype.getParameterTypes());
   487         emitop(invokedynamic);
   488         if (!alive) return;
   489         emit2(desc);
   490         emit2(0);
   491         state.pop(argsize);
   492         state.push(mtype.getReturnType());
   493     }
   495     /** Emit an opcode with no operand field.
   496      */
   497     public void emitop0(int op) {
   498         emitop(op);
   499         if (!alive) return;
   500         switch (op) {
   501         case aaload: {
   502             state.pop(1);// index
   503             Type a = state.stack[state.stacksize-1];
   504             state.pop(1);
   505             //sometimes 'null type' is treated as a one-dimensional array type
   506             //see Gen.visitLiteral - we should handle this case accordingly
   507             Type stackType = a.hasTag(BOT) ?
   508                 syms.objectType :
   509                 types.erasure(types.elemtype(a));
   510             state.push(stackType); }
   511             break;
   512         case goto_:
   513             markDead();
   514             break;
   515         case nop:
   516         case ineg:
   517         case lneg:
   518         case fneg:
   519         case dneg:
   520             break;
   521         case aconst_null:
   522             state.push(syms.botType);
   523             break;
   524         case iconst_m1:
   525         case iconst_0:
   526         case iconst_1:
   527         case iconst_2:
   528         case iconst_3:
   529         case iconst_4:
   530         case iconst_5:
   531         case iload_0:
   532         case iload_1:
   533         case iload_2:
   534         case iload_3:
   535             state.push(syms.intType);
   536             break;
   537         case lconst_0:
   538         case lconst_1:
   539         case lload_0:
   540         case lload_1:
   541         case lload_2:
   542         case lload_3:
   543             state.push(syms.longType);
   544             break;
   545         case fconst_0:
   546         case fconst_1:
   547         case fconst_2:
   548         case fload_0:
   549         case fload_1:
   550         case fload_2:
   551         case fload_3:
   552             state.push(syms.floatType);
   553             break;
   554         case dconst_0:
   555         case dconst_1:
   556         case dload_0:
   557         case dload_1:
   558         case dload_2:
   559         case dload_3:
   560             state.push(syms.doubleType);
   561             break;
   562         case aload_0:
   563             state.push(lvar[0].sym.type);
   564             break;
   565         case aload_1:
   566             state.push(lvar[1].sym.type);
   567             break;
   568         case aload_2:
   569             state.push(lvar[2].sym.type);
   570             break;
   571         case aload_3:
   572             state.push(lvar[3].sym.type);
   573             break;
   574         case iaload:
   575         case baload:
   576         case caload:
   577         case saload:
   578             state.pop(2);
   579             state.push(syms.intType);
   580             break;
   581         case laload:
   582             state.pop(2);
   583             state.push(syms.longType);
   584             break;
   585         case faload:
   586             state.pop(2);
   587             state.push(syms.floatType);
   588             break;
   589         case daload:
   590             state.pop(2);
   591             state.push(syms.doubleType);
   592             break;
   593         case istore_0:
   594         case istore_1:
   595         case istore_2:
   596         case istore_3:
   597         case fstore_0:
   598         case fstore_1:
   599         case fstore_2:
   600         case fstore_3:
   601         case astore_0:
   602         case astore_1:
   603         case astore_2:
   604         case astore_3:
   605         case pop:
   606         case lshr:
   607         case lshl:
   608         case lushr:
   609             state.pop(1);
   610             break;
   611         case areturn:
   612         case ireturn:
   613         case freturn:
   614             Assert.check(state.nlocks == 0);
   615             state.pop(1);
   616             markDead();
   617             break;
   618         case athrow:
   619             state.pop(1);
   620             markDead();
   621             break;
   622         case lstore_0:
   623         case lstore_1:
   624         case lstore_2:
   625         case lstore_3:
   626         case dstore_0:
   627         case dstore_1:
   628         case dstore_2:
   629         case dstore_3:
   630         case pop2:
   631             state.pop(2);
   632             break;
   633         case lreturn:
   634         case dreturn:
   635             Assert.check(state.nlocks == 0);
   636             state.pop(2);
   637             markDead();
   638             break;
   639         case dup:
   640             state.push(state.stack[state.stacksize-1]);
   641             break;
   642         case return_:
   643             Assert.check(state.nlocks == 0);
   644             markDead();
   645             break;
   646         case arraylength:
   647             state.pop(1);
   648             state.push(syms.intType);
   649             break;
   650         case isub:
   651         case iadd:
   652         case imul:
   653         case idiv:
   654         case imod:
   655         case ishl:
   656         case ishr:
   657         case iushr:
   658         case iand:
   659         case ior:
   660         case ixor:
   661             state.pop(1);
   662             // state.pop(1);
   663             // state.push(syms.intType);
   664             break;
   665         case aastore:
   666             state.pop(3);
   667             break;
   668         case land:
   669         case lor:
   670         case lxor:
   671         case lmod:
   672         case ldiv:
   673         case lmul:
   674         case lsub:
   675         case ladd:
   676             state.pop(2);
   677             break;
   678         case lcmp:
   679             state.pop(4);
   680             state.push(syms.intType);
   681             break;
   682         case l2i:
   683             state.pop(2);
   684             state.push(syms.intType);
   685             break;
   686         case i2l:
   687             state.pop(1);
   688             state.push(syms.longType);
   689             break;
   690         case i2f:
   691             state.pop(1);
   692             state.push(syms.floatType);
   693             break;
   694         case i2d:
   695             state.pop(1);
   696             state.push(syms.doubleType);
   697             break;
   698         case l2f:
   699             state.pop(2);
   700             state.push(syms.floatType);
   701             break;
   702         case l2d:
   703             state.pop(2);
   704             state.push(syms.doubleType);
   705             break;
   706         case f2i:
   707             state.pop(1);
   708             state.push(syms.intType);
   709             break;
   710         case f2l:
   711             state.pop(1);
   712             state.push(syms.longType);
   713             break;
   714         case f2d:
   715             state.pop(1);
   716             state.push(syms.doubleType);
   717             break;
   718         case d2i:
   719             state.pop(2);
   720             state.push(syms.intType);
   721             break;
   722         case d2l:
   723             state.pop(2);
   724             state.push(syms.longType);
   725             break;
   726         case d2f:
   727             state.pop(2);
   728             state.push(syms.floatType);
   729             break;
   730         case tableswitch:
   731         case lookupswitch:
   732             state.pop(1);
   733             // the caller is responsible for patching up the state
   734             break;
   735         case dup_x1: {
   736             Type val1 = state.pop1();
   737             Type val2 = state.pop1();
   738             state.push(val1);
   739             state.push(val2);
   740             state.push(val1);
   741             break;
   742         }
   743         case bastore:
   744             state.pop(3);
   745             break;
   746         case int2byte:
   747         case int2char:
   748         case int2short:
   749             break;
   750         case fmul:
   751         case fadd:
   752         case fsub:
   753         case fdiv:
   754         case fmod:
   755             state.pop(1);
   756             break;
   757         case castore:
   758         case iastore:
   759         case fastore:
   760         case sastore:
   761             state.pop(3);
   762             break;
   763         case lastore:
   764         case dastore:
   765             state.pop(4);
   766             break;
   767         case dup2:
   768             if (state.stack[state.stacksize-1] != null) {
   769                 Type value1 = state.pop1();
   770                 Type value2 = state.pop1();
   771                 state.push(value2);
   772                 state.push(value1);
   773                 state.push(value2);
   774                 state.push(value1);
   775             } else {
   776                 Type value = state.pop2();
   777                 state.push(value);
   778                 state.push(value);
   779             }
   780             break;
   781         case dup2_x1:
   782             if (state.stack[state.stacksize-1] != null) {
   783                 Type value1 = state.pop1();
   784                 Type value2 = state.pop1();
   785                 Type value3 = state.pop1();
   786                 state.push(value2);
   787                 state.push(value1);
   788                 state.push(value3);
   789                 state.push(value2);
   790                 state.push(value1);
   791             } else {
   792                 Type value1 = state.pop2();
   793                 Type value2 = state.pop1();
   794                 state.push(value1);
   795                 state.push(value2);
   796                 state.push(value1);
   797             }
   798             break;
   799         case dup2_x2:
   800             if (state.stack[state.stacksize-1] != null) {
   801                 Type value1 = state.pop1();
   802                 Type value2 = state.pop1();
   803                 if (state.stack[state.stacksize-1] != null) {
   804                     // form 1
   805                     Type value3 = state.pop1();
   806                     Type value4 = state.pop1();
   807                     state.push(value2);
   808                     state.push(value1);
   809                     state.push(value4);
   810                     state.push(value3);
   811                     state.push(value2);
   812                     state.push(value1);
   813                 } else {
   814                     // form 3
   815                     Type value3 = state.pop2();
   816                     state.push(value2);
   817                     state.push(value1);
   818                     state.push(value3);
   819                     state.push(value2);
   820                     state.push(value1);
   821                 }
   822             } else {
   823                 Type value1 = state.pop2();
   824                 if (state.stack[state.stacksize-1] != null) {
   825                     // form 2
   826                     Type value2 = state.pop1();
   827                     Type value3 = state.pop1();
   828                     state.push(value1);
   829                     state.push(value3);
   830                     state.push(value2);
   831                     state.push(value1);
   832                 } else {
   833                     // form 4
   834                     Type value2 = state.pop2();
   835                     state.push(value1);
   836                     state.push(value2);
   837                     state.push(value1);
   838                 }
   839             }
   840             break;
   841         case dup_x2: {
   842             Type value1 = state.pop1();
   843             if (state.stack[state.stacksize-1] != null) {
   844                 // form 1
   845                 Type value2 = state.pop1();
   846                 Type value3 = state.pop1();
   847                 state.push(value1);
   848                 state.push(value3);
   849                 state.push(value2);
   850                 state.push(value1);
   851             } else {
   852                 // form 2
   853                 Type value2 = state.pop2();
   854                 state.push(value1);
   855                 state.push(value2);
   856                 state.push(value1);
   857             }
   858         }
   859             break;
   860         case fcmpl:
   861         case fcmpg:
   862             state.pop(2);
   863             state.push(syms.intType);
   864             break;
   865         case dcmpl:
   866         case dcmpg:
   867             state.pop(4);
   868             state.push(syms.intType);
   869             break;
   870         case swap: {
   871             Type value1 = state.pop1();
   872             Type value2 = state.pop1();
   873             state.push(value1);
   874             state.push(value2);
   875             break;
   876         }
   877         case dadd:
   878         case dsub:
   879         case dmul:
   880         case ddiv:
   881         case dmod:
   882             state.pop(2);
   883             break;
   884         case ret:
   885             markDead();
   886             break;
   887         case wide:
   888             // must be handled by the caller.
   889             return;
   890         case monitorenter:
   891         case monitorexit:
   892             state.pop(1);
   893             break;
   895         default:
   896             throw new AssertionError(mnem(op));
   897         }
   898         postop();
   899     }
   901     /** Emit an opcode with a one-byte operand field.
   902      */
   903     public void emitop1(int op, int od) {
   904         emitop(op);
   905         if (!alive) return;
   906         emit1(od);
   907         switch (op) {
   908         case bipush:
   909             state.push(syms.intType);
   910             break;
   911         case ldc1:
   912             state.push(typeForPool(pool.pool[od]));
   913             break;
   914         default:
   915             throw new AssertionError(mnem(op));
   916         }
   917         postop();
   918     }
   920     /** The type of a constant pool entry. */
   921     private Type typeForPool(Object o) {
   922         if (o instanceof Integer) return syms.intType;
   923         if (o instanceof Float) return syms.floatType;
   924         if (o instanceof String) return syms.stringType;
   925         if (o instanceof Long) return syms.longType;
   926         if (o instanceof Double) return syms.doubleType;
   927         if (o instanceof ClassSymbol) return syms.classType;
   928         if (o instanceof Pool.MethodHandle) return syms.methodHandleType;
   929         if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type);
   930         if (o instanceof Type) {
   931             Type ty = ((Type)o).unannotatedType();
   933             if (ty instanceof Type.ArrayType) return syms.classType;
   934             if (ty instanceof Type.MethodType) return syms.methodTypeType;
   935         }
   936         throw new AssertionError("Invalid type of constant pool entry: " + o.getClass());
   937     }
   939     /** Emit an opcode with a one-byte operand field;
   940      *  widen if field does not fit in a byte.
   941      */
   942     public void emitop1w(int op, int od) {
   943         if (od > 0xFF) {
   944             emitop(wide);
   945             emitop(op);
   946             emit2(od);
   947         } else {
   948             emitop(op);
   949             emit1(od);
   950         }
   951         if (!alive) return;
   952         switch (op) {
   953         case iload:
   954             state.push(syms.intType);
   955             break;
   956         case lload:
   957             state.push(syms.longType);
   958             break;
   959         case fload:
   960             state.push(syms.floatType);
   961             break;
   962         case dload:
   963             state.push(syms.doubleType);
   964             break;
   965         case aload:
   966             state.push(lvar[od].sym.type);
   967             break;
   968         case lstore:
   969         case dstore:
   970             state.pop(2);
   971             break;
   972         case istore:
   973         case fstore:
   974         case astore:
   975             state.pop(1);
   976             break;
   977         case ret:
   978             markDead();
   979             break;
   980         default:
   981             throw new AssertionError(mnem(op));
   982         }
   983         postop();
   984     }
   986     /** Emit an opcode with two one-byte operand fields;
   987      *  widen if either field does not fit in a byte.
   988      */
   989     public void emitop1w(int op, int od1, int od2) {
   990         if (od1 > 0xFF || od2 < -128 || od2 > 127) {
   991             emitop(wide);
   992             emitop(op);
   993             emit2(od1);
   994             emit2(od2);
   995         } else {
   996             emitop(op);
   997             emit1(od1);
   998             emit1(od2);
   999         }
  1000         if (!alive) return;
  1001         switch (op) {
  1002         case iinc:
  1003             break;
  1004         default:
  1005             throw new AssertionError(mnem(op));
  1009     /** Emit an opcode with a two-byte operand field.
  1010      */
  1011     public void emitop2(int op, int od) {
  1012         emitop(op);
  1013         if (!alive) return;
  1014         emit2(od);
  1015         switch (op) {
  1016         case getstatic:
  1017             state.push(((Symbol)(pool.pool[od])).erasure(types));
  1018             break;
  1019         case putstatic:
  1020             state.pop(((Symbol)(pool.pool[od])).erasure(types));
  1021             break;
  1022         case new_:
  1023             Symbol sym;
  1024             if (pool.pool[od] instanceof UniqueType) {
  1025                 // Required by change in Gen.makeRef to allow
  1026                 // annotated types.
  1027                 // TODO: is this needed anywhere else?
  1028                 sym = ((UniqueType)(pool.pool[od])).type.tsym;
  1029             } else {
  1030                 sym = (Symbol)(pool.pool[od]);
  1032             state.push(uninitializedObject(sym.erasure(types), cp-3));
  1033             break;
  1034         case sipush:
  1035             state.push(syms.intType);
  1036             break;
  1037         case if_acmp_null:
  1038         case if_acmp_nonnull:
  1039         case ifeq:
  1040         case ifne:
  1041         case iflt:
  1042         case ifge:
  1043         case ifgt:
  1044         case ifle:
  1045             state.pop(1);
  1046             break;
  1047         case if_icmpeq:
  1048         case if_icmpne:
  1049         case if_icmplt:
  1050         case if_icmpge:
  1051         case if_icmpgt:
  1052         case if_icmple:
  1053         case if_acmpeq:
  1054         case if_acmpne:
  1055             state.pop(2);
  1056             break;
  1057         case goto_:
  1058             markDead();
  1059             break;
  1060         case putfield:
  1061             state.pop(((Symbol)(pool.pool[od])).erasure(types));
  1062             state.pop(1); // object ref
  1063             break;
  1064         case getfield:
  1065             state.pop(1); // object ref
  1066             state.push(((Symbol)(pool.pool[od])).erasure(types));
  1067             break;
  1068         case checkcast: {
  1069             state.pop(1); // object ref
  1070             Object o = pool.pool[od];
  1071             Type t = (o instanceof Symbol)
  1072                 ? ((Symbol)o).erasure(types)
  1073                 : types.erasure((((UniqueType)o).type));
  1074             state.push(t);
  1075             break; }
  1076         case ldc2w:
  1077             state.push(typeForPool(pool.pool[od]));
  1078             break;
  1079         case instanceof_:
  1080             state.pop(1);
  1081             state.push(syms.intType);
  1082             break;
  1083         case ldc2:
  1084             state.push(typeForPool(pool.pool[od]));
  1085             break;
  1086         case jsr:
  1087             break;
  1088         default:
  1089             throw new AssertionError(mnem(op));
  1091         // postop();
  1094     /** Emit an opcode with a four-byte operand field.
  1095      */
  1096     public void emitop4(int op, int od) {
  1097         emitop(op);
  1098         if (!alive) return;
  1099         emit4(od);
  1100         switch (op) {
  1101         case goto_w:
  1102             markDead();
  1103             break;
  1104         case jsr_w:
  1105             break;
  1106         default:
  1107             throw new AssertionError(mnem(op));
  1109         // postop();
  1112     /** Align code pointer to next `incr' boundary.
  1113      */
  1114     public void align(int incr) {
  1115         if (alive)
  1116             while (cp % incr != 0) emitop0(nop);
  1119     /** Place a byte into code at address pc.
  1120      *  Pre: {@literal pc + 1 <= cp }.
  1121      */
  1122     private void put1(int pc, int op) {
  1123         code[pc] = (byte)op;
  1126     /** Place two bytes into code at address pc.
  1127      *  Pre: {@literal pc + 2 <= cp }.
  1128      */
  1129     private void put2(int pc, int od) {
  1130         // pre: pc + 2 <= cp
  1131         put1(pc, od >> 8);
  1132         put1(pc+1, od);
  1135     /** Place four  bytes into code at address pc.
  1136      *  Pre: {@literal pc + 4 <= cp }.
  1137      */
  1138     public void put4(int pc, int od) {
  1139         // pre: pc + 4 <= cp
  1140         put1(pc  , od >> 24);
  1141         put1(pc+1, od >> 16);
  1142         put1(pc+2, od >> 8);
  1143         put1(pc+3, od);
  1146     /** Return code byte at position pc as an unsigned int.
  1147      */
  1148     private int get1(int pc) {
  1149         return code[pc] & 0xFF;
  1152     /** Return two code bytes at position pc as an unsigned int.
  1153      */
  1154     private int get2(int pc) {
  1155         return (get1(pc) << 8) | get1(pc+1);
  1158     /** Return four code bytes at position pc as an int.
  1159      */
  1160     public int get4(int pc) {
  1161         // pre: pc + 4 <= cp
  1162         return
  1163             (get1(pc) << 24) |
  1164             (get1(pc+1) << 16) |
  1165             (get1(pc+2) << 8) |
  1166             (get1(pc+3));
  1169     /** Is code generation currently enabled?
  1170      */
  1171     public boolean isAlive() {
  1172         return alive || pendingJumps != null;
  1175     /** Switch code generation on/off.
  1176      */
  1177     public void markDead() {
  1178         alive = false;
  1181     /** Declare an entry point; return current code pointer
  1182      */
  1183     public int entryPoint() {
  1184         int pc = curCP();
  1185         alive = true;
  1186         pendingStackMap = needStackMap;
  1187         return pc;
  1190     /** Declare an entry point with initial state;
  1191      *  return current code pointer
  1192      */
  1193     public int entryPoint(State state) {
  1194         int pc = curCP();
  1195         alive = true;
  1196         this.state = state.dup();
  1197         Assert.check(state.stacksize <= max_stack);
  1198         if (debugCode) System.err.println("entry point " + state);
  1199         pendingStackMap = needStackMap;
  1200         return pc;
  1203     /** Declare an entry point with initial state plus a pushed value;
  1204      *  return current code pointer
  1205      */
  1206     public int entryPoint(State state, Type pushed) {
  1207         int pc = curCP();
  1208         alive = true;
  1209         this.state = state.dup();
  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 end) {
  1957             if (isLastRangeInitialized()) {
  1958                 Range range = lastRange();
  1959                 if (range != null) {
  1960                     if (range.length == Character.MAX_VALUE) {
  1961                         range.length = end;
  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);
  2012     public void closeAliveRanges(JCTree tree) {
  2013         closeAliveRanges(tree, cp);
  2016     public void closeAliveRanges(JCTree tree, int closingCP) {
  2017         List<VarSymbol> locals = lvtRanges.getVars(meth, tree);
  2018         for (LocalVar localVar: lvar) {
  2019             for (VarSymbol aliveLocal : locals) {
  2020                 if (localVar == null) {
  2021                     return;
  2023                 if (localVar.sym == aliveLocal && localVar.lastRange() != null) {
  2024                     char length = (char)(closingCP - localVar.lastRange().start_pc);
  2025                     if (length > 0 && length < Character.MAX_VALUE) {
  2026                         localVar.closeRange(length);
  2033     void adjustAliveRanges(int oldCP, int delta) {
  2034         for (LocalVar localVar: lvar) {
  2035             if (localVar == null) {
  2036                 return;
  2038             for (LocalVar.Range range: localVar.aliveRanges) {
  2039                 if (range.closed() && range.start_pc + range.length >= oldCP) {
  2040                     range.length += delta;
  2046     /**
  2047      * Calculates the size of the LocalVariableTable.
  2048      */
  2049     public int getLVTSize() {
  2050         int result = varBufferSize;
  2051         for (int i = 0; i < varBufferSize; i++) {
  2052             LocalVar var = varBuffer[i];
  2053             result += var.aliveRanges.size() - 1;
  2055         return result;
  2058     /** Set the current variable defined state. */
  2059     public void setDefined(Bits newDefined) {
  2060         if (alive && newDefined != state.defined) {
  2061             Bits diff = new Bits(state.defined).xorSet(newDefined);
  2062             for (int adr = diff.nextBit(0);
  2063                  adr >= 0;
  2064                  adr = diff.nextBit(adr+1)) {
  2065                 if (adr >= nextreg)
  2066                     state.defined.excl(adr);
  2067                 else if (state.defined.isMember(adr))
  2068                     setUndefined(adr);
  2069                 else
  2070                     setDefined(adr);
  2075     /** Mark a register as being (possibly) defined. */
  2076     public void setDefined(int adr) {
  2077         LocalVar v = lvar[adr];
  2078         if (v == null) {
  2079             state.defined.excl(adr);
  2080         } else {
  2081             state.defined.incl(adr);
  2082             if (cp < Character.MAX_VALUE) {
  2083                 v.openRange((char)cp);
  2088     /** Mark a register as being undefined. */
  2089     public void setUndefined(int adr) {
  2090         state.defined.excl(adr);
  2091         if (adr < lvar.length &&
  2092             lvar[adr] != null &&
  2093             lvar[adr].isLastRangeInitialized()) {
  2094             LocalVar v = lvar[adr];
  2095             char length = (char)(curCP() - v.lastRange().start_pc);
  2096             if (length > 0 && length < Character.MAX_VALUE) {
  2097                 lvar[adr] = v.dup();
  2098                 v.closeRange(length);
  2099                 putVar(v);
  2100             } else {
  2101                 v.removeLastRange();
  2106     /** End the scope of a variable. */
  2107     private void endScope(int adr) {
  2108         LocalVar v = lvar[adr];
  2109         if (v != null) {
  2110             if (v.isLastRangeInitialized()) {
  2111                 char length = (char)(curCP() - v.lastRange().start_pc);
  2112                 if (length < Character.MAX_VALUE) {
  2113                     v.closeRange(length);
  2114                     putVar(v);
  2115                     fillLocalVarPosition(v);
  2118             /** the call to curCP() can implicitly adjust the current cp, if so
  2119              * the alive range of local variables may be modified. Thus we need
  2120              * all of them. For this reason assigning null to the given address
  2121              * should be the last action to do.
  2122              */
  2123             lvar[adr] = null;
  2125         state.defined.excl(adr);
  2128     private void fillLocalVarPosition(LocalVar lv) {
  2129         if (lv == null || lv.sym == null || !lv.sym.hasTypeAnnotations())
  2130             return;
  2131         for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
  2132             TypeAnnotationPosition p = ta.position;
  2133             LocalVar.Range widestRange = lv.getWidestRange();
  2134             p.lvarOffset = new int[] { (int)widestRange.start_pc };
  2135             p.lvarLength = new int[] { (int)widestRange.length };
  2136             p.lvarIndex = new int[] { (int)lv.reg };
  2137             p.isValidOffset = true;
  2141     // Method to be called after compressCatchTable to
  2142     // fill in the exception table index for type
  2143     // annotations on exception parameters.
  2144     public void fillExceptionParameterPositions() {
  2145         for (int i = 0; i < varBufferSize; ++i) {
  2146             LocalVar lv = varBuffer[i];
  2147             if (lv == null || lv.sym == null
  2148                     || !lv.sym.hasTypeAnnotations()
  2149                     || !lv.sym.isExceptionParameter())
  2150                 continue;
  2152             for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
  2153                 TypeAnnotationPosition p = ta.position;
  2154                 // At this point p.type_index contains the catch type index.
  2155                 // Use that index to determine the exception table index.
  2156                 // We can afterwards discard the type_index.
  2157                 // A TA position is shared for all type annotations in the
  2158                 // same location; updating one is enough.
  2159                 // Use -666 as a marker that the exception_index was already updated.
  2160                 if (p.type_index != -666) {
  2161                     p.exception_index = findExceptionIndex(p.type_index);
  2162                     p.type_index = -666;
  2168     private int findExceptionIndex(int catchType) {
  2169         if (catchType == Integer.MIN_VALUE) {
  2170             // We didn't set the catch type index correctly.
  2171             // This shouldn't happen.
  2172             // TODO: issue error?
  2173             return -1;
  2175         List<char[]> iter = catchInfo.toList();
  2176         int len = catchInfo.length();
  2177         for (int i = 0; i < len; ++i) {
  2178             char[] catchEntry = iter.head;
  2179             iter = iter.tail;
  2180             char ct = catchEntry[3];
  2181             if (catchType == ct) {
  2182                 return i;
  2185         return -1;
  2188     /** Put a live variable range into the buffer to be output to the
  2189      *  class file.
  2190      */
  2191     void putVar(LocalVar var) {
  2192         // Keep local variables if
  2193         // 1) we need them for debug information
  2194         // 2) it is an exception type and it contains type annotations
  2195         boolean keepLocalVariables = varDebugInfo ||
  2196             (var.sym.isExceptionParameter() && var.sym.hasTypeAnnotations());
  2197         if (!keepLocalVariables) return;
  2198         if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return;
  2199         if (varBuffer == null)
  2200             varBuffer = new LocalVar[20];
  2201         else
  2202             varBuffer = ArrayUtils.ensureCapacity(varBuffer, varBufferSize);
  2203         varBuffer[varBufferSize++] = var;
  2206     /** Previously live local variables, to be put into the variable table. */
  2207     LocalVar[] varBuffer;
  2208     int varBufferSize;
  2210     /** Create a new local variable address and return it.
  2211      */
  2212     private int newLocal(int typecode) {
  2213         int reg = nextreg;
  2214         int w = width(typecode);
  2215         nextreg = reg + w;
  2216         if (nextreg > max_locals) max_locals = nextreg;
  2217         return reg;
  2220     private int newLocal(Type type) {
  2221         return newLocal(typecode(type));
  2224     public int newLocal(VarSymbol v) {
  2225         int reg = v.adr = newLocal(v.erasure(types));
  2226         addLocalVar(v);
  2227         return reg;
  2230     /** Start a set of fresh registers.
  2231      */
  2232     public void newRegSegment() {
  2233         nextreg = max_locals;
  2236     /** End scopes of all variables with registers &ge; first.
  2237      */
  2238     public void endScopes(int first) {
  2239         int prevNextReg = nextreg;
  2240         nextreg = first;
  2241         for (int i = nextreg; i < prevNextReg; i++) endScope(i);
  2244 /**************************************************************************
  2245  * static tables
  2246  *************************************************************************/
  2248     public static String mnem(int opcode) {
  2249         return Mneumonics.mnem[opcode];
  2252     private static class Mneumonics {
  2253         private final static String[] mnem = new String[ByteCodeCount];
  2254         static {
  2255             mnem[nop] = "nop";
  2256             mnem[aconst_null] = "aconst_null";
  2257             mnem[iconst_m1] = "iconst_m1";
  2258             mnem[iconst_0] = "iconst_0";
  2259             mnem[iconst_1] = "iconst_1";
  2260             mnem[iconst_2] = "iconst_2";
  2261             mnem[iconst_3] = "iconst_3";
  2262             mnem[iconst_4] = "iconst_4";
  2263             mnem[iconst_5] = "iconst_5";
  2264             mnem[lconst_0] = "lconst_0";
  2265             mnem[lconst_1] = "lconst_1";
  2266             mnem[fconst_0] = "fconst_0";
  2267             mnem[fconst_1] = "fconst_1";
  2268             mnem[fconst_2] = "fconst_2";
  2269             mnem[dconst_0] = "dconst_0";
  2270             mnem[dconst_1] = "dconst_1";
  2271             mnem[bipush] = "bipush";
  2272             mnem[sipush] = "sipush";
  2273             mnem[ldc1] = "ldc1";
  2274             mnem[ldc2] = "ldc2";
  2275             mnem[ldc2w] = "ldc2w";
  2276             mnem[iload] = "iload";
  2277             mnem[lload] = "lload";
  2278             mnem[fload] = "fload";
  2279             mnem[dload] = "dload";
  2280             mnem[aload] = "aload";
  2281             mnem[iload_0] = "iload_0";
  2282             mnem[lload_0] = "lload_0";
  2283             mnem[fload_0] = "fload_0";
  2284             mnem[dload_0] = "dload_0";
  2285             mnem[aload_0] = "aload_0";
  2286             mnem[iload_1] = "iload_1";
  2287             mnem[lload_1] = "lload_1";
  2288             mnem[fload_1] = "fload_1";
  2289             mnem[dload_1] = "dload_1";
  2290             mnem[aload_1] = "aload_1";
  2291             mnem[iload_2] = "iload_2";
  2292             mnem[lload_2] = "lload_2";
  2293             mnem[fload_2] = "fload_2";
  2294             mnem[dload_2] = "dload_2";
  2295             mnem[aload_2] = "aload_2";
  2296             mnem[iload_3] = "iload_3";
  2297             mnem[lload_3] = "lload_3";
  2298             mnem[fload_3] = "fload_3";
  2299             mnem[dload_3] = "dload_3";
  2300             mnem[aload_3] = "aload_3";
  2301             mnem[iaload] = "iaload";
  2302             mnem[laload] = "laload";
  2303             mnem[faload] = "faload";
  2304             mnem[daload] = "daload";
  2305             mnem[aaload] = "aaload";
  2306             mnem[baload] = "baload";
  2307             mnem[caload] = "caload";
  2308             mnem[saload] = "saload";
  2309             mnem[istore] = "istore";
  2310             mnem[lstore] = "lstore";
  2311             mnem[fstore] = "fstore";
  2312             mnem[dstore] = "dstore";
  2313             mnem[astore] = "astore";
  2314             mnem[istore_0] = "istore_0";
  2315             mnem[lstore_0] = "lstore_0";
  2316             mnem[fstore_0] = "fstore_0";
  2317             mnem[dstore_0] = "dstore_0";
  2318             mnem[astore_0] = "astore_0";
  2319             mnem[istore_1] = "istore_1";
  2320             mnem[lstore_1] = "lstore_1";
  2321             mnem[fstore_1] = "fstore_1";
  2322             mnem[dstore_1] = "dstore_1";
  2323             mnem[astore_1] = "astore_1";
  2324             mnem[istore_2] = "istore_2";
  2325             mnem[lstore_2] = "lstore_2";
  2326             mnem[fstore_2] = "fstore_2";
  2327             mnem[dstore_2] = "dstore_2";
  2328             mnem[astore_2] = "astore_2";
  2329             mnem[istore_3] = "istore_3";
  2330             mnem[lstore_3] = "lstore_3";
  2331             mnem[fstore_3] = "fstore_3";
  2332             mnem[dstore_3] = "dstore_3";
  2333             mnem[astore_3] = "astore_3";
  2334             mnem[iastore] = "iastore";
  2335             mnem[lastore] = "lastore";
  2336             mnem[fastore] = "fastore";
  2337             mnem[dastore] = "dastore";
  2338             mnem[aastore] = "aastore";
  2339             mnem[bastore] = "bastore";
  2340             mnem[castore] = "castore";
  2341             mnem[sastore] = "sastore";
  2342             mnem[pop] = "pop";
  2343             mnem[pop2] = "pop2";
  2344             mnem[dup] = "dup";
  2345             mnem[dup_x1] = "dup_x1";
  2346             mnem[dup_x2] = "dup_x2";
  2347             mnem[dup2] = "dup2";
  2348             mnem[dup2_x1] = "dup2_x1";
  2349             mnem[dup2_x2] = "dup2_x2";
  2350             mnem[swap] = "swap";
  2351             mnem[iadd] = "iadd";
  2352             mnem[ladd] = "ladd";
  2353             mnem[fadd] = "fadd";
  2354             mnem[dadd] = "dadd";
  2355             mnem[isub] = "isub";
  2356             mnem[lsub] = "lsub";
  2357             mnem[fsub] = "fsub";
  2358             mnem[dsub] = "dsub";
  2359             mnem[imul] = "imul";
  2360             mnem[lmul] = "lmul";
  2361             mnem[fmul] = "fmul";
  2362             mnem[dmul] = "dmul";
  2363             mnem[idiv] = "idiv";
  2364             mnem[ldiv] = "ldiv";
  2365             mnem[fdiv] = "fdiv";
  2366             mnem[ddiv] = "ddiv";
  2367             mnem[imod] = "imod";
  2368             mnem[lmod] = "lmod";
  2369             mnem[fmod] = "fmod";
  2370             mnem[dmod] = "dmod";
  2371             mnem[ineg] = "ineg";
  2372             mnem[lneg] = "lneg";
  2373             mnem[fneg] = "fneg";
  2374             mnem[dneg] = "dneg";
  2375             mnem[ishl] = "ishl";
  2376             mnem[lshl] = "lshl";
  2377             mnem[ishr] = "ishr";
  2378             mnem[lshr] = "lshr";
  2379             mnem[iushr] = "iushr";
  2380             mnem[lushr] = "lushr";
  2381             mnem[iand] = "iand";
  2382             mnem[land] = "land";
  2383             mnem[ior] = "ior";
  2384             mnem[lor] = "lor";
  2385             mnem[ixor] = "ixor";
  2386             mnem[lxor] = "lxor";
  2387             mnem[iinc] = "iinc";
  2388             mnem[i2l] = "i2l";
  2389             mnem[i2f] = "i2f";
  2390             mnem[i2d] = "i2d";
  2391             mnem[l2i] = "l2i";
  2392             mnem[l2f] = "l2f";
  2393             mnem[l2d] = "l2d";
  2394             mnem[f2i] = "f2i";
  2395             mnem[f2l] = "f2l";
  2396             mnem[f2d] = "f2d";
  2397             mnem[d2i] = "d2i";
  2398             mnem[d2l] = "d2l";
  2399             mnem[d2f] = "d2f";
  2400             mnem[int2byte] = "int2byte";
  2401             mnem[int2char] = "int2char";
  2402             mnem[int2short] = "int2short";
  2403             mnem[lcmp] = "lcmp";
  2404             mnem[fcmpl] = "fcmpl";
  2405             mnem[fcmpg] = "fcmpg";
  2406             mnem[dcmpl] = "dcmpl";
  2407             mnem[dcmpg] = "dcmpg";
  2408             mnem[ifeq] = "ifeq";
  2409             mnem[ifne] = "ifne";
  2410             mnem[iflt] = "iflt";
  2411             mnem[ifge] = "ifge";
  2412             mnem[ifgt] = "ifgt";
  2413             mnem[ifle] = "ifle";
  2414             mnem[if_icmpeq] = "if_icmpeq";
  2415             mnem[if_icmpne] = "if_icmpne";
  2416             mnem[if_icmplt] = "if_icmplt";
  2417             mnem[if_icmpge] = "if_icmpge";
  2418             mnem[if_icmpgt] = "if_icmpgt";
  2419             mnem[if_icmple] = "if_icmple";
  2420             mnem[if_acmpeq] = "if_acmpeq";
  2421             mnem[if_acmpne] = "if_acmpne";
  2422             mnem[goto_] = "goto_";
  2423             mnem[jsr] = "jsr";
  2424             mnem[ret] = "ret";
  2425             mnem[tableswitch] = "tableswitch";
  2426             mnem[lookupswitch] = "lookupswitch";
  2427             mnem[ireturn] = "ireturn";
  2428             mnem[lreturn] = "lreturn";
  2429             mnem[freturn] = "freturn";
  2430             mnem[dreturn] = "dreturn";
  2431             mnem[areturn] = "areturn";
  2432             mnem[return_] = "return_";
  2433             mnem[getstatic] = "getstatic";
  2434             mnem[putstatic] = "putstatic";
  2435             mnem[getfield] = "getfield";
  2436             mnem[putfield] = "putfield";
  2437             mnem[invokevirtual] = "invokevirtual";
  2438             mnem[invokespecial] = "invokespecial";
  2439             mnem[invokestatic] = "invokestatic";
  2440             mnem[invokeinterface] = "invokeinterface";
  2441             mnem[invokedynamic] = "invokedynamic";
  2442             mnem[new_] = "new_";
  2443             mnem[newarray] = "newarray";
  2444             mnem[anewarray] = "anewarray";
  2445             mnem[arraylength] = "arraylength";
  2446             mnem[athrow] = "athrow";
  2447             mnem[checkcast] = "checkcast";
  2448             mnem[instanceof_] = "instanceof_";
  2449             mnem[monitorenter] = "monitorenter";
  2450             mnem[monitorexit] = "monitorexit";
  2451             mnem[wide] = "wide";
  2452             mnem[multianewarray] = "multianewarray";
  2453             mnem[if_acmp_null] = "if_acmp_null";
  2454             mnem[if_acmp_nonnull] = "if_acmp_nonnull";
  2455             mnem[goto_w] = "goto_w";
  2456             mnem[jsr_w] = "jsr_w";
  2457             mnem[breakpoint] = "breakpoint";

mercurial