langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
changeset 25445 603f0c93d5c9
parent 25443 9187d77f2c64
equal deleted inserted replaced
25444:27045478cf23 25445:603f0c93d5c9
    80     private final ClassWriter writer;
    80     private final ClassWriter writer;
    81     private final ConstFold cfolder;
    81     private final ConstFold cfolder;
    82     private final Target target;
    82     private final Target target;
    83     private final Source source;
    83     private final Source source;
    84     private final TypeEnvs typeEnvs;
    84     private final TypeEnvs typeEnvs;
    85     private final boolean allowEnums;
       
    86     private final Name dollarAssertionsDisabled;
    85     private final Name dollarAssertionsDisabled;
    87     private final Name classDollar;
    86     private final Name classDollar;
    88     private final Types types;
    87     private final Types types;
    89     private final boolean debugLower;
    88     private final boolean debugLower;
    90     private final PkgInfo pkginfoOpt;
    89     private final PkgInfo pkginfoOpt;
   101         writer = ClassWriter.instance(context);
   100         writer = ClassWriter.instance(context);
   102         cfolder = ConstFold.instance(context);
   101         cfolder = ConstFold.instance(context);
   103         target = Target.instance(context);
   102         target = Target.instance(context);
   104         source = Source.instance(context);
   103         source = Source.instance(context);
   105         typeEnvs = TypeEnvs.instance(context);
   104         typeEnvs = TypeEnvs.instance(context);
   106         allowEnums = source.allowEnums();
       
   107         dollarAssertionsDisabled = names.
   105         dollarAssertionsDisabled = names.
   108             fromString(target.syntheticNameChar() + "assertionsDisabled");
   106             fromString(target.syntheticNameChar() + "assertionsDisabled");
   109         classDollar = names.
   107         classDollar = names.
   110             fromString("class" + target.syntheticNameChar());
   108             fromString("class" + target.syntheticNameChar());
   111 
   109 
  1490     }
  1488     }
  1491 
  1489 
  1492     List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
  1490     List<JCVariableDecl> freevarDefs(int pos, List<VarSymbol> freevars, Symbol owner,
  1493             long additionalFlags) {
  1491             long additionalFlags) {
  1494         long flags = FINAL | SYNTHETIC | additionalFlags;
  1492         long flags = FINAL | SYNTHETIC | additionalFlags;
  1495         if (owner.kind == TYP &&
       
  1496             target.usePrivateSyntheticFields())
       
  1497             flags |= PRIVATE;
       
  1498         List<JCVariableDecl> defs = List.nil();
  1493         List<JCVariableDecl> defs = List.nil();
  1499         for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) {
  1494         for (List<VarSymbol> l = freevars; l.nonEmpty(); l = l.tail) {
  1500             VarSymbol v = l.head;
  1495             VarSymbol v = l.head;
  1501             VarSymbol proxy = new VarSymbol(
  1496             VarSymbol proxy = new VarSymbol(
  1502                 flags, proxyName(v.name), v.erasure(types), owner);
  1497                 flags, proxyName(v.name), v.erasure(types), owner);
  1523             result = names.fromString(result.toString() + target.syntheticNameChar());
  1518             result = names.fromString(result.toString() + target.syntheticNameChar());
  1524         return result;
  1519         return result;
  1525     }
  1520     }
  1526 
  1521 
  1527     private VarSymbol makeOuterThisVarSymbol(Symbol owner, long flags) {
  1522     private VarSymbol makeOuterThisVarSymbol(Symbol owner, long flags) {
  1528         if (owner.kind == TYP &&
       
  1529             target.usePrivateSyntheticFields())
       
  1530             flags |= PRIVATE;
       
  1531         Type target = types.erasure(owner.enclClass().type.getEnclosingType());
  1523         Type target = types.erasure(owner.enclClass().type.getEnclosingType());
  1532         VarSymbol outerThis =
  1524         VarSymbol outerThis =
  1533             new VarSymbol(flags, outerThisName(target, owner), target, owner);
  1525             new VarSymbol(flags, outerThisName(target, owner), target, owner);
  1534         outerThisStack = outerThisStack.prepend(outerThis);
  1526         outerThisStack = outerThisStack.prepend(outerThis);
  1535         return outerThis;
  1527         return outerThis;
  1898      *  for backward compatibility in 1.4 and earlier we use the
  1890      *  for backward compatibility in 1.4 and earlier we use the
  1899      *  top-level class itself.
  1891      *  top-level class itself.
  1900      */
  1892      */
  1901     private ClassSymbol outerCacheClass() {
  1893     private ClassSymbol outerCacheClass() {
  1902         ClassSymbol clazz = outermostClassDef.sym;
  1894         ClassSymbol clazz = outermostClassDef.sym;
  1903         if ((clazz.flags() & INTERFACE) == 0 &&
       
  1904             !target.useInnerCacheClass()) return clazz;
       
  1905         Scope s = clazz.members();
  1895         Scope s = clazz.members();
  1906         for (Symbol sym : s.getSymbols(NON_RECURSIVE))
  1896         for (Symbol sym : s.getSymbols(NON_RECURSIVE))
  1907             if (sym.kind == TYP &&
  1897             if (sym.kind == TYP &&
  1908                 sym.name == names.empty &&
  1898                 sym.name == names.empty &&
  1909                 (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
  1899                 (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
  1956         MethodSymbol classDollarSym = md.sym;
  1946         MethodSymbol classDollarSym = md.sym;
  1957         ClassSymbol outerCacheClass = (ClassSymbol)classDollarSym.owner;
  1947         ClassSymbol outerCacheClass = (ClassSymbol)classDollarSym.owner;
  1958 
  1948 
  1959         JCBlock returnResult;
  1949         JCBlock returnResult;
  1960 
  1950 
  1961         // in 1.4.2 and above, we use
  1951         // cache the current loader in cl$
  1962         // Class.forName(String name, boolean init, ClassLoader loader);
  1952         // clsym = "private static ClassLoader cl$"
  1963         // which requires we cache the current loader in cl$
  1953         VarSymbol clsym = new VarSymbol(STATIC | SYNTHETIC,
  1964         if (target.classLiteralsNoInit()) {
  1954                                         names.fromString("cl" + target.syntheticNameChar()),
  1965             // clsym = "private static ClassLoader cl$"
  1955                                         syms.classLoaderType,
  1966             VarSymbol clsym = new VarSymbol(STATIC|SYNTHETIC,
  1956                                         outerCacheClass);
  1967                                             names.fromString("cl" + target.syntheticNameChar()),
  1957         enterSynthetic(pos, clsym, outerCacheClass.members());
  1968                                             syms.classLoaderType,
  1958 
  1969                                             outerCacheClass);
  1959         // emit "private static ClassLoader cl$;"
  1970             enterSynthetic(pos, clsym, outerCacheClass.members());
  1960         JCVariableDecl cldef = make.VarDef(clsym, null);
  1971 
  1961         JCClassDecl outerCacheClassDef = classDef(outerCacheClass);
  1972             // emit "private static ClassLoader cl$;"
  1962         outerCacheClassDef.defs = outerCacheClassDef.defs.prepend(cldef);
  1973             JCVariableDecl cldef = make.VarDef(clsym, null);
  1963 
  1974             JCClassDecl outerCacheClassDef = classDef(outerCacheClass);
  1964         // newcache := "new cache$1[0]"
  1975             outerCacheClassDef.defs = outerCacheClassDef.defs.prepend(cldef);
  1965         JCNewArray newcache = make.NewArray(make.Type(outerCacheClass.type),
  1976 
  1966                                             List.<JCExpression>of(make.Literal(INT, 0).setType(syms.intType)),
  1977             // newcache := "new cache$1[0]"
  1967                                             null);
  1978             JCNewArray newcache = make.
  1968         newcache.type = new ArrayType(types.erasure(outerCacheClass.type),
  1979                 NewArray(make.Type(outerCacheClass.type),
  1969                                       syms.arrayClass, Type.noAnnotations);
  1980                          List.<JCExpression>of(make.Literal(INT, 0).setType(syms.intType)),
  1970 
  1981                          null);
  1971         // forNameSym := java.lang.Class.forName(
  1982             newcache.type = new ArrayType(types.erasure(outerCacheClass.type),
  1972         //     String s,boolean init,ClassLoader loader)
  1983                                           syms.arrayClass, Type.noAnnotations);
  1973         Symbol forNameSym = lookupMethod(make_pos, names.forName,
  1984 
  1974                                          types.erasure(syms.classType),
  1985             // forNameSym := java.lang.Class.forName(
  1975                                          List.of(syms.stringType,
  1986             //     String s,boolean init,ClassLoader loader)
  1976                                                  syms.booleanType,
  1987             Symbol forNameSym = lookupMethod(make_pos, names.forName,
  1977                                                  syms.classLoaderType));
  1988                                              types.erasure(syms.classType),
  1978         // clvalue := "(cl$ == null) ?
  1989                                              List.of(syms.stringType,
  1979         // $newcache.getClass().getComponentType().getClassLoader() : cl$"
  1990                                                      syms.booleanType,
  1980         JCExpression clvalue =
  1991                                                      syms.classLoaderType));
       
  1992             // clvalue := "(cl$ == null) ?
       
  1993             // $newcache.getClass().getComponentType().getClassLoader() : cl$"
       
  1994             JCExpression clvalue =
       
  1995                 make.Conditional(
  1981                 make.Conditional(
  1996                     makeBinary(EQ, make.Ident(clsym), makeNull()),
  1982                         makeBinary(EQ, make.Ident(clsym), makeNull()),
  1997                     make.Assign(
  1983                         make.Assign(make.Ident(clsym),
  1998                         make.Ident(clsym),
  1984                                     makeCall(
  1999                         makeCall(
  1985                                             makeCall(makeCall(newcache,
  2000                             makeCall(makeCall(newcache,
  1986                                                               names.getClass,
  2001                                               names.getClass,
  1987                                                               List.<JCExpression>nil()),
  2002                                               List.<JCExpression>nil()),
  1988                                                      names.getComponentType,
  2003                                      names.getComponentType,
  1989                                                      List.<JCExpression>nil()),
  2004                                      List.<JCExpression>nil()),
  1990                                             names.getClassLoader,
  2005                             names.getClassLoader,
  1991                                             List.<JCExpression>nil())).setType(syms.classLoaderType),
  2006                             List.<JCExpression>nil())).setType(syms.classLoaderType),
  1992                         make.Ident(clsym)).setType(syms.classLoaderType);
  2007                     make.Ident(clsym)).setType(syms.classLoaderType);
  1993 
  2008 
  1994         // returnResult := "{ return Class.forName(param1, false, cl$); }"
  2009             // returnResult := "{ return Class.forName(param1, false, cl$); }"
  1995         List<JCExpression> args = List.of(make.Ident(md.params.head.sym),
  2010             List<JCExpression> args = List.of(make.Ident(md.params.head.sym),
  1996                                           makeLit(syms.booleanType, 0),
  2011                                               makeLit(syms.booleanType, 0),
  1997                                           clvalue);
  2012                                               clvalue);
  1998         returnResult = make.Block(0, List.<JCStatement>of(make.Call(make.App(make.Ident(forNameSym), args))));
  2013             returnResult = make.
       
  2014                 Block(0, List.<JCStatement>of(make.
       
  2015                               Call(make. // return
       
  2016                                    App(make.
       
  2017                                        Ident(forNameSym), args))));
       
  2018         } else {
       
  2019             // forNameSym := java.lang.Class.forName(String s)
       
  2020             Symbol forNameSym = lookupMethod(make_pos,
       
  2021                                              names.forName,
       
  2022                                              types.erasure(syms.classType),
       
  2023                                              List.of(syms.stringType));
       
  2024             // returnResult := "{ return Class.forName(param1); }"
       
  2025             returnResult = make.
       
  2026                 Block(0, List.of(make.
       
  2027                           Call(make. // return
       
  2028                               App(make.
       
  2029                                   QualIdent(forNameSym),
       
  2030                                   List.<JCExpression>of(make.
       
  2031                                                         Ident(md.params.
       
  2032                                                               head.sym))))));
       
  2033         }
       
  2034 
  1999 
  2035         // catchParam := ClassNotFoundException e1
  2000         // catchParam := ClassNotFoundException e1
  2036         VarSymbol catchParam =
  2001         VarSymbol catchParam =
  2037             new VarSymbol(SYNTHETIC, make.paramName(1),
  2002             new VarSymbol(SYNTHETIC, make.paramName(1),
  2038                           syms.classNotFoundExceptionType,
  2003                           syms.classNotFoundExceptionType,
  2039                           classDollarSym);
  2004                           classDollarSym);
  2040 
  2005 
  2041         JCStatement rethrow;
  2006         JCStatement rethrow;
  2042         if (target.hasInitCause()) {
  2007         // rethrow = "throw new NoClassDefFoundError().initCause(e);
  2043             // rethrow = "throw new NoClassDefFoundError().initCause(e);
  2008         JCExpression throwExpr =
  2044             JCExpression throwExpr =
  2009             makeCall(makeNewClass(syms.noClassDefFoundErrorType,
  2045                 makeCall(makeNewClass(syms.noClassDefFoundErrorType,
  2010                                   List.<JCExpression>nil()),
  2046                                       List.<JCExpression>nil()),
  2011                      names.initCause,
  2047                          names.initCause,
  2012                      List.<JCExpression>of(make.Ident(catchParam)));
  2048                          List.<JCExpression>of(make.Ident(catchParam)));
  2013         rethrow = make.Throw(throwExpr);
  2049             rethrow = make.Throw(throwExpr);
       
  2050         } else {
       
  2051             // getMessageSym := ClassNotFoundException.getMessage()
       
  2052             Symbol getMessageSym = lookupMethod(make_pos,
       
  2053                                                 names.getMessage,
       
  2054                                                 syms.classNotFoundExceptionType,
       
  2055                                                 List.<Type>nil());
       
  2056             // rethrow = "throw new NoClassDefFoundError(e.getMessage());"
       
  2057             rethrow = make.
       
  2058                 Throw(makeNewClass(syms.noClassDefFoundErrorType,
       
  2059                           List.<JCExpression>of(make.App(make.Select(make.Ident(catchParam),
       
  2060                                                                      getMessageSym),
       
  2061                                                          List.<JCExpression>nil()))));
       
  2062         }
       
  2063 
  2014 
  2064         // rethrowStmt := "( $rethrow )"
  2015         // rethrowStmt := "( $rethrow )"
  2065         JCBlock rethrowStmt = make.Block(0, List.of(rethrow));
  2016         JCBlock rethrowStmt = make.Block(0, List.of(rethrow));
  2066 
  2017 
  2067         // catchBlock := "catch ($catchParam) $rethrowStmt"
  2018         // catchBlock := "catch ($catchParam) $rethrowStmt"
  2145                     pos, c.type, names.TYPE, true);
  2096                     pos, c.type, names.TYPE, true);
  2146             if (typeSym.kind == VAR)
  2097             if (typeSym.kind == VAR)
  2147                 ((VarSymbol)typeSym).getConstValue(); // ensure initializer is evaluated
  2098                 ((VarSymbol)typeSym).getConstValue(); // ensure initializer is evaluated
  2148             return make.QualIdent(typeSym);
  2099             return make.QualIdent(typeSym);
  2149         case CLASS: case ARRAY:
  2100         case CLASS: case ARRAY:
  2150             if (target.hasClassLiterals()) {
       
  2151                 VarSymbol sym = new VarSymbol(
  2101                 VarSymbol sym = new VarSymbol(
  2152                         STATIC | PUBLIC | FINAL, names._class,
  2102                         STATIC | PUBLIC | FINAL, names._class,
  2153                         syms.classType, type.tsym);
  2103                         syms.classType, type.tsym);
  2154                 return make_at(pos).Select(make.Type(type), sym);
  2104                 return make_at(pos).Select(make.Type(type), sym);
  2155             }
       
  2156             // replace with <cache == null ? cache = class$(tsig) : cache>
       
  2157             // where
       
  2158             //  - <tsig>  is the type signature of T,
       
  2159             //  - <cache> is the cache variable for tsig.
       
  2160             String sig =
       
  2161                 writer.xClassName(type).toString().replace('/', '.');
       
  2162             Symbol cs = cacheSym(pos, sig);
       
  2163             return make_at(pos).Conditional(
       
  2164                 makeBinary(EQ, make.Ident(cs), makeNull()),
       
  2165                 make.Assign(
       
  2166                     make.Ident(cs),
       
  2167                     make.App(
       
  2168                         make.Ident(classDollarSym(pos)),
       
  2169                         List.<JCExpression>of(make.Literal(CLASS, sig)
       
  2170                                               .setType(syms.stringType))))
       
  2171                 .setType(types.erasure(syms.classType)),
       
  2172                 make.Ident(cs)).setType(types.erasure(syms.classType));
       
  2173         default:
  2105         default:
  2174             throw new AssertionError();
  2106             throw new AssertionError();
  2175         }
  2107         }
  2176     }
  2108     }
  2177 
  2109 
  2413         if (!needPackageInfoClass(tree))
  2345         if (!needPackageInfoClass(tree))
  2414             return;
  2346             return;
  2415 
  2347 
  2416         Name name = names.package_info;
  2348         Name name = names.package_info;
  2417         long flags = Flags.ABSTRACT | Flags.INTERFACE;
  2349         long flags = Flags.ABSTRACT | Flags.INTERFACE;
  2418         if (target.isPackageInfoSynthetic())
  2350         // package-info is marked SYNTHETIC in JDK 1.6 and later releases
  2419             // package-info is marked SYNTHETIC in JDK 1.6 and later releases
  2351         flags = flags | Flags.SYNTHETIC;
  2420             flags = flags | Flags.SYNTHETIC;
       
  2421         JCClassDecl packageAnnotationsClass
  2352         JCClassDecl packageAnnotationsClass
  2422             = make.ClassDef(make.Modifiers(flags, tree.getAnnotations()),
  2353             = make.ClassDef(make.Modifiers(flags, tree.getAnnotations()),
  2423                             name, List.<JCTypeParameter>nil(),
  2354                             name, List.<JCTypeParameter>nil(),
  2424                             null, List.<JCExpression>nil(), List.<JCTree>nil());
  2355                             null, List.<JCExpression>nil(), List.<JCTree>nil());
  2425         ClassSymbol c = tree.packge.package_info;
  2356         ClassSymbol c = tree.packge.package_info;
  2547 
  2478 
  2548         // add the supertype, if needed
  2479         // add the supertype, if needed
  2549         if (tree.extending == null)
  2480         if (tree.extending == null)
  2550             tree.extending = make.Type(types.supertype(tree.type));
  2481             tree.extending = make.Type(types.supertype(tree.type));
  2551 
  2482 
  2552         // classOfType adds a cache field to tree.defs unless
  2483         // classOfType adds a cache field to tree.defs
  2553         // target.hasClassLiterals().
       
  2554         JCExpression e_class = classOfType(tree.sym.type, tree.pos()).
  2484         JCExpression e_class = classOfType(tree.sym.type, tree.pos()).
  2555             setType(types.erasure(syms.classType));
  2485             setType(types.erasure(syms.classType));
  2556 
  2486 
  2557         // process each enumeration constant, adding implicit constructor parameters
  2487         // process each enumeration constant, adding implicit constructor parameters
  2558         int nextOrdinal = 0;
  2488         int nextOrdinal = 0;
  2808             proxies = proxies.leave();
  2738             proxies = proxies.leave();
  2809 
  2739 
  2810             // recursively translate following local statements and
  2740             // recursively translate following local statements and
  2811             // combine with this- or super-call
  2741             // combine with this- or super-call
  2812             List<JCStatement> stats = translate(tree.body.stats.tail);
  2742             List<JCStatement> stats = translate(tree.body.stats.tail);
  2813             if (target.initializeFieldsBeforeSuper())
  2743             tree.body.stats = stats.prepend(selfCall).prependList(added);
  2814                 tree.body.stats = stats.prepend(selfCall).prependList(added);
       
  2815             else
       
  2816                 tree.body.stats = stats.prependList(added).prepend(selfCall);
       
  2817 
       
  2818             outerThisStack = prevOuterThisStack;
  2744             outerThisStack = prevOuterThisStack;
  2819         } else {
  2745         } else {
  2820             Map<Symbol, Symbol> prevLambdaTranslationMap =
  2746             Map<Symbol, Symbol> prevLambdaTranslationMap =
  2821                     lambdaTranslationMap;
  2747                     lambdaTranslationMap;
  2822             try {
  2748             try {
  3054     }
  2980     }
  3055 
  2981 
  3056     public void visitApply(JCMethodInvocation tree) {
  2982     public void visitApply(JCMethodInvocation tree) {
  3057         Symbol meth = TreeInfo.symbol(tree.meth);
  2983         Symbol meth = TreeInfo.symbol(tree.meth);
  3058         List<Type> argtypes = meth.type.getParameterTypes();
  2984         List<Type> argtypes = meth.type.getParameterTypes();
  3059         if (allowEnums &&
  2985         if (meth.name == names.init && meth.owner == syms.enumSym)
  3060             meth.name==names.init &&
       
  3061             meth.owner == syms.enumSym)
       
  3062             argtypes = argtypes.tail.tail;
  2986             argtypes = argtypes.tail.tail;
  3063         tree.args = boxArgs(argtypes, tree.args, tree.varargsElement);
  2987         tree.args = boxArgs(argtypes, tree.args, tree.varargsElement);
  3064         tree.varargsElement = null;
  2988         tree.varargsElement = null;
  3065         Name methName = TreeInfo.name(tree.meth);
  2989         Name methName = TreeInfo.name(tree.meth);
  3066         if (meth.name==names.init) {
  2990         if (meth.name==names.init) {
  3193     }
  3117     }
  3194 
  3118 
  3195     /** Box up a single primitive expression. */
  3119     /** Box up a single primitive expression. */
  3196     JCExpression boxPrimitive(JCExpression tree, Type box) {
  3120     JCExpression boxPrimitive(JCExpression tree, Type box) {
  3197         make_at(tree.pos());
  3121         make_at(tree.pos());
  3198         if (target.boxWithConstructors()) {
  3122         Symbol valueOfSym = lookupMethod(tree.pos(),
  3199             Symbol ctor = lookupConstructor(tree.pos(),
  3123                                          names.valueOf,
  3200                                             box,
  3124                                          box,
  3201                                             List.<Type>nil()
  3125                                          List.<Type>nil()
  3202                                             .prepend(tree.type));
  3126                                          .prepend(tree.type));
  3203             return make.Create(ctor, List.of(tree));
  3127         return make.App(make.QualIdent(valueOfSym), List.of(tree));
  3204         } else {
       
  3205             Symbol valueOfSym = lookupMethod(tree.pos(),
       
  3206                                              names.valueOf,
       
  3207                                              box,
       
  3208                                              List.<Type>nil()
       
  3209                                              .prepend(tree.type));
       
  3210             return make.App(make.QualIdent(valueOfSym), List.of(tree));
       
  3211         }
       
  3212     }
  3128     }
  3213 
  3129 
  3214     /** Unbox an object to a primitive value. */
  3130     /** Unbox an object to a primitive value. */
  3215     JCExpression unbox(JCExpression tree, Type primitive) {
  3131     JCExpression unbox(JCExpression tree, Type primitive) {
  3216         Type unboxedType = types.unboxedType(tree.type);
  3132         Type unboxedType = types.unboxedType(tree.type);