< prev index next >

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

Print this page

  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.jvm;
  27 
  28 import com.sun.tools.javac.code.*;
  29 import com.sun.tools.javac.code.Symbol.*;
  30 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  31 import com.sun.tools.javac.util.*;
  32 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  33 
  34 import java.util.function.ToIntBiFunction;
  35 import java.util.function.ToIntFunction;
  36 
  37 import static com.sun.tools.javac.code.TypeTag.BOT;
  38 import static com.sun.tools.javac.code.TypeTag.INT;
  39 import static com.sun.tools.javac.jvm.ByteCodes.*;
  40 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Class;
  41 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Double;
  42 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Fieldref;
  43 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Float;
  44 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Integer;
  45 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_InterfaceMethodref;
  46 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Long;
  47 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodHandle;
  48 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodType;
  49 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Methodref;
  50 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_String;
  51 import static com.sun.tools.javac.jvm.UninitializedType.*;
  52 import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
  53 import java.util.Arrays;
  54 
  55 /** An internal structure that corresponds to the code attribute of
  56  *  methods in a classfile. The class also provides some utility operations to
  57  *  generate bytecode instructions.
  58  *
  59  *  <p><b>This is NOT part of any supported API.
  60  *  If you write code that depends on this, you do so at your own risk.
  61  *  This code and its internal interfaces are subject to change or
  62  *  deletion without notice.</b>
  63  */
  64 public class Code {
  65 
  66     public final boolean debugCode;
  67     public final boolean needStackMap;
  68 
  69     public enum StackMapFormat {
  70         NONE,

 177     boolean pendingStackMap = false;
 178 
 179     /** The stack map format to be generated. */
 180     StackMapFormat stackMap;
 181 
 182     /** Switch: emit variable debug info.
 183      */
 184     boolean varDebugInfo;
 185 
 186     /** Switch: emit line number info.
 187      */
 188     boolean lineDebugInfo;
 189 
 190     /** Emit line number info if map supplied
 191      */
 192     Position.LineMap lineMap;
 193 
 194     final MethodSymbol meth;
 195 
 196     private int letExprStackPos = 0;

 197 
 198     /** Construct a code object, given the settings of the fatcode,
 199      *  debugging info switches and the CharacterRangeTable.
 200      */
 201     public Code(MethodSymbol meth,
 202                 boolean fatcode,
 203                 Position.LineMap lineMap,
 204                 boolean varDebugInfo,
 205                 StackMapFormat stackMap,
 206                 boolean debugCode,
 207                 CRTable crt,
 208                 Symtab syms,
 209                 Types types,
 210                 PoolWriter poolWriter) {

 211         this.meth = meth;
 212         this.fatcode = fatcode;
 213         this.lineMap = lineMap;
 214         this.lineDebugInfo = lineMap != null;
 215         this.varDebugInfo = varDebugInfo;
 216         this.crt = crt;
 217         this.syms = syms;
 218         this.types = types;
 219         this.poolWriter = poolWriter;
 220         this.debugCode = debugCode;
 221         this.stackMap = stackMap;
 222         switch (stackMap) {
 223         case CLDC:
 224         case JSR202:
 225             this.needStackMap = true;
 226             break;
 227         default:
 228             this.needStackMap = false;
 229         }
 230         state = new State();
 231         lvar = new LocalVar[20];

 232     }
 233 
 234 
 235 /* **************************************************************************
 236  * Typecodes & related stuff
 237  ****************************************************************************/
 238 
 239     /** Given a type, return its type code (used implicitly in the
 240      *  JVM architecture).
 241      */
 242     public static int typecode(Type type) {
 243         switch (type.getTag()) {
 244         case BYTE: return BYTEcode;
 245         case SHORT: return SHORTcode;
 246         case CHAR: return CHARcode;
 247         case INT: return INTcode;
 248         case LONG: return LONGcode;
 249         case FLOAT: return FLOATcode;
 250         case DOUBLE: return DOUBLEcode;
 251         case BOOLEAN: return BYTEcode;

 382             if (pendingStatPos != Position.NOPOS)
 383                 markStatBegin();
 384             if (pendingStackMap) {
 385                 pendingStackMap = false;
 386                 emitStackMap();
 387             }
 388             if (debugCode)
 389                 System.err.println("emit@" + cp + " stack=" +
 390                                    state.stacksize + ": " +
 391                                    mnem(op));
 392             emit1(op);
 393         }
 394     }
 395 
 396     void postop() {
 397         Assert.check(alive || isStatementStart());
 398     }
 399 
 400     /** Emit a ldc (or ldc_w) instruction, taking into account operand size
 401     */











 402     public void emitLdc(LoadableConstant constant) {
 403         int od = poolWriter.putConstant(constant);
 404         if (od <= 255) {
 405             emitop1(ldc1, od, constant);
 406         }
 407         else {
 408             emitop2(ldc2, od, constant);
 409         }
 410     }
 411 
 412     /** Emit a multinewarray instruction.
 413      */
 414     public void emitMultianewarray(int ndims, int type, Type arrayType) {
 415         emitop(multianewarray);
 416         if (!alive) return;
 417         emit2(type);
 418         emit1(ndims);
 419         state.pop(ndims);
 420         state.push(arrayType);
 421     }

 444      */
 445     public void emitInvokeinterface(Symbol member, Type mtype) {
 446         int argsize = width(mtype.getParameterTypes());
 447         emitop(invokeinterface);
 448         if (!alive) return;
 449         emit2(poolWriter.putMember(member));
 450         emit1(argsize + 1);
 451         emit1(0);
 452         state.pop(argsize + 1);
 453         state.push(mtype.getReturnType());
 454     }
 455 
 456     /** Emit an invokespecial instruction.
 457      */
 458     public void emitInvokespecial(Symbol member, Type mtype) {
 459         int argsize = width(mtype.getParameterTypes());
 460         emitop(invokespecial);
 461         if (!alive) return;
 462         emit2(poolWriter.putMember(member));
 463         state.pop(argsize);
 464         if (member.isConstructor())
 465             state.markInitialized((UninitializedType)state.peek());
 466         state.pop(1);
 467         state.push(mtype.getReturnType());
 468     }
 469 
 470     /** Emit an invokestatic instruction.
 471      */
 472     public void emitInvokestatic(Symbol member, Type mtype) {
 473         int argsize = width(mtype.getParameterTypes());
 474         emitop(invokestatic);
 475         if (!alive) return;
 476         emit2(poolWriter.putMember(member));
 477         state.pop(argsize);
 478         state.push(mtype.getReturnType());
 479     }
 480 
 481     /** Emit an invokevirtual instruction.
 482      */
 483     public void emitInvokevirtual(Symbol member, Type mtype) {
 484         int argsize = width(mtype.getParameterTypes());

1003         emitop2(op, od, constant);
1004     }
1005 
1006     public void emitop2(int op, int od) {
1007         emitop2(op, od, null);
1008     }
1009 
1010     public void emitop2(int op, int od, PoolConstant data) {
1011         emitop(op);
1012         if (!alive) return;
1013         emit2(od);
1014         switch (op) {
1015         case getstatic:
1016             state.push(((Symbol)data).erasure(types));
1017             break;
1018         case putstatic:
1019             state.pop(((Symbol)data).erasure(types));
1020             break;
1021         case new_: {
1022             Type t = (Type)data;
1023             state.push(uninitializedObject(t.tsym.erasure(types), cp-3));





1024             break;
1025         }
1026         case sipush:
1027             state.push(syms.intType);
1028             break;
1029         case if_acmp_null:
1030         case if_acmp_nonnull:
1031         case ifeq:
1032         case ifne:
1033         case iflt:
1034         case ifge:
1035         case ifgt:
1036         case ifle:
1037             state.pop(1);
1038             break;
1039         case if_icmpeq:
1040         case if_icmpne:
1041         case if_icmplt:
1042         case if_icmpge:
1043         case if_icmpgt:
1044         case if_icmple:
1045         case if_acmpeq:
1046         case if_acmpne:
1047             state.pop(2);
1048             break;
1049         case goto_:
1050             markDead();
1051             break;



1052         case putfield:
1053             state.pop(((Symbol)data).erasure(types));
1054             state.pop(1); // object ref
1055             break;
1056         case getfield:
1057             state.pop(1); // object ref
1058             state.push(((Symbol)data).erasure(types));
1059             break;
1060         case checkcast: {
1061             state.pop(1); // object ref
1062             Type t = types.erasure((Type)data);
1063             state.push(t);
1064             break; }
1065         case ldc2w:
1066             state.push(types.constantType((LoadableConstant)data));
1067             break;
1068         case instanceof_:
1069             state.pop(1);
1070             state.push(syms.intType);
1071             break;
1072         case ldc2:
1073             state.push(types.constantType((LoadableConstant)data));
1074             break;
1075         case jsr:
1076             break;
1077         default:
1078             throw new AssertionError(mnem(op));
1079         }
1080         // postop();
1081     }
1082 

1358         } else {
1359             stackMapTableBuffer = ArrayUtils.ensureCapacity(
1360                                     stackMapTableBuffer,
1361                                     stackMapBufferSize);
1362         }
1363         stackMapTableBuffer[stackMapBufferSize++] =
1364                 StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
1365 
1366         frameBeforeLast = lastFrame;
1367         lastFrame = frame;
1368     }
1369 
1370     StackMapFrame getInitialFrame() {
1371         StackMapFrame frame = new StackMapFrame();
1372         List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
1373         int len = arg_types.length();
1374         int count = 0;
1375         if (!meth.isStatic()) {
1376             Type thisType = meth.owner.type;
1377             frame.locals = new Type[len+1];
1378             if (meth.isConstructor() && thisType != syms.objectType) {
1379                 frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
1380             } else {
1381                 frame.locals[count++] = types.erasure(thisType);
1382             }
1383         } else {
1384             frame.locals = new Type[len];
1385         }
1386         for (Type arg_type : arg_types) {
1387             frame.locals[count++] = types.erasure(arg_type);
1388         }
1389         frame.pc = -1;
1390         frame.stack = null;
1391         return frame;
1392     }
1393 
1394 
1395 /**************************************************************************
1396  * Operations having to do with jumps
1397  *************************************************************************/
1398 

