40 import com.sun.tools.javac.tree.EndPosTable; |
40 import com.sun.tools.javac.tree.EndPosTable; |
41 import com.sun.tools.javac.tree.JCTree.*; |
41 import com.sun.tools.javac.tree.JCTree.*; |
42 |
42 |
43 import static com.sun.tools.javac.code.Flags.*; |
43 import static com.sun.tools.javac.code.Flags.*; |
44 import static com.sun.tools.javac.code.Kinds.*; |
44 import static com.sun.tools.javac.code.Kinds.*; |
45 import static com.sun.tools.javac.code.TypeTags.*; |
45 import static com.sun.tools.javac.code.TypeTag.*; |
46 import static com.sun.tools.javac.jvm.ByteCodes.*; |
46 import static com.sun.tools.javac.jvm.ByteCodes.*; |
47 import static com.sun.tools.javac.jvm.CRTFlags.*; |
47 import static com.sun.tools.javac.jvm.CRTFlags.*; |
48 import static com.sun.tools.javac.main.Option.*; |
48 import static com.sun.tools.javac.main.Option.*; |
49 import static com.sun.tools.javac.tree.JCTree.Tag.*; |
49 import static com.sun.tools.javac.tree.JCTree.Tag.*; |
50 import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK; |
50 import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK; |
256 * @param sym The accessed symbol |
256 * @param sym The accessed symbol |
257 * @param site The qualifier's type. |
257 * @param site The qualifier's type. |
258 */ |
258 */ |
259 Symbol binaryQualifier(Symbol sym, Type site) { |
259 Symbol binaryQualifier(Symbol sym, Type site) { |
260 |
260 |
261 if (site.tag == ARRAY) { |
261 if (site.hasTag(ARRAY)) { |
262 if (sym == syms.lengthVar || |
262 if (sym == syms.lengthVar || |
263 sym.owner != syms.arrayClass) |
263 sym.owner != syms.arrayClass) |
264 return sym; |
264 return sym; |
265 // array clone can be qualified by the array type in later targets |
265 // array clone can be qualified by the array type in later targets |
266 Symbol qualifier = target.arrayBinaryCompatibility() |
266 Symbol qualifier = target.arrayBinaryCompatibility() |
303 * return the reference's index. |
303 * return the reference's index. |
304 * @param type The type for which a reference is inserted. |
304 * @param type The type for which a reference is inserted. |
305 */ |
305 */ |
306 int makeRef(DiagnosticPosition pos, Type type) { |
306 int makeRef(DiagnosticPosition pos, Type type) { |
307 checkDimension(pos, type); |
307 checkDimension(pos, type); |
308 return pool.put(type.tag == CLASS ? (Object)type.tsym : (Object)type); |
308 return pool.put(type.hasTag(CLASS) ? (Object)type.tsym : (Object)type); |
309 } |
309 } |
310 |
310 |
311 /** Check if the given type is an array with too many dimensions. |
311 /** Check if the given type is an array with too many dimensions. |
312 */ |
312 */ |
313 private void checkDimension(DiagnosticPosition pos, Type t) { |
313 private void checkDimension(DiagnosticPosition pos, Type t) { |
314 switch (t.tag) { |
314 switch (t.getTag()) { |
315 case METHOD: |
315 case METHOD: |
316 checkDimension(pos, t.getReturnType()); |
316 checkDimension(pos, t.getReturnType()); |
317 for (List<Type> args = t.getParameterTypes(); args.nonEmpty(); args = args.tail) |
317 for (List<Type> args = t.getParameterTypes(); args.nonEmpty(); args = args.tail) |
318 checkDimension(pos, args.head); |
318 checkDimension(pos, args.head); |
319 break; |
319 break; |
920 // If last statement could complete normally, insert a |
920 // If last statement could complete normally, insert a |
921 // return at the end. |
921 // return at the end. |
922 if (code.isAlive()) { |
922 if (code.isAlive()) { |
923 code.statBegin(TreeInfo.endPos(tree.body)); |
923 code.statBegin(TreeInfo.endPos(tree.body)); |
924 if (env.enclMethod == null || |
924 if (env.enclMethod == null || |
925 env.enclMethod.sym.type.getReturnType().tag == VOID) { |
925 env.enclMethod.sym.type.getReturnType().hasTag(VOID)) { |
926 code.emitop0(return_); |
926 code.emitop0(return_); |
927 } else { |
927 } else { |
928 // sometime dead code seems alive (4415991); |
928 // sometime dead code seems alive (4415991); |
929 // generate a small loop instead |
929 // generate a small loop instead |
930 int startpc = code.entryPoint(); |
930 int startpc = code.entryPoint(); |
1108 code.resolve(localEnv.info.exit); |
1108 code.resolve(localEnv.info.exit); |
1109 } |
1109 } |
1110 |
1110 |
1111 public void visitSwitch(JCSwitch tree) { |
1111 public void visitSwitch(JCSwitch tree) { |
1112 int limit = code.nextreg; |
1112 int limit = code.nextreg; |
1113 Assert.check(tree.selector.type.tag != CLASS); |
1113 Assert.check(!tree.selector.type.hasTag(CLASS)); |
1114 int startpcCrt = genCrt ? code.curPc() : 0; |
1114 int startpcCrt = genCrt ? code.curPc() : 0; |
1115 Item sel = genExpr(tree.selector, syms.intType); |
1115 Item sel = genExpr(tree.selector, syms.intType); |
1116 List<JCCase> cases = tree.cases; |
1116 List<JCCase> cases = tree.cases; |
1117 if (cases.isEmpty()) { |
1117 if (cases.isEmpty()) { |
1118 // We are seeing: switch <sel> {} |
1118 // We are seeing: switch <sel> {} |
1815 // If we have an increment of -32768 to +32767 of a local |
1815 // If we have an increment of -32768 to +32767 of a local |
1816 // int variable we can use an incr instruction instead of |
1816 // int variable we can use an incr instruction instead of |
1817 // proceeding further. |
1817 // proceeding further. |
1818 if ((tree.hasTag(PLUS_ASG) || tree.hasTag(MINUS_ASG)) && |
1818 if ((tree.hasTag(PLUS_ASG) || tree.hasTag(MINUS_ASG)) && |
1819 l instanceof LocalItem && |
1819 l instanceof LocalItem && |
1820 tree.lhs.type.tag <= INT && |
1820 tree.lhs.type.getTag().isSubRangeOf(INT) && |
1821 tree.rhs.type.tag <= INT && |
1821 tree.rhs.type.getTag().isSubRangeOf(INT) && |
1822 tree.rhs.type.constValue() != null) { |
1822 tree.rhs.type.constValue() != null) { |
1823 int ival = ((Number) tree.rhs.type.constValue()).intValue(); |
1823 int ival = ((Number) tree.rhs.type.constValue()).intValue(); |
1824 if (tree.hasTag(MINUS_ASG)) ival = -ival; |
1824 if (tree.hasTag(MINUS_ASG)) ival = -ival; |
1825 ((LocalItem)l).incr(ival); |
1825 ((LocalItem)l).incr(ival); |
1826 result = l; |
1826 result = l; |
1967 |
1967 |
1968 /** Append value (on tos) to string buffer (on tos - 1). |
1968 /** Append value (on tos) to string buffer (on tos - 1). |
1969 */ |
1969 */ |
1970 void appendString(JCTree tree) { |
1970 void appendString(JCTree tree) { |
1971 Type t = tree.type.baseType(); |
1971 Type t = tree.type.baseType(); |
1972 if (t.tag > lastBaseTag && t.tsym != syms.stringType.tsym) { |
1972 if (!t.isPrimitive() && t.tsym != syms.stringType.tsym) { |
1973 t = syms.objectType; |
1973 t = syms.objectType; |
1974 } |
1974 } |
1975 items.makeMemberItem(getStringBufferAppend(tree, t), false).invoke(); |
1975 items.makeMemberItem(getStringBufferAppend(tree, t), false).invoke(); |
1976 } |
1976 } |
1977 Symbol getStringBufferAppend(JCTree tree, Type t) { |
1977 Symbol getStringBufferAppend(JCTree tree, Type t) { |
2065 result = genExpr(tree.expr, tree.clazz.type).load(); |
2065 result = genExpr(tree.expr, tree.clazz.type).load(); |
2066 // Additional code is only needed if we cast to a reference type |
2066 // Additional code is only needed if we cast to a reference type |
2067 // which is not statically a supertype of the expression's type. |
2067 // which is not statically a supertype of the expression's type. |
2068 // For basic types, the coerce(...) in genExpr(...) will do |
2068 // For basic types, the coerce(...) in genExpr(...) will do |
2069 // the conversion. |
2069 // the conversion. |
2070 if (tree.clazz.type.tag > lastBaseTag && |
2070 if (!tree.clazz.type.isPrimitive() && |
2071 types.asSuper(tree.expr.type, tree.clazz.type.tsym) == null) { |
2071 types.asSuper(tree.expr.type, tree.clazz.type.tsym) == null) { |
2072 code.emitop2(checkcast, makeRef(tree.pos(), tree.clazz.type)); |
2072 code.emitop2(checkcast, makeRef(tree.pos(), tree.clazz.type)); |
2073 } |
2073 } |
2074 } |
2074 } |
2075 |
2075 |
2183 public boolean isInvokeDynamic(Symbol sym) { |
2183 public boolean isInvokeDynamic(Symbol sym) { |
2184 return sym.kind == MTH && ((MethodSymbol)sym).isDynamic(); |
2184 return sym.kind == MTH && ((MethodSymbol)sym).isDynamic(); |
2185 } |
2185 } |
2186 |
2186 |
2187 public void visitLiteral(JCLiteral tree) { |
2187 public void visitLiteral(JCLiteral tree) { |
2188 if (tree.type.tag == TypeTags.BOT) { |
2188 if (tree.type.hasTag(BOT)) { |
2189 code.emitop0(aconst_null); |
2189 code.emitop0(aconst_null); |
2190 if (types.dimensions(pt) > 1) { |
2190 if (types.dimensions(pt) > 1) { |
2191 code.emitop2(checkcast, makeRef(tree.pos(), pt)); |
2191 code.emitop2(checkcast, makeRef(tree.pos(), pt)); |
2192 result = items.makeStackItem(pt); |
2192 result = items.makeStackItem(pt); |
2193 } else { |
2193 } else { |