< prev index next >

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

Print this page

        

*** 25,55 **** package com.sun.tools.javac.jvm; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; - import java.util.function.ToIntBiFunction; - import java.util.function.ToIntFunction; - import static com.sun.tools.javac.code.TypeTag.BOT; import static com.sun.tools.javac.code.TypeTag.INT; import static com.sun.tools.javac.jvm.ByteCodes.*; - import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Class; - import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Double; - import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Fieldref; - import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Float; - import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Integer; - import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_InterfaceMethodref; - import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Long; - import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodHandle; - import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodType; - import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Methodref; - import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_String; import static com.sun.tools.javac.jvm.UninitializedType.*; import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame; /** An internal structure that corresponds to the code attribute of * methods in a classfile. The class also provides some utility operations to --- 25,44 ---- package com.sun.tools.javac.jvm; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.*; + import com.sun.tools.javac.code.Types.UniqueType; import com.sun.tools.javac.resources.CompilerProperties.Errors; + import com.sun.tools.javac.jvm.Pool.DynamicVariable; + import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import static com.sun.tools.javac.code.TypeTag.BOT; import static com.sun.tools.javac.code.TypeTag.INT; import static com.sun.tools.javac.jvm.ByteCodes.*; import static com.sun.tools.javac.jvm.UninitializedType.*; import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame; /** An internal structure that corresponds to the code attribute of * methods in a classfile. The class also provides some utility operations to
*** 82,92 **** } } final Types types; final Symtab syms; - final PoolWriter poolWriter; /*---------- classfile fields: --------------- */ /** The maximum stack size. */ --- 71,80 ----
*** 188,197 **** --- 176,189 ---- /** Emit line number info if map supplied */ Position.LineMap lineMap; + /** The constant pool of the current class. + */ + final Pool pool; + final MethodSymbol meth; private int letExprStackPos = 0; /** Construct a code object, given the settings of the fatcode,
*** 204,223 **** StackMapFormat stackMap, boolean debugCode, CRTable crt, Symtab syms, Types types, ! PoolWriter poolWriter) { this.meth = meth; this.fatcode = fatcode; this.lineMap = lineMap; this.lineDebugInfo = lineMap != null; this.varDebugInfo = varDebugInfo; this.crt = crt; this.syms = syms; this.types = types; - this.poolWriter = poolWriter; this.debugCode = debugCode; this.stackMap = stackMap; switch (stackMap) { case CLDC: case JSR202: --- 196,214 ---- StackMapFormat stackMap, boolean debugCode, CRTable crt, Symtab syms, Types types, ! Pool pool) { this.meth = meth; this.fatcode = fatcode; this.lineMap = lineMap; this.lineDebugInfo = lineMap != null; this.varDebugInfo = varDebugInfo; this.crt = crt; this.syms = syms; this.types = types; this.debugCode = debugCode; this.stackMap = stackMap; switch (stackMap) { case CLDC: case JSR202:
*** 226,235 **** --- 217,227 ---- default: this.needStackMap = false; } state = new State(); lvar = new LocalVar[20]; + this.pool = pool; } /* ************************************************************************** * Typecodes & related stuff
*** 396,412 **** Assert.check(alive || isStatementStart()); } /** Emit a ldc (or ldc_w) instruction, taking into account operand size */ ! public void emitLdc(LoadableConstant constant) { ! int od = poolWriter.putConstant(constant); if (od <= 255) { ! emitop1(ldc1, od, constant); } else { ! emitop2(ldc2, od, constant); } } /** Emit a multinewarray instruction. */ --- 388,403 ---- Assert.check(alive || isStatementStart()); } /** Emit a ldc (or ldc_w) instruction, taking into account operand size */ ! public void emitLdc(int od) { if (od <= 255) { ! emitop1(ldc1, od); } else { ! emitop2(ldc2, od); } } /** Emit a multinewarray instruction. */
*** 439,502 **** state.push(arrayType); } /** Emit an invokeinterface instruction. */ ! public void emitInvokeinterface(Symbol member, Type mtype) { int argsize = width(mtype.getParameterTypes()); emitop(invokeinterface); if (!alive) return; ! emit2(poolWriter.putMember(member)); emit1(argsize + 1); emit1(0); state.pop(argsize + 1); state.push(mtype.getReturnType()); } /** Emit an invokespecial instruction. */ ! public void emitInvokespecial(Symbol member, Type mtype) { int argsize = width(mtype.getParameterTypes()); emitop(invokespecial); if (!alive) return; ! emit2(poolWriter.putMember(member)); state.pop(argsize); ! if (member.isConstructor()) state.markInitialized((UninitializedType)state.peek()); state.pop(1); state.push(mtype.getReturnType()); } /** Emit an invokestatic instruction. */ ! public void emitInvokestatic(Symbol member, Type mtype) { int argsize = width(mtype.getParameterTypes()); emitop(invokestatic); if (!alive) return; ! emit2(poolWriter.putMember(member)); state.pop(argsize); state.push(mtype.getReturnType()); } /** Emit an invokevirtual instruction. */ ! public void emitInvokevirtual(Symbol member, Type mtype) { int argsize = width(mtype.getParameterTypes()); emitop(invokevirtual); if (!alive) return; ! emit2(poolWriter.putMember(member)); state.pop(argsize + 1); state.push(mtype.getReturnType()); } /** Emit an invokedynamic instruction. */ ! public void emitInvokedynamic(DynamicMethodSymbol dynMember, Type mtype) { int argsize = width(mtype.getParameterTypes()); emitop(invokedynamic); if (!alive) return; ! emit2(poolWriter.putDynamic(dynMember)); emit2(0); state.pop(argsize); state.push(mtype.getReturnType()); } --- 430,494 ---- state.push(arrayType); } /** Emit an invokeinterface instruction. */ ! public void emitInvokeinterface(int meth, Type mtype) { int argsize = width(mtype.getParameterTypes()); emitop(invokeinterface); if (!alive) return; ! emit2(meth); emit1(argsize + 1); emit1(0); state.pop(argsize + 1); state.push(mtype.getReturnType()); } /** Emit an invokespecial instruction. */ ! public void emitInvokespecial(int meth, Type mtype) { int argsize = width(mtype.getParameterTypes()); emitop(invokespecial); if (!alive) return; ! emit2(meth); ! Symbol sym = (Symbol)pool.pool[meth]; state.pop(argsize); ! if (sym.isConstructor()) state.markInitialized((UninitializedType)state.peek()); state.pop(1); state.push(mtype.getReturnType()); } /** Emit an invokestatic instruction. */ ! public void emitInvokestatic(int meth, Type mtype) { int argsize = width(mtype.getParameterTypes()); emitop(invokestatic); if (!alive) return; ! emit2(meth); state.pop(argsize); state.push(mtype.getReturnType()); } /** Emit an invokevirtual instruction. */ ! public void emitInvokevirtual(int meth, Type mtype) { int argsize = width(mtype.getParameterTypes()); emitop(invokevirtual); if (!alive) return; ! emit2(meth); state.pop(argsize + 1); state.push(mtype.getReturnType()); } /** Emit an invokedynamic instruction. */ ! public void emitInvokedynamic(int desc, Type mtype) { int argsize = width(mtype.getParameterTypes()); emitop(invokedynamic); if (!alive) return; ! emit2(desc); emit2(0); state.pop(argsize); state.push(mtype.getReturnType()); }
*** 903,932 **** } /** Emit an opcode with a one-byte operand field. */ public void emitop1(int op, int od) { - emitop1(op, od, null); - } - - public void emitop1(int op, int od, PoolConstant data) { emitop(op); if (!alive) return; emit1(od); switch (op) { case bipush: state.push(syms.intType); break; case ldc1: ! state.push(types.constantType((LoadableConstant)data)); break; default: throw new AssertionError(mnem(op)); } postop(); } /** Emit an opcode with a one-byte operand field; * widen if field does not fit in a byte. */ public void emitop1w(int op, int od) { if (od > 0xFF) { --- 895,940 ---- } /** Emit an opcode with a one-byte operand field. */ public void emitop1(int op, int od) { emitop(op); if (!alive) return; emit1(od); switch (op) { case bipush: state.push(syms.intType); break; case ldc1: ! state.push(typeForPool(pool.pool[od])); break; default: throw new AssertionError(mnem(op)); } postop(); } + /** The type of a constant pool entry. */ + private Type typeForPool(Object o) { + if (o instanceof Integer) return syms.intType; + if (o instanceof Float) return syms.floatType; + if (o instanceof String) return syms.stringType; + if (o instanceof Long) return syms.longType; + if (o instanceof Double) return syms.doubleType; + if (o instanceof ClassSymbol) return syms.classType; + if (o instanceof Pool.MethodHandle) return syms.methodHandleType; + if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type); + if (o instanceof Pool.DynamicVariable) return ((Pool.DynamicVariable)o).type; + if (o instanceof Type) { + Type ty = (Type) o; + + if (ty instanceof Type.ArrayType) return syms.classType; + if (ty instanceof Type.MethodType) return syms.methodTypeType; + } + throw new AssertionError("Invalid type of constant pool entry: " + o.getClass()); + } + /** Emit an opcode with a one-byte operand field; * widen if field does not fit in a byte. */ public void emitop1w(int op, int od) { if (od > 0xFF) {
*** 995,1029 **** } } /** Emit an opcode with a two-byte operand field. */ - public <P extends PoolConstant> void emitop2(int op, P constant, ToIntBiFunction<PoolWriter, P> poolFunc) { - int od = poolFunc.applyAsInt(poolWriter, constant); - emitop2(op, od, constant); - } - public void emitop2(int op, int od) { - emitop2(op, od, null); - } - - public void emitop2(int op, int od, PoolConstant data) { emitop(op); if (!alive) return; emit2(od); switch (op) { case getstatic: ! state.push(((Symbol)data).erasure(types)); break; case putstatic: ! state.pop(((Symbol)data).erasure(types)); break; ! case new_: { ! Type t = (Type)data; ! state.push(uninitializedObject(t.tsym.erasure(types), cp-3)); break; - } case sipush: state.push(syms.intType); break; case if_acmp_null: case if_acmp_nonnull: --- 1003,1035 ---- } } /** Emit an opcode with a two-byte operand field. */ public void emitop2(int op, int od) { emitop(op); if (!alive) return; emit2(od); switch (op) { case getstatic: ! state.push(((Symbol)(pool.pool[od])).erasure(types)); break; case putstatic: ! state.pop(((Symbol)(pool.pool[od])).erasure(types)); break; ! case new_: ! Symbol sym; ! if (pool.pool[od] instanceof UniqueType) { ! // Required by change in Gen.makeRef to allow ! // annotated types. ! // TODO: is this needed anywhere else? ! sym = ((UniqueType)(pool.pool[od])).type.tsym; ! } else { ! sym = (Symbol)(pool.pool[od]); ! } ! state.push(uninitializedObject(sym.erasure(types), cp-3)); break; case sipush: state.push(syms.intType); break; case if_acmp_null: case if_acmp_nonnull:
*** 1047,1077 **** break; case goto_: markDead(); break; case putfield: ! state.pop(((Symbol)data).erasure(types)); state.pop(1); // object ref break; case getfield: state.pop(1); // object ref ! state.push(((Symbol)data).erasure(types)); break; case checkcast: { state.pop(1); // object ref ! Type t = types.erasure((Type)data); state.push(t); break; } case ldc2w: ! state.push(types.constantType((LoadableConstant)data)); break; case instanceof_: state.pop(1); state.push(syms.intType); break; case ldc2: ! state.push(types.constantType((LoadableConstant)data)); break; case jsr: break; default: throw new AssertionError(mnem(op)); --- 1053,1086 ---- break; case goto_: markDead(); break; case putfield: ! state.pop(((Symbol)(pool.pool[od])).erasure(types)); state.pop(1); // object ref break; case getfield: state.pop(1); // object ref ! state.push(((Symbol)(pool.pool[od])).erasure(types)); break; case checkcast: { state.pop(1); // object ref ! Object o = pool.pool[od]; ! Type t = (o instanceof Symbol) ! ? ((Symbol)o).erasure(types) ! : types.erasure((((UniqueType)o).type)); state.push(t); break; } case ldc2w: ! state.push(typeForPool(pool.pool[od])); break; case instanceof_: state.pop(1); state.push(syms.intType); break; case ldc2: ! state.push(typeForPool(pool.pool[od])); break; case jsr: break; default: throw new AssertionError(mnem(op));
< prev index next >