1756             if (debugCode) System.err.println("   popping " + n);
1757             while (n > 0) {
1758                 stack[--stacksize] = null;
1759                 n--;
1760             }
1761         }
1762 
1763         void pop(Type t) {
1764             pop(width(t));
1765         }
1766 
1767         /** Force the top of the stack to be treated as this supertype
1768          *  of its current type. */
1769         void forceStackTop(Type t) {
1770             if (!alive) return;
1771             switch (t.getTag()) {
1772             case CLASS:
1773             case ARRAY:
1774                 int width = width(t);
1775                 Type old = stack[stacksize-width];
1776                 Assert.check(types.isSubtype(types.erasure(old),
1777                                        types.erasure(t)));




1778                 stack[stacksize-width] = t;
1779                 break;
1780             default:
1781             }
1782         }
1783 
1784         void markInitialized(UninitializedType old) {
1785             Type newtype = old.initializedType();
1786             for (int i=0; i<stacksize; i++) {
1787                 if (stack[i] == old) stack[i] = newtype;
1788             }
1789             for (int i=0; i<lvar.length; i++) {
1790                 LocalVar lv = lvar[i];
1791                 if (lv != null && lv.sym.type == old) {
1792                     VarSymbol sym = lv.sym;
1793                     sym = sym.clone(sym.owner);
1794                     sym.type = newtype;
1795                     LocalVar newlv = lvar[i] = new LocalVar(sym);
1796                     newlv.aliveRanges = lv.aliveRanges;
1797                 }

2433             mnem[invokespecial] = "invokespecial";
2434             mnem[invokestatic] = "invokestatic";
2435             mnem[invokeinterface] = "invokeinterface";
2436             mnem[invokedynamic] = "invokedynamic";
2437             mnem[new_] = "new_";
2438             mnem[newarray] = "newarray";
2439             mnem[anewarray] = "anewarray";
2440             mnem[arraylength] = "arraylength";
2441             mnem[athrow] = "athrow";
2442             mnem[checkcast] = "checkcast";
2443             mnem[instanceof_] = "instanceof_";
2444             mnem[monitorenter] = "monitorenter";
2445             mnem[monitorexit] = "monitorexit";
2446             mnem[wide] = "wide";
2447             mnem[multianewarray] = "multianewarray";
2448             mnem[if_acmp_null] = "if_acmp_null";
2449             mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2450             mnem[goto_w] = "goto_w";
2451             mnem[jsr_w] = "jsr_w";
2452             mnem[breakpoint] = "breakpoint";


2453         }
2454     }
2455 }

  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.jvm;
  27 
  28 import com.sun.tools.javac.code.*;
  29 import com.sun.tools.javac.code.Symbol.*;
  30 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  31 import com.sun.tools.javac.util.*;
  32 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  33 
  34 import java.util.function.ToIntBiFunction;

  35 
  36 import static com.sun.tools.javac.code.TypeTag.BOT;
  37 import static com.sun.tools.javac.code.TypeTag.INT;
  38 import static com.sun.tools.javac.jvm.ByteCodes.*;











  39 import static com.sun.tools.javac.jvm.UninitializedType.*;
  40 import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
  41 import java.util.Arrays;
  42 
  43 /** An internal structure that corresponds to the code attribute of
  44  *  methods in a classfile. The class also provides some utility operations to
  45  *  generate bytecode instructions.
  46  *
  47  *  <p><b>This is NOT part of any supported API.
  48  *  If you write code that depends on this, you do so at your own risk.
  49  *  This code and its internal interfaces are subject to change or
  50  *  deletion without notice.</b>
  51  */
  52 public class Code {
  53 
  54     public final boolean debugCode;
  55     public final boolean needStackMap;
  56 
  57     public enum StackMapFormat {
  58         NONE,

 165     boolean pendingStackMap = false;
 166 
 167     /** The stack map format to be generated. */
 168     StackMapFormat stackMap;
 169 
 170     /** Switch: emit variable debug info.
 171      */
 172     boolean varDebugInfo;
 173 
 174     /** Switch: emit line number info.
 175      */
 176     boolean lineDebugInfo;
 177 
 178     /** Emit line number info if map supplied
 179      */
 180     Position.LineMap lineMap;
 181 
 182     final MethodSymbol meth;
 183 
 184     private int letExprStackPos = 0;
 185     private boolean allowPrimitiveClasses;
 186 
 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                 PoolWriter poolWriter,
 200                 boolean allowPrimitiveClasses) {
 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.poolWriter = poolWriter;
 210         this.debugCode = debugCode;
 211         this.stackMap = stackMap;
 212         switch (stackMap) {
 213         case CLDC:
 214         case JSR202:
 215             this.needStackMap = true;
 216             break;
 217         default:
 218             this.needStackMap = false;
 219         }
 220         state = new State();
 221         lvar = new LocalVar[20];
 222         this.allowPrimitiveClasses = allowPrimitiveClasses;
 223     }
 224 
 225 
 226 /* **************************************************************************
 227  * Typecodes & related stuff
 228  ****************************************************************************/
 229 
 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;

 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     }
 386 
 387     void postop() {
 388         Assert.check(alive || isStatementStart());
 389     }
 390 
 391     /** Emit a ldc (or ldc_w) instruction, taking into account operand size
 392     */
 393     public void emitLdc(LoadableConstant constant, int od) {
 394         if (od <= 255) {
 395             emitop1(ldc1, od, constant);
 396         }
 397         else {
 398             emitop2(ldc2, od, constant);
 399         }
 400     }
 401 
 402     /** Emit a ldc (or ldc_w) instruction, taking into account operand size
 403      */
 404     public void emitLdc(LoadableConstant constant) {
 405         int od = poolWriter.putConstant(constant);
 406         if (od <= 255) {
 407             emitop1(ldc1, od, constant);
 408         }
 409         else {
 410             emitop2(ldc2, od, constant);
 411         }
 412     }
 413 
 414     /** Emit a multinewarray instruction.
 415      */
 416     public void emitMultianewarray(int ndims, int type, Type arrayType) {
 417         emitop(multianewarray);
 418         if (!alive) return;
 419         emit2(type);
 420         emit1(ndims);
 421         state.pop(ndims);
 422         state.push(arrayType);
 423     }

 446      */
 447     public void emitInvokeinterface(Symbol member, Type mtype) {
 448         int argsize = width(mtype.getParameterTypes());
 449         emitop(invokeinterface);
 450         if (!alive) return;
 451         emit2(poolWriter.putMember(member));
 452         emit1(argsize + 1);
 453         emit1(0);
 454         state.pop(argsize + 1);
 455         state.push(mtype.getReturnType());
 456     }
 457 
 458     /** Emit an invokespecial instruction.
 459      */
 460     public void emitInvokespecial(Symbol member, Type mtype) {
 461         int argsize = width(mtype.getParameterTypes());
 462         emitop(invokespecial);
 463         if (!alive) return;
 464         emit2(poolWriter.putMember(member));
 465         state.pop(argsize);
 466         if (member.isInitOrVNew())
 467             state.markInitialized((UninitializedType)state.peek());
 468         state.pop(1);
 469         state.push(mtype.getReturnType());
 470     }
 471 
 472     /** Emit an invokestatic instruction.
 473      */
 474     public void emitInvokestatic(Symbol member, Type mtype) {
 475         int argsize = width(mtype.getParameterTypes());
 476         emitop(invokestatic);
 477         if (!alive) return;
 478         emit2(poolWriter.putMember(member));
 479         state.pop(argsize);
 480         state.push(mtype.getReturnType());
 481     }
 482 
 483     /** Emit an invokevirtual instruction.
 484      */
 485     public void emitInvokevirtual(Symbol member, Type mtype) {
 486         int argsize = width(mtype.getParameterTypes());

1005         emitop2(op, od, constant);
1006     }
1007 
1008     public void emitop2(int op, int od) {
1009         emitop2(op, od, null);
1010     }
1011 
1012     public void emitop2(int op, int od, PoolConstant data) {
1013         emitop(op);
1014         if (!alive) return;
1015         emit2(od);
1016         switch (op) {
1017         case getstatic:
1018             state.push(((Symbol)data).erasure(types));
1019             break;
1020         case putstatic:
1021             state.pop(((Symbol)data).erasure(types));
1022             break;
1023         case new_: {
1024             Type t = (Type)data;
1025             state.push(uninitializedObject(t.tsym.erasure(types), cp - 3));
1026             break;
1027         }
1028         case aconst_init: {
1029             Type t = (Type)data;
1030             state.push(t.tsym.erasure(types));
1031             break;
1032         }
1033         case sipush:
1034             state.push(syms.intType);
1035             break;
1036         case if_acmp_null:
1037         case if_acmp_nonnull:
1038         case ifeq:
1039         case ifne:
1040         case iflt:
1041         case ifge:
1042         case ifgt:
1043         case ifle:
1044             state.pop(1);
1045             break;
1046         case if_icmpeq:
1047         case if_icmpne:
1048         case if_icmplt:
1049         case if_icmpge:
1050         case if_icmpgt:
1051         case if_icmple:
1052         case if_acmpeq:
1053         case if_acmpne:
1054             state.pop(2);
1055             break;
1056         case goto_:
1057             markDead();
1058             break;
1059         case withfield:
1060             state.pop(((Symbol)data).erasure(types));
1061             break;
1062         case putfield:
1063             state.pop(((Symbol)data).erasure(types));
1064             state.pop(1); // object ref
1065             break;
1066         case getfield:
1067             state.pop(1); // object ref
1068             state.push(((Symbol)data).erasure(types));
1069             break;
1070         case checkcast: {
1071             state.pop(1); // object ref
1072             Type t = types.erasure(data instanceof  ConstantPoolQType ? ((ConstantPoolQType)data).type: (Type)data);
1073             state.push(t);
1074             break; }
1075         case ldc2w:
1076             state.push(types.constantType((LoadableConstant)data));
1077             break;
1078         case instanceof_:
1079             state.pop(1);
1080             state.push(syms.intType);
1081             break;
1082         case ldc2:
1083             state.push(types.constantType((LoadableConstant)data));
1084             break;
1085         case jsr:
1086             break;
1087         default:
1088             throw new AssertionError(mnem(op));
1089         }
1090         // postop();
1091     }
1092 

