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

Wed, 09 Oct 2013 13:09:31 +0200

author
jlahoda
date
Wed, 09 Oct 2013 13:09:31 +0200
changeset 2099
1b469fd31e35
parent 2047
5f915a0c9615
child 2178
cc80c03c41e4
permissions
-rw-r--r--

8025087: Annotation processing api returns default modifier for interface static method
Summary: ClassReader must not set Flags.DEFAULT for interface static methods
Reviewed-by: vromero, jjg

     1 /*
     2  * Copyright (c) 1999, 2013, 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         // N.B. this format is under consideration by the JSR 292 EG
   487         int argsize = width(mtype.getParameterTypes());
   488         int prevPos = pendingStatPos;
   489         try {
   490             //disable line number generation (we could have used 'emit1', that
   491             //bypasses stackmap generation - which is needed for indy calls)
   492             pendingStatPos = Position.NOPOS;
   493             emitop(invokedynamic);
   494         } finally {
   495             pendingStatPos = prevPos;
   496         }
   497         if (!alive) return;
   498         emit2(desc);
   499         emit2(0);
   500         state.pop(argsize);
   501         state.push(mtype.getReturnType());
   502     }
   504     /** Emit an opcode with no operand field.
   505      */
   506     public void emitop0(int op) {
   507         emitop(op);
   508         if (!alive) return;
   509         switch (op) {
   510         case aaload: {
   511             state.pop(1);// index
   512             Type a = state.stack[state.stacksize-1];
   513             state.pop(1);
   514             //sometimes 'null type' is treated as a one-dimensional array type
   515             //see Gen.visitLiteral - we should handle this case accordingly
   516             Type stackType = a.hasTag(BOT) ?
   517                 syms.objectType :
   518                 types.erasure(types.elemtype(a));
   519             state.push(stackType); }
   520             break;
   521         case goto_:
   522             markDead();
   523             break;
   524         case nop:
   525         case ineg:
   526         case lneg:
   527         case fneg:
   528         case dneg:
   529             break;
   530         case aconst_null:
   531             state.push(syms.botType);
   532             break;
   533         case iconst_m1:
   534         case iconst_0:
   535         case iconst_1:
   536         case iconst_2:
   537         case iconst_3:
   538         case iconst_4:
   539         case iconst_5:
   540         case iload_0:
   541         case iload_1:
   542         case iload_2:
   543         case iload_3:
   544             state.push(syms.intType);
   545             break;
   546         case lconst_0:
   547         case lconst_1:
   548         case lload_0:
   549         case lload_1:
   550         case lload_2:
   551         case lload_3:
   552             state.push(syms.longType);
   553             break;
   554         case fconst_0:
   555         case fconst_1:
   556         case fconst_2:
   557         case fload_0:
   558         case fload_1:
   559         case fload_2:
   560         case fload_3:
   561             state.push(syms.floatType);
   562             break;
   563         case dconst_0:
   564         case dconst_1:
   565         case dload_0:
   566         case dload_1:
   567         case dload_2:
   568         case dload_3:
   569             state.push(syms.doubleType);
   570             break;
   571         case aload_0:
   572             state.push(lvar[0].sym.type);
   573             break;
   574         case aload_1:
   575             state.push(lvar[1].sym.type);
   576             break;
   577         case aload_2:
   578             state.push(lvar[2].sym.type);
   579             break;
   580         case aload_3:
   581             state.push(lvar[3].sym.type);
   582             break;
   583         case iaload:
   584         case baload:
   585         case caload:
   586         case saload:
   587             state.pop(2);
   588             state.push(syms.intType);
   589             break;
   590         case laload:
   591             state.pop(2);
   592             state.push(syms.longType);
   593             break;
   594         case faload:
   595             state.pop(2);
   596             state.push(syms.floatType);
   597             break;
   598         case daload:
   599             state.pop(2);
   600             state.push(syms.doubleType);
   601             break;
   602         case istore_0:
   603         case istore_1:
   604         case istore_2:
   605         case istore_3:
   606         case fstore_0:
   607         case fstore_1:
   608         case fstore_2:
   609         case fstore_3:
   610         case astore_0:
   611         case astore_1:
   612         case astore_2:
   613         case astore_3:
   614         case pop:
   615         case lshr:
   616         case lshl:
   617         case lushr:
   618             state.pop(1);
   619             break;
   620         case areturn:
   621         case ireturn:
   622         case freturn:
   623             Assert.check(state.nlocks == 0);
   624             state.pop(1);
   625             markDead();
   626             break;
   627         case athrow:
   628             state.pop(1);
   629             markDead();
   630             break;
   631         case lstore_0:
   632         case lstore_1:
   633         case lstore_2:
   634         case lstore_3:
   635         case dstore_0:
   636         case dstore_1:
   637         case dstore_2:
   638         case dstore_3:
   639         case pop2:
   640             state.pop(2);
   641             break;
   642         case lreturn:
   643         case dreturn:
   644             Assert.check(state.nlocks == 0);
   645             state.pop(2);
   646             markDead();
   647             break;
   648         case dup:
   649             state.push(state.stack[state.stacksize-1]);
   650             break;
   651         case return_:
   652             Assert.check(state.nlocks == 0);
   653             markDead();
   654             break;
   655         case arraylength:
   656             state.pop(1);
   657             state.push(syms.intType);
   658             break;
   659         case isub:
   660         case iadd:
   661         case imul:
   662         case idiv:
   663         case imod:
   664         case ishl:
   665         case ishr:
   666         case iushr:
   667         case iand:
   668         case ior:
   669         case ixor:
   670             state.pop(1);
   671             // state.pop(1);
   672             // state.push(syms.intType);
   673             break;
   674         case aastore:
   675             state.pop(3);
   676             break;
   677         case land:
   678         case lor:
   679         case lxor:
   680         case lmod:
   681         case ldiv:
   682         case lmul:
   683         case lsub:
   684         case ladd:
   685             state.pop(2);
   686             break;
   687         case lcmp:
   688             state.pop(4);
   689             state.push(syms.intType);
   690             break;
   691         case l2i:
   692             state.pop(2);
   693             state.push(syms.intType);
   694             break;
   695         case i2l:
   696             state.pop(1);
   697             state.push(syms.longType);
   698             break;
   699         case i2f:
   700             state.pop(1);
   701             state.push(syms.floatType);
   702             break;
   703         case i2d:
   704             state.pop(1);
   705             state.push(syms.doubleType);
   706             break;
   707         case l2f:
   708             state.pop(2);
   709             state.push(syms.floatType);
   710             break;
   711         case l2d:
   712             state.pop(2);
   713             state.push(syms.doubleType);
   714             break;
   715         case f2i:
   716             state.pop(1);
   717             state.push(syms.intType);
   718             break;
   719         case f2l:
   720             state.pop(1);
   721             state.push(syms.longType);
   722             break;
   723         case f2d:
   724             state.pop(1);
   725             state.push(syms.doubleType);
   726             break;
   727         case d2i:
   728             state.pop(2);
   729             state.push(syms.intType);
   730             break;
   731         case d2l:
   732             state.pop(2);
   733             state.push(syms.longType);
   734             break;
   735         case d2f:
   736             state.pop(2);
   737             state.push(syms.floatType);
   738             break;
   739         case tableswitch:
   740         case lookupswitch:
   741             state.pop(1);
   742             // the caller is responsible for patching up the state
   743             break;
   744         case dup_x1: {
   745             Type val1 = state.pop1();
   746             Type val2 = state.pop1();
   747             state.push(val1);
   748             state.push(val2);
   749             state.push(val1);
   750             break;
   751         }
   752         case bastore:
   753             state.pop(3);
   754             break;
   755         case int2byte:
   756         case int2char:
   757         case int2short:
   758             break;
   759         case fmul:
   760         case fadd:
   761         case fsub:
   762         case fdiv:
   763         case fmod:
   764             state.pop(1);
   765             break;
   766         case castore:
   767         case iastore:
   768         case fastore:
   769         case sastore:
   770             state.pop(3);
   771             break;
   772         case lastore:
   773         case dastore:
   774             state.pop(4);
   775             break;
   776         case dup2:
   777             if (state.stack[state.stacksize-1] != null) {
   778                 Type value1 = state.pop1();
   779                 Type value2 = state.pop1();
   780                 state.push(value2);
   781                 state.push(value1);
   782                 state.push(value2);
   783                 state.push(value1);
   784             } else {
   785                 Type value = state.pop2();
   786                 state.push(value);
   787                 state.push(value);
   788             }
   789             break;
   790         case dup2_x1:
   791             if (state.stack[state.stacksize-1] != null) {
   792                 Type value1 = state.pop1();
   793                 Type value2 = state.pop1();
   794                 Type value3 = state.pop1();
   795                 state.push(value2);
   796                 state.push(value1);
   797                 state.push(value3);
   798                 state.push(value2);
   799                 state.push(value1);
   800             } else {
   801                 Type value1 = state.pop2();
   802                 Type value2 = state.pop1();
   803                 state.push(value1);
   804                 state.push(value2);
   805                 state.push(value1);
   806             }
   807             break;
   808         case dup2_x2:
   809             if (state.stack[state.stacksize-1] != null) {
   810                 Type value1 = state.pop1();
   811                 Type value2 = state.pop1();
   812                 if (state.stack[state.stacksize-1] != null) {
   813                     // form 1
   814                     Type value3 = state.pop1();
   815                     Type value4 = state.pop1();
   816                     state.push(value2);
   817                     state.push(value1);
   818                     state.push(value4);
   819                     state.push(value3);
   820                     state.push(value2);
   821                     state.push(value1);
   822                 } else {
   823                     // form 3
   824                     Type value3 = state.pop2();
   825                     state.push(value2);
   826                     state.push(value1);
   827                     state.push(value3);
   828                     state.push(value2);
   829                     state.push(value1);
   830                 }
   831             } else {
   832                 Type value1 = state.pop2();
   833                 if (state.stack[state.stacksize-1] != null) {
   834                     // form 2
   835                     Type value2 = state.pop1();
   836                     Type value3 = state.pop1();
   837                     state.push(value1);
   838                     state.push(value3);
   839                     state.push(value2);
   840                     state.push(value1);
   841                 } else {
   842                     // form 4
   843                     Type value2 = state.pop2();
   844                     state.push(value1);
   845                     state.push(value2);
   846                     state.push(value1);
   847                 }
   848             }
   849             break;
   850         case dup_x2: {
   851             Type value1 = state.pop1();
   852             if (state.stack[state.stacksize-1] != null) {
   853                 // form 1
   854                 Type value2 = state.pop1();
   855                 Type value3 = state.pop1();
   856                 state.push(value1);
   857                 state.push(value3);
   858                 state.push(value2);
   859                 state.push(value1);
   860             } else {
   861                 // form 2
   862                 Type value2 = state.pop2();
   863                 state.push(value1);
   864                 state.push(value2);
   865                 state.push(value1);
   866             }
   867         }
   868             break;
   869         case fcmpl:
   870         case fcmpg:
   871             state.pop(2);
   872             state.push(syms.intType);
   873             break;
   874         case dcmpl:
   875         case dcmpg:
   876             state.pop(4);
   877             state.push(syms.intType);
   878             break;
   879         case swap: {
   880             Type value1 = state.pop1();
   881             Type value2 = state.pop1();
   882             state.push(value1);
   883             state.push(value2);
   884             break;
   885         }
   886         case dadd:
   887         case dsub:
   888         case dmul:
   889         case ddiv:
   890         case dmod:
   891             state.pop(2);
   892             break;
   893         case ret:
   894             markDead();
   895             break;
   896         case wide:
   897             // must be handled by the caller.
   898             return;
   899         case monitorenter:
   900         case monitorexit:
   901             state.pop(1);
   902             break;
   904         default:
   905             throw new AssertionError(mnem(op));
   906         }
   907         postop();
   908     }
   910     /** Emit an opcode with a one-byte operand field.
   911      */
   912     public void emitop1(int op, int od) {
   913         emitop(op);
   914         if (!alive) return;
   915         emit1(od);
   916         switch (op) {
   917         case bipush:
   918             state.push(syms.intType);
   919             break;
   920         case ldc1:
   921             state.push(typeForPool(pool.pool[od]));
   922             break;
   923         default:
   924             throw new AssertionError(mnem(op));
   925         }
   926         postop();
   927     }
   929     /** The type of a constant pool entry. */
   930     private Type typeForPool(Object o) {
   931         if (o instanceof Integer) return syms.intType;
   932         if (o instanceof Float) return syms.floatType;
   933         if (o instanceof String) return syms.stringType;
   934         if (o instanceof Long) return syms.longType;
   935         if (o instanceof Double) return syms.doubleType;
   936         if (o instanceof ClassSymbol) return syms.classType;
   937         if (o instanceof Pool.MethodHandle) return syms.methodHandleType;
   938         if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type);
   939         if (o instanceof Type) {
   940             Type ty = ((Type)o).unannotatedType();
   942             if (ty instanceof Type.ArrayType) return syms.classType;
   943             if (ty instanceof Type.MethodType) return syms.methodTypeType;
   944         }
   945         throw new AssertionError("Invalid type of constant pool entry: " + o.getClass());
   946     }
   948     /** Emit an opcode with a one-byte operand field;
   949      *  widen if field does not fit in a byte.
   950      */
   951     public void emitop1w(int op, int od) {
   952         if (od > 0xFF) {
   953             emitop(wide);
   954             emitop(op);
   955             emit2(od);
   956         } else {
   957             emitop(op);
   958             emit1(od);
   959         }
   960         if (!alive) return;
   961         switch (op) {
   962         case iload:
   963             state.push(syms.intType);
   964             break;
   965         case lload:
   966             state.push(syms.longType);
   967             break;
   968         case fload:
   969             state.push(syms.floatType);
   970             break;
   971         case dload:
   972             state.push(syms.doubleType);
   973             break;
   974         case aload:
   975             state.push(lvar[od].sym.type);
   976             break;
   977         case lstore:
   978         case dstore:
   979             state.pop(2);
   980             break;
   981         case istore:
   982         case fstore:
   983         case astore:
   984             state.pop(1);
   985             break;
   986         case ret:
   987             markDead();
   988             break;
   989         default:
   990             throw new AssertionError(mnem(op));
   991         }
   992         postop();
   993     }
   995     /** Emit an opcode with two one-byte operand fields;
   996      *  widen if either field does not fit in a byte.
   997      */
   998     public void emitop1w(int op, int od1, int od2) {
   999         if (od1 > 0xFF || od2 < -128 || od2 > 127) {
  1000             emitop(wide);
  1001             emitop(op);
  1002             emit2(od1);
  1003             emit2(od2);
  1004         } else {
  1005             emitop(op);
  1006             emit1(od1);
  1007             emit1(od2);
  1009         if (!alive) return;
  1010         switch (op) {
  1011         case iinc:
  1012             break;
  1013         default:
  1014             throw new AssertionError(mnem(op));
  1018     /** Emit an opcode with a two-byte operand field.
  1019      */
  1020     public void emitop2(int op, int od) {
  1021         emitop(op);
  1022         if (!alive) return;
  1023         emit2(od);
  1024         switch (op) {
  1025         case getstatic:
  1026             state.push(((Symbol)(pool.pool[od])).erasure(types));
  1027             break;
  1028         case putstatic:
  1029             state.pop(((Symbol)(pool.pool[od])).erasure(types));
  1030             break;
  1031         case new_:
  1032             Symbol sym;
  1033             if (pool.pool[od] instanceof UniqueType) {
  1034                 // Required by change in Gen.makeRef to allow
  1035                 // annotated types.
  1036                 // TODO: is this needed anywhere else?
  1037                 sym = ((UniqueType)(pool.pool[od])).type.tsym;
  1038             } else {
  1039                 sym = (Symbol)(pool.pool[od]);
  1041             state.push(uninitializedObject(sym.erasure(types), cp-3));
  1042             break;
  1043         case sipush:
  1044             state.push(syms.intType);
  1045             break;
  1046         case if_acmp_null:
  1047         case if_acmp_nonnull:
  1048         case ifeq:
  1049         case ifne:
  1050         case iflt:
  1051         case ifge:
  1052         case ifgt:
  1053         case ifle:
  1054             state.pop(1);
  1055             break;
  1056         case if_icmpeq:
  1057         case if_icmpne:
  1058         case if_icmplt:
  1059         case if_icmpge:
  1060         case if_icmpgt:
  1061         case if_icmple:
  1062         case if_acmpeq:
  1063         case if_acmpne:
  1064             state.pop(2);
  1065             break;
  1066         case goto_:
  1067             markDead();
  1068             break;
  1069         case putfield:
  1070             state.pop(((Symbol)(pool.pool[od])).erasure(types));
  1071             state.pop(1); // object ref
  1072             break;
  1073         case getfield:
  1074             state.pop(1); // object ref
  1075             state.push(((Symbol)(pool.pool[od])).erasure(types));
  1076             break;
  1077         case checkcast: {
  1078             state.pop(1); // object ref
  1079             Object o = pool.pool[od];
  1080             Type t = (o instanceof Symbol)
  1081                 ? ((Symbol)o).erasure(types)
  1082                 : types.erasure((((UniqueType)o).type));
  1083             state.push(t);
  1084             break; }
  1085         case ldc2w:
  1086             state.push(typeForPool(pool.pool[od]));
  1087             break;
  1088         case instanceof_:
  1089             state.pop(1);
  1090             state.push(syms.intType);
  1091             break;
  1092         case ldc2:
  1093             state.push(typeForPool(pool.pool[od]));
  1094             break;
  1095         case jsr:
  1096             break;
  1097         default:
  1098             throw new AssertionError(mnem(op));
  1100         // postop();
  1103     /** Emit an opcode with a four-byte operand field.
  1104      */
  1105     public void emitop4(int op, int od) {
  1106         emitop(op);
  1107         if (!alive) return;
  1108         emit4(od);
  1109         switch (op) {
  1110         case goto_w:
  1111             markDead();
  1112             break;
  1113         case jsr_w:
  1114             break;
  1115         default:
  1116             throw new AssertionError(mnem(op));
  1118         // postop();
  1121     /** Align code pointer to next `incr' boundary.
  1122      */
  1123     public void align(int incr) {
  1124         if (alive)
  1125             while (cp % incr != 0) emitop0(nop);
  1128     /** Place a byte into code at address pc.
  1129      *  Pre: {@literal pc + 1 <= cp }.
  1130      */
  1131     private void put1(int pc, int op) {
  1132         code[pc] = (byte)op;
  1135     /** Place two bytes into code at address pc.
  1136      *  Pre: {@literal pc + 2 <= cp }.
  1137      */
  1138     private void put2(int pc, int od) {
  1139         // pre: pc + 2 <= cp
  1140         put1(pc, od >> 8);
  1141         put1(pc+1, od);
  1144     /** Place four  bytes into code at address pc.
  1145      *  Pre: {@literal pc + 4 <= cp }.
  1146      */
  1147     public void put4(int pc, int od) {
  1148         // pre: pc + 4 <= cp
  1149         put1(pc  , od >> 24);
  1150         put1(pc+1, od >> 16);
  1151         put1(pc+2, od >> 8);
  1152         put1(pc+3, od);
  1155     /** Return code byte at position pc as an unsigned int.
  1156      */
  1157     private int get1(int pc) {
  1158         return code[pc] & 0xFF;
  1161     /** Return two code bytes at position pc as an unsigned int.
  1162      */
  1163     private int get2(int pc) {
  1164         return (get1(pc) << 8) | get1(pc+1);
  1167     /** Return four code bytes at position pc as an int.
  1168      */
  1169     public int get4(int pc) {
  1170         // pre: pc + 4 <= cp
  1171         return
  1172             (get1(pc) << 24) |
  1173             (get1(pc+1) << 16) |
  1174             (get1(pc+2) << 8) |
  1175             (get1(pc+3));
  1178     /** Is code generation currently enabled?
  1179      */
  1180     public boolean isAlive() {
  1181         return alive || pendingJumps != null;
  1184     /** Switch code generation on/off.
  1185      */
  1186     public void markDead() {
  1187         alive = false;
  1190     /** Declare an entry point; return current code pointer
  1191      */
  1192     public int entryPoint() {
  1193         int pc = curCP();
  1194         alive = true;
  1195         pendingStackMap = needStackMap;
  1196         return pc;
  1199     /** Declare an entry point with initial state;
  1200      *  return current code pointer
  1201      */
  1202     public int entryPoint(State state) {
  1203         int pc = curCP();
  1204         alive = true;
  1205         this.state = state.dup();
  1206         Assert.check(state.stacksize <= max_stack);
  1207         if (debugCode) System.err.println("entry point " + state);
  1208         pendingStackMap = needStackMap;
  1209         return pc;
  1212     /** Declare an entry point with initial state plus a pushed value;
  1213      *  return current code pointer
  1214      */
  1215     public int entryPoint(State state, Type pushed) {
  1216         int pc = curCP();
  1217         alive = true;
  1218         this.state = state.dup();
  1219         Assert.check(state.stacksize <= max_stack);
  1220         this.state.push(pushed);
  1221         if (debugCode) System.err.println("entry point " + state);
  1222         pendingStackMap = needStackMap;
  1223         return pc;
  1227 /**************************************************************************
  1228  * Stack map generation
  1229  *************************************************************************/
  1231     /** An entry in the stack map. */
  1232     static class StackMapFrame {
  1233         int pc;
  1234         Type[] locals;
  1235         Type[] stack;
  1238     /** A buffer of cldc stack map entries. */
  1239     StackMapFrame[] stackMapBuffer = null;
  1241     /** A buffer of compressed StackMapTable entries. */
  1242     StackMapTableFrame[] stackMapTableBuffer = null;
  1243     int stackMapBufferSize = 0;
  1245     /** The last PC at which we generated a stack map. */
  1246     int lastStackMapPC = -1;
  1248     /** The last stack map frame in StackMapTable. */
  1249     StackMapFrame lastFrame = null;
  1251     /** The stack map frame before the last one. */
  1252     StackMapFrame frameBeforeLast = null;
  1254     /** Emit a stack map entry.  */
  1255     public void emitStackMap() {
  1256         int pc = curCP();
  1257         if (!needStackMap) return;
  1261         switch (stackMap) {
  1262             case CLDC:
  1263                 emitCLDCStackMap(pc, getLocalsSize());
  1264                 break;
  1265             case JSR202:
  1266                 emitStackMapFrame(pc, getLocalsSize());
  1267                 break;
  1268             default:
  1269                 throw new AssertionError("Should have chosen a stackmap format");
  1271         // DEBUG code follows
  1272         if (debugCode) state.dump(pc);
  1275     private int getLocalsSize() {
  1276         int nextLocal = 0;
  1277         for (int i=max_locals-1; i>=0; i--) {
  1278             if (state.defined.isMember(i) && lvar[i] != null) {
  1279                 nextLocal = i + width(lvar[i].sym.erasure(types));
  1280                 break;
  1283         return nextLocal;
  1286     /** Emit a CLDC stack map frame. */
  1287     void emitCLDCStackMap(int pc, int localsSize) {
  1288         if (lastStackMapPC == pc) {
  1289             // drop existing stackmap at this offset
  1290             stackMapBuffer[--stackMapBufferSize] = null;
  1292         lastStackMapPC = pc;
  1294         if (stackMapBuffer == null) {
  1295             stackMapBuffer = new StackMapFrame[20];
  1296         } else {
  1297             stackMapBuffer = ArrayUtils.ensureCapacity(stackMapBuffer, stackMapBufferSize);
  1299         StackMapFrame frame =
  1300             stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
  1301         frame.pc = pc;
  1303         frame.locals = new Type[localsSize];
  1304         for (int i=0; i<localsSize; i++) {
  1305             if (state.defined.isMember(i) && lvar[i] != null) {
  1306                 Type vtype = lvar[i].sym.type;
  1307                 if (!(vtype instanceof UninitializedType))
  1308                     vtype = types.erasure(vtype);
  1309                 frame.locals[i] = vtype;
  1312         frame.stack = new Type[state.stacksize];
  1313         for (int i=0; i<state.stacksize; i++)
  1314             frame.stack[i] = state.stack[i];
  1317     void emitStackMapFrame(int pc, int localsSize) {
  1318         if (lastFrame == null) {
  1319             // first frame
  1320             lastFrame = getInitialFrame();
  1321         } else if (lastFrame.pc == pc) {
  1322             // drop existing stackmap at this offset
  1323             stackMapTableBuffer[--stackMapBufferSize] = null;
  1324             lastFrame = frameBeforeLast;
  1325             frameBeforeLast = null;
  1328         StackMapFrame frame = new StackMapFrame();
  1329         frame.pc = pc;
  1331         int localCount = 0;
  1332         Type[] locals = new Type[localsSize];
  1333         for (int i=0; i<localsSize; i++, localCount++) {
  1334             if (state.defined.isMember(i) && lvar[i] != null) {
  1335                 Type vtype = lvar[i].sym.type;
  1336                 if (!(vtype instanceof UninitializedType))
  1337                     vtype = types.erasure(vtype);
  1338                 locals[i] = vtype;
  1339                 if (width(vtype) > 1) i++;
  1342         frame.locals = new Type[localCount];
  1343         for (int i=0, j=0; i<localsSize; i++, j++) {
  1344             Assert.check(j < localCount);
  1345             frame.locals[j] = locals[i];
  1346             if (width(locals[i]) > 1) i++;
  1349         int stackCount = 0;
  1350         for (int i=0; i<state.stacksize; i++) {
  1351             if (state.stack[i] != null) {
  1352                 stackCount++;
  1355         frame.stack = new Type[stackCount];
  1356         stackCount = 0;
  1357         for (int i=0; i<state.stacksize; i++) {
  1358             if (state.stack[i] != null) {
  1359                 frame.stack[stackCount++] = types.erasure(state.stack[i]);
  1363         if (stackMapTableBuffer == null) {
  1364             stackMapTableBuffer = new StackMapTableFrame[20];
  1365         } else {
  1366             stackMapTableBuffer = ArrayUtils.ensureCapacity(
  1367                                     stackMapTableBuffer,
  1368                                     stackMapBufferSize);
  1370         stackMapTableBuffer[stackMapBufferSize++] =
  1371                 StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
  1373         frameBeforeLast = lastFrame;
  1374         lastFrame = frame;
  1377     StackMapFrame getInitialFrame() {
  1378         StackMapFrame frame = new StackMapFrame();
  1379         List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
  1380         int len = arg_types.length();
  1381         int count = 0;
  1382         if (!meth.isStatic()) {
  1383             Type thisType = meth.owner.type;
  1384             frame.locals = new Type[len+1];
  1385             if (meth.isConstructor() && thisType != syms.objectType) {
  1386                 frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
  1387             } else {
  1388                 frame.locals[count++] = types.erasure(thisType);
  1390         } else {
  1391             frame.locals = new Type[len];
  1393         for (Type arg_type : arg_types) {
  1394             frame.locals[count++] = types.erasure(arg_type);
  1396         frame.pc = -1;
  1397         frame.stack = null;
  1398         return frame;
  1402 /**************************************************************************
  1403  * Operations having to do with jumps
  1404  *************************************************************************/
  1406     /** A chain represents a list of unresolved jumps. Jump locations
  1407      *  are sorted in decreasing order.
  1408      */
  1409     public static class Chain {
  1411         /** The position of the jump instruction.
  1412          */
  1413         public final int pc;
  1415         /** The machine state after the jump instruction.
  1416          *  Invariant: all elements of a chain list have the same stacksize
  1417          *  and compatible stack and register contents.
  1418          */
  1419         Code.State state;
  1421         /** The next jump in the list.
  1422          */
  1423         public final Chain next;
  1425         /** Construct a chain from its jump position, stacksize, previous
  1426          *  chain, and machine state.
  1427          */
  1428         public Chain(int pc, Chain next, Code.State state) {
  1429             this.pc = pc;
  1430             this.next = next;
  1431             this.state = state;
  1435     /** Negate a branch opcode.
  1436      */
  1437     public static int negate(int opcode) {
  1438         if (opcode == if_acmp_null) return if_acmp_nonnull;
  1439         else if (opcode == if_acmp_nonnull) return if_acmp_null;
  1440         else return ((opcode + 1) ^ 1) - 1;
  1443     /** Emit a jump instruction.
  1444      *  Return code pointer of instruction to be patched.
  1445      */
  1446     public int emitJump(int opcode) {
  1447         if (fatcode) {
  1448             if (opcode == goto_ || opcode == jsr) {
  1449                 emitop4(opcode + goto_w - goto_, 0);
  1450             } else {
  1451                 emitop2(negate(opcode), 8);
  1452                 emitop4(goto_w, 0);
  1453                 alive = true;
  1454                 pendingStackMap = needStackMap;
  1456             return cp - 5;
  1457         } else {
  1458             emitop2(opcode, 0);
  1459             return cp - 3;
  1463     /** Emit a branch with given opcode; return its chain.
  1464      *  branch differs from jump in that jsr is treated as no-op.
  1465      */
  1466     public Chain branch(int opcode) {
  1467         Chain result = null;
  1468         if (opcode == goto_) {
  1469             result = pendingJumps;
  1470             pendingJumps = null;
  1472         if (opcode != dontgoto && isAlive()) {
  1473             result = new Chain(emitJump(opcode),
  1474                                result,
  1475                                state.dup());
  1476             fixedPc = fatcode;
  1477             if (opcode == goto_) alive = false;
  1479         return result;
  1482     /** Resolve chain to point to given target.
  1483      */
  1484     public void resolve(Chain chain, int target) {
  1485         boolean changed = false;
  1486         State newState = state;
  1487         for (; chain != null; chain = chain.next) {
  1488             Assert.check(state != chain.state
  1489                     && (target > chain.pc || state.stacksize == 0));
  1490             if (target >= cp) {
  1491                 target = cp;
  1492             } else if (get1(target) == goto_) {
  1493                 if (fatcode) target = target + get4(target + 1);
  1494                 else target = target + get2(target + 1);
  1496             if (get1(chain.pc) == goto_ &&
  1497                 chain.pc + 3 == target && target == cp && !fixedPc) {
  1498                 // If goto the next instruction, the jump is not needed:
  1499                 // compact the code.
  1500                 if (varDebugInfo) {
  1501                     adjustAliveRanges(cp, -3);
  1503                 cp = cp - 3;
  1504                 target = target - 3;
  1505                 if (chain.next == null) {
  1506                     // This is the only jump to the target. Exit the loop
  1507                     // without setting new state. The code is reachable
  1508                     // from the instruction before goto_.
  1509                     alive = true;
  1510                     break;
  1512             } else {
  1513                 if (fatcode)
  1514                     put4(chain.pc + 1, target - chain.pc);
  1515                 else if (target - chain.pc < Short.MIN_VALUE ||
  1516                          target - chain.pc > Short.MAX_VALUE)
  1517                     fatcode = true;
  1518                 else
  1519                     put2(chain.pc + 1, target - chain.pc);
  1520                 Assert.check(!alive ||
  1521                     chain.state.stacksize == newState.stacksize &&
  1522                     chain.state.nlocks == newState.nlocks);
  1524             fixedPc = true;
  1525             if (cp == target) {
  1526                 changed = true;
  1527                 if (debugCode)
  1528                     System.err.println("resolving chain state=" + chain.state);
  1529                 if (alive) {
  1530                     newState = chain.state.join(newState);
  1531                 } else {
  1532                     newState = chain.state;
  1533                     alive = true;
  1537         Assert.check(!changed || state != newState);
  1538         if (state != newState) {
  1539             setDefined(newState.defined);
  1540             state = newState;
  1541             pendingStackMap = needStackMap;
  1545     /** Resolve chain to point to current code pointer.
  1546      */
  1547     public void resolve(Chain chain) {
  1548         Assert.check(
  1549             !alive ||
  1550             chain==null ||
  1551             state.stacksize == chain.state.stacksize &&
  1552             state.nlocks == chain.state.nlocks);
  1553         pendingJumps = mergeChains(chain, pendingJumps);
  1556     /** Resolve any pending jumps.
  1557      */
  1558     public void resolvePending() {
  1559         Chain x = pendingJumps;
  1560         pendingJumps = null;
  1561         resolve(x, cp);
  1564     /** Merge the jumps in of two chains into one.
  1565      */
  1566     public static Chain mergeChains(Chain chain1, Chain chain2) {
  1567         // recursive merge sort
  1568         if (chain2 == null) return chain1;
  1569         if (chain1 == null) return chain2;
  1570         Assert.check(
  1571             chain1.state.stacksize == chain2.state.stacksize &&
  1572             chain1.state.nlocks == chain2.state.nlocks);
  1573         if (chain1.pc < chain2.pc)
  1574             return new Chain(
  1575                 chain2.pc,
  1576                 mergeChains(chain1, chain2.next),
  1577                 chain2.state);
  1578         return new Chain(
  1579                 chain1.pc,
  1580                 mergeChains(chain1.next, chain2),
  1581                 chain1.state);
  1585 /* **************************************************************************
  1586  * Catch clauses
  1587  ****************************************************************************/
  1589     /** Add a catch clause to code.
  1590      */
  1591     public void addCatch(
  1592         char startPc, char endPc, char handlerPc, char catchType) {
  1593             catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
  1597     public void compressCatchTable() {
  1598         ListBuffer<char[]> compressedCatchInfo = new ListBuffer<>();
  1599         List<Integer> handlerPcs = List.nil();
  1600         for (char[] catchEntry : catchInfo) {
  1601             handlerPcs = handlerPcs.prepend((int)catchEntry[2]);
  1603         for (char[] catchEntry : catchInfo) {
  1604             int startpc = catchEntry[0];
  1605             int endpc = catchEntry[1];
  1606             if (startpc == endpc ||
  1607                     (startpc == (endpc - 1) &&
  1608                     handlerPcs.contains(startpc))) {
  1609                 continue;
  1610             } else {
  1611                 compressedCatchInfo.append(catchEntry);
  1614         catchInfo = compressedCatchInfo;
  1618 /* **************************************************************************
  1619  * Line numbers
  1620  ****************************************************************************/
  1622     /** Add a line number entry.
  1623      */
  1624     public void addLineNumber(char startPc, char lineNumber) {
  1625         if (lineDebugInfo) {
  1626             if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
  1627                 lineInfo = lineInfo.tail;
  1628             if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
  1629                 lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
  1633     /** Mark beginning of statement.
  1634      */
  1635     public void statBegin(int pos) {
  1636         if (pos != Position.NOPOS) {
  1637             pendingStatPos = pos;
  1641     /** Force stat begin eagerly
  1642      */
  1643     public void markStatBegin() {
  1644         if (alive && lineDebugInfo) {
  1645             int line = lineMap.getLineNumber(pendingStatPos);
  1646             char cp1 = (char)cp;
  1647             char line1 = (char)line;
  1648             if (cp1 == cp && line1 == line)
  1649                 addLineNumber(cp1, line1);
  1651         pendingStatPos = Position.NOPOS;
  1655 /* **************************************************************************
  1656  * Simulated VM machine state
  1657  ****************************************************************************/
  1659     class State implements Cloneable {
  1660         /** The set of registers containing values. */
  1661         Bits defined;
  1663         /** The (types of the) contents of the machine stack. */
  1664         Type[] stack;
  1666         /** The first stack position currently unused. */
  1667         int stacksize;
  1669         /** The numbers of registers containing locked monitors. */
  1670         int[] locks;
  1671         int nlocks;
  1673         State() {
  1674             defined = new Bits();
  1675             stack = new Type[16];
  1678         State dup() {
  1679             try {
  1680                 State state = (State)super.clone();
  1681                 state.defined = new Bits(defined);
  1682                 state.stack = stack.clone();
  1683                 if (locks != null) state.locks = locks.clone();
  1684                 if (debugCode) {
  1685                     System.err.println("duping state " + this);
  1686                     dump();
  1688                 return state;
  1689             } catch (CloneNotSupportedException ex) {
  1690                 throw new AssertionError(ex);
  1694         void lock(int register) {
  1695             if (locks == null) {
  1696                 locks = new int[20];
  1697             } else {
  1698                 locks = ArrayUtils.ensureCapacity(locks, nlocks);
  1700             locks[nlocks] = register;
  1701             nlocks++;
  1704         void unlock(int register) {
  1705             nlocks--;
  1706             Assert.check(locks[nlocks] == register);
  1707             locks[nlocks] = -1;
  1710         void push(Type t) {
  1711             if (debugCode) System.err.println("   pushing " + t);
  1712             switch (t.getTag()) {
  1713             case VOID:
  1714                 return;
  1715             case BYTE:
  1716             case CHAR:
  1717             case SHORT:
  1718             case BOOLEAN:
  1719                 t = syms.intType;
  1720                 break;
  1721             default:
  1722                 break;
  1724             stack = ArrayUtils.ensureCapacity(stack, stacksize+2);
  1725             stack[stacksize++] = t;
  1726             switch (width(t)) {
  1727             case 1:
  1728                 break;
  1729             case 2:
  1730                 stack[stacksize++] = null;
  1731                 break;
  1732             default:
  1733                 throw new AssertionError(t);
  1735             if (stacksize > max_stack)
  1736                 max_stack = stacksize;
  1739         Type pop1() {
  1740             if (debugCode) System.err.println("   popping " + 1);
  1741             stacksize--;
  1742             Type result = stack[stacksize];
  1743             stack[stacksize] = null;
  1744             Assert.check(result != null && width(result) == 1);
  1745             return result;
  1748         Type peek() {
  1749             return stack[stacksize-1];
  1752         Type pop2() {
  1753             if (debugCode) System.err.println("   popping " + 2);
  1754             stacksize -= 2;
  1755             Type result = stack[stacksize];
  1756             stack[stacksize] = null;
  1757             Assert.check(stack[stacksize+1] == null
  1758                     && result != null && width(result) == 2);
  1759             return result;
  1762         void pop(int n) {
  1763             if (debugCode) System.err.println("   popping " + n);
  1764             while (n > 0) {
  1765                 stack[--stacksize] = null;
  1766                 n--;
  1770         void pop(Type t) {
  1771             pop(width(t));
  1774         /** Force the top of the stack to be treated as this supertype
  1775          *  of its current type. */
  1776         void forceStackTop(Type t) {
  1777             if (!alive) return;
  1778             switch (t.getTag()) {
  1779             case CLASS:
  1780             case ARRAY:
  1781                 int width = width(t);
  1782                 Type old = stack[stacksize-width];
  1783                 Assert.check(types.isSubtype(types.erasure(old),
  1784                                        types.erasure(t)));
  1785                 stack[stacksize-width] = t;
  1786                 break;
  1787             default:
  1791         void markInitialized(UninitializedType old) {
  1792             Type newtype = old.initializedType();
  1793             for (int i=0; i<stacksize; i++)
  1794                 if (stack[i] == old) stack[i] = newtype;
  1795             for (int i=0; i<lvar.length; i++) {
  1796                 LocalVar lv = lvar[i];
  1797                 if (lv != null && lv.sym.type == old) {
  1798                     VarSymbol sym = lv.sym;
  1799                     sym = sym.clone(sym.owner);
  1800                     sym.type = newtype;
  1801                     LocalVar newlv = lvar[i] = new LocalVar(sym);
  1802                     newlv.aliveRanges = lv.aliveRanges;
  1807         State join(State other) {
  1808             defined.andSet(other.defined);
  1809             Assert.check(stacksize == other.stacksize
  1810                     && nlocks == other.nlocks);
  1811             for (int i=0; i<stacksize; ) {
  1812                 Type t = stack[i];
  1813                 Type tother = other.stack[i];
  1814                 Type result =
  1815                     t==tother ? t :
  1816                     types.isSubtype(t, tother) ? tother :
  1817                     types.isSubtype(tother, t) ? t :
  1818                     error();
  1819                 int w = width(result);
  1820                 stack[i] = result;
  1821                 if (w == 2) Assert.checkNull(stack[i+1]);
  1822                 i += w;
  1824             return this;
  1827         Type error() {
  1828             throw new AssertionError("inconsistent stack types at join point");
  1831         void dump() {
  1832             dump(-1);
  1835         void dump(int pc) {
  1836             System.err.print("stackMap for " + meth.owner + "." + meth);
  1837             if (pc == -1)
  1838                 System.out.println();
  1839             else
  1840                 System.out.println(" at " + pc);
  1841             System.err.println(" stack (from bottom):");
  1842             for (int i=0; i<stacksize; i++)
  1843                 System.err.println("  " + i + ": " + stack[i]);
  1845             int lastLocal = 0;
  1846             for (int i=max_locals-1; i>=0; i--) {
  1847                 if (defined.isMember(i)) {
  1848                     lastLocal = i;
  1849                     break;
  1852             if (lastLocal >= 0)
  1853                 System.err.println(" locals:");
  1854             for (int i=0; i<=lastLocal; i++) {
  1855                 System.err.print("  " + i + ": ");
  1856                 if (defined.isMember(i)) {
  1857                     LocalVar var = lvar[i];
  1858                     if (var == null) {
  1859                         System.err.println("(none)");
  1860                     } else if (var.sym == null)
  1861                         System.err.println("UNKNOWN!");
  1862                     else
  1863                         System.err.println("" + var.sym + " of type " +
  1864                                            var.sym.erasure(types));
  1865                 } else {
  1866                     System.err.println("undefined");
  1869             if (nlocks != 0) {
  1870                 System.err.print(" locks:");
  1871                 for (int i=0; i<nlocks; i++) {
  1872                     System.err.print(" " + locks[i]);
  1874                 System.err.println();
  1879     static final Type jsrReturnValue = new JCPrimitiveType(INT, null);
  1882 /* **************************************************************************
  1883  * Local variables
  1884  ****************************************************************************/
  1886     /** A live range of a local variable. */
  1887     static class LocalVar {
  1888         final VarSymbol sym;
  1889         final char reg;
  1891         class Range {
  1892             char start_pc = Character.MAX_VALUE;
  1893             char length = Character.MAX_VALUE;
  1895             Range() {}
  1897             Range(char start) {
  1898                 this.start_pc = start;
  1901             Range(char start, char length) {
  1902                 this.start_pc = start;
  1903                 this.length = length;
  1906             boolean closed() {
  1907                 return start_pc != Character.MAX_VALUE && length != Character.MAX_VALUE;
  1910             @Override
  1911             public String toString() {
  1912                 int currentStartPC = start_pc;
  1913                 int currentLength = length;
  1914                 return "startpc = " + currentStartPC + " length " + currentLength;
  1918         java.util.List<Range> aliveRanges = new java.util.ArrayList<>();
  1920         LocalVar(VarSymbol v) {
  1921             this.sym = v;
  1922             this.reg = (char)v.adr;
  1924         public LocalVar dup() {
  1925             return new LocalVar(sym);
  1928         Range firstRange() {
  1929             return aliveRanges.isEmpty() ? null : aliveRanges.get(0);
  1932         Range lastRange() {
  1933             return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
  1936         @Override
  1937         public String toString() {
  1938             if (aliveRanges == null) {
  1939                 return "empty local var";
  1941             StringBuilder sb = new StringBuilder().append(sym)
  1942                     .append(" in register ").append((int)reg).append(" \n");
  1943             for (Range r : aliveRanges) {
  1944                 sb.append(" starts at pc=").append(Integer.toString(((int)r.start_pc)))
  1945                     .append(" length=").append(Integer.toString(((int)r.length)))
  1946                     .append("\n");
  1948             return sb.toString();
  1951         public void openRange(char start) {
  1952             if (!hasOpenRange()) {
  1953                 aliveRanges.add(new Range(start));
  1957         public void closeRange(char end) {
  1958             if (isLastRangeInitialized()) {
  1959                 Range range = lastRange();
  1960                 if (range != null) {
  1961                     if (range.length == Character.MAX_VALUE) {
  1962                         range.length = end;
  1965             } else {
  1966                 if (!aliveRanges.isEmpty()) {
  1967                     aliveRanges.remove(aliveRanges.size() - 1);
  1972         public boolean hasOpenRange() {
  1973             if (aliveRanges.isEmpty()) {
  1974                 return false;
  1976             Range range = lastRange();
  1977             return range.length == Character.MAX_VALUE;
  1980         public boolean isLastRangeInitialized() {
  1981             if (aliveRanges.isEmpty()) {
  1982                 return false;
  1984             Range range = lastRange();
  1985             return range.start_pc != Character.MAX_VALUE;
  1988         public Range getWidestRange() {
  1989             if (aliveRanges.isEmpty()) {
  1990                 return new Range();
  1991             } else {
  1992                 Range firstRange = firstRange();
  1993                 Range lastRange = lastRange();
  1994                 char length = (char)(lastRange.length + (lastRange.start_pc - firstRange.start_pc));
  1995                 return new Range(firstRange.start_pc, length);
  1999     };
  2001     /** Local variables, indexed by register. */
  2002     LocalVar[] lvar;
  2004     /** Add a new local variable. */
  2005     private void addLocalVar(VarSymbol v) {
  2006         int adr = v.adr;
  2007         lvar = ArrayUtils.ensureCapacity(lvar, adr+1);
  2008         Assert.checkNull(lvar[adr]);
  2009         if (pendingJumps != null) {
  2010             resolvePending();
  2012         lvar[adr] = new LocalVar(v);
  2013         state.defined.excl(adr);
  2017     public void closeAliveRanges(JCTree tree) {
  2018         closeAliveRanges(tree, cp);
  2021     public void closeAliveRanges(JCTree tree, int closingCP) {
  2022         List<VarSymbol> locals = lvtRanges.getVars(meth, tree);
  2023         for (LocalVar localVar: lvar) {
  2024             for (VarSymbol aliveLocal : locals) {
  2025                 if (localVar == null) {
  2026                     return;
  2028                 if (localVar.sym == aliveLocal && localVar.lastRange() != null) {
  2029                     char length = (char)(closingCP - localVar.lastRange().start_pc);
  2030                     if (length > 0 && length < Character.MAX_VALUE) {
  2031                         localVar.closeRange(length);
  2038     void adjustAliveRanges(int oldCP, int delta) {
  2039         for (LocalVar localVar: lvar) {
  2040             if (localVar == null) {
  2041                 return;
  2043             for (LocalVar.Range range: localVar.aliveRanges) {
  2044                 if (range.closed() && range.start_pc + range.length >= oldCP) {
  2045                     range.length += delta;
  2051     /**
  2052      * Calculates the size of the LocalVariableTable.
  2053      */
  2054     public int getLVTSize() {
  2055         int result = varBufferSize;
  2056         for (int i = 0; i < varBufferSize; i++) {
  2057             LocalVar var = varBuffer[i];
  2058             result += var.aliveRanges.size() - 1;
  2060         return result;
  2063     /** Set the current variable defined state. */
  2064     public void setDefined(Bits newDefined) {
  2065         if (alive && newDefined != state.defined) {
  2066             Bits diff = new Bits(state.defined).xorSet(newDefined);
  2067             for (int adr = diff.nextBit(0);
  2068                  adr >= 0;
  2069                  adr = diff.nextBit(adr+1)) {
  2070                 if (adr >= nextreg)
  2071                     state.defined.excl(adr);
  2072                 else if (state.defined.isMember(adr))
  2073                     setUndefined(adr);
  2074                 else
  2075                     setDefined(adr);
  2080     /** Mark a register as being (possibly) defined. */
  2081     public void setDefined(int adr) {
  2082         LocalVar v = lvar[adr];
  2083         if (v == null) {
  2084             state.defined.excl(adr);
  2085         } else {
  2086             state.defined.incl(adr);
  2087             if (cp < Character.MAX_VALUE) {
  2088                 v.openRange((char)cp);
  2093     /** Mark a register as being undefined. */
  2094     public void setUndefined(int adr) {
  2095         state.defined.excl(adr);
  2096         if (adr < lvar.length &&
  2097             lvar[adr] != null &&
  2098             lvar[adr].isLastRangeInitialized()) {
  2099             LocalVar v = lvar[adr];
  2100             char length = (char)(curCP() - v.lastRange().start_pc);
  2101             if (length > 0 && length < Character.MAX_VALUE) {
  2102                 lvar[adr] = v.dup();
  2103                 v.closeRange(length);
  2104                 putVar(v);
  2105             } else {
  2106                 v.lastRange().start_pc = Character.MAX_VALUE;
  2111     /** End the scope of a variable. */
  2112     private void endScope(int adr) {
  2113         LocalVar v = lvar[adr];
  2114         if (v != null) {
  2115             lvar[adr] = null;
  2116             if (v.isLastRangeInitialized()) {
  2117                 char length = (char)(curCP() - v.lastRange().start_pc);
  2118                 if (length < Character.MAX_VALUE) {
  2119                     v.closeRange(length);
  2120                     putVar(v);
  2121                     fillLocalVarPosition(v);
  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         if (!varDebugInfo &&
  2196                 (!var.sym.isExceptionParameter() ||
  2197                 var.sym.hasTypeAnnotations())) 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