1368         } else {
1369             stackMapTableBuffer = ArrayUtils.ensureCapacity(
1370                                     stackMapTableBuffer,
1371                                     stackMapBufferSize);
1372         }
1373         stackMapTableBuffer[stackMapBufferSize++] =
1374                 StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
1375 
1376         frameBeforeLast = lastFrame;
1377         lastFrame = frame;
1378     }
1379 
1380     StackMapFrame getInitialFrame() {
1381         StackMapFrame frame = new StackMapFrame();
1382         List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
1383         int len = arg_types.length();
1384         int count = 0;
1385         if (!meth.isStatic()) {
1386             Type thisType = meth.owner.type;
1387             frame.locals = new Type[len+1];
1388             if (meth.isInitOrVNew() && thisType != syms.objectType) {
1389                 frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
1390             } else {
1391                 frame.locals[count++] = types.erasure(thisType);
1392             }
1393         } else {
1394             frame.locals = new Type[len];
1395         }
1396         for (Type arg_type : arg_types) {
1397             frame.locals[count++] = types.erasure(arg_type);
1398         }
1399         frame.pc = -1;
1400         frame.stack = null;
1401         return frame;
1402     }
1403 
1404 
1405 /**************************************************************************
1406  * Operations having to do with jumps
1407  *************************************************************************/
1408 

1766             if (debugCode) System.err.println("   popping " + n);
1767             while (n > 0) {
1768                 stack[--stacksize] = null;
1769                 n--;
1770             }
1771         }
1772 
1773         void pop(Type t) {
1774             pop(width(t));
1775         }
1776 
1777         /** Force the top of the stack to be treated as this supertype
1778          *  of its current type. */
1779         void forceStackTop(Type t) {
1780             if (!alive) return;
1781             switch (t.getTag()) {
1782             case CLASS:
1783             case ARRAY:
1784                 int width = width(t);
1785                 Type old = stack[stacksize-width];
1786                 if (!allowPrimitiveClasses) {
1787                     Assert.check(types.isSubtype(types.erasure(old), types.erasure(t)));
1788                 } else {
1789                     Assert.check(types.isSubtype(types.erasure(old), types.erasure(t)) ||
1790                             (old.isPrimitiveClass() != t.isPrimitiveClass() && types.isConvertible(types.erasure(old), types.erasure(t))));
1791                 }
1792                 stack[stacksize-width] = t;
1793                 break;
1794             default:
1795             }
1796         }
1797 
1798         void markInitialized(UninitializedType old) {
1799             Type newtype = old.initializedType();
1800             for (int i=0; i<stacksize; i++) {
1801                 if (stack[i] == old) stack[i] = newtype;
1802             }
1803             for (int i=0; i<lvar.length; i++) {
1804                 LocalVar lv = lvar[i];
1805                 if (lv != null && lv.sym.type == old) {
1806                     VarSymbol sym = lv.sym;
1807                     sym = sym.clone(sym.owner);
1808                     sym.type = newtype;
1809                     LocalVar newlv = lvar[i] = new LocalVar(sym);
1810                     newlv.aliveRanges = lv.aliveRanges;
1811                 }

2447             mnem[invokespecial] = "invokespecial";
2448             mnem[invokestatic] = "invokestatic";
2449             mnem[invokeinterface] = "invokeinterface";
2450             mnem[invokedynamic] = "invokedynamic";
2451             mnem[new_] = "new_";
2452             mnem[newarray] = "newarray";
2453             mnem[anewarray] = "anewarray";
2454             mnem[arraylength] = "arraylength";
2455             mnem[athrow] = "athrow";
2456             mnem[checkcast] = "checkcast";
2457             mnem[instanceof_] = "instanceof_";
2458             mnem[monitorenter] = "monitorenter";
2459             mnem[monitorexit] = "monitorexit";
2460             mnem[wide] = "wide";
2461             mnem[multianewarray] = "multianewarray";
2462             mnem[if_acmp_null] = "if_acmp_null";
2463             mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2464             mnem[goto_w] = "goto_w";
2465             mnem[jsr_w] = "jsr_w";
2466             mnem[breakpoint] = "breakpoint";
2467             mnem[aconst_init] = "aconst_init";
2468             mnem[withfield] = "withfield";
2469         }
2470     }
2471 }
< prev index next >