langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java

Print this page




  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package com.sun.tools.javac.jvm;
  27 
  28 import java.io.*;
  29 import java.net.URI;
  30 import java.net.URISyntaxException;
  31 import java.nio.CharBuffer;

  32 import java.util.EnumSet;
  33 import java.util.HashMap;
  34 import java.util.Map;
  35 import java.util.Set;
  36 import javax.lang.model.SourceVersion;
  37 import javax.tools.JavaFileObject;
  38 import javax.tools.JavaFileManager;
  39 import javax.tools.JavaFileManager.Location;
  40 import javax.tools.StandardJavaFileManager;
  41 
  42 import static javax.tools.StandardLocation.*;
  43 
  44 import com.sun.tools.javac.comp.Annotate;
  45 import com.sun.tools.javac.code.*;
  46 import com.sun.tools.javac.code.Type.*;
  47 import com.sun.tools.javac.code.Symbol.*;
  48 import com.sun.tools.javac.code.Symtab;
  49 import com.sun.tools.javac.file.BaseFileObject;
  50 import com.sun.tools.javac.util.*;
  51 


 174     int bp;
 175 
 176     /** The objects of the constant pool.
 177      */
 178     Object[] poolObj;
 179 
 180     /** For every constant pool entry, an index into buf where the
 181      *  defining section of the entry is found.
 182      */
 183     int[] poolIdx;
 184 
 185     /** The major version number of the class file being read. */
 186     int majorVersion;
 187     /** The minor version number of the class file being read. */
 188     int minorVersion;
 189 
 190     /** Switch: debug output for JSR 308-related operations.
 191      */
 192     boolean debugJSR308;
 193 





 194     /** Get the ClassReader instance for this invocation. */
 195     public static ClassReader instance(Context context) {
 196         ClassReader instance = context.get(classReaderKey);
 197         if (instance == null)
 198             instance = new ClassReader(context, true);
 199         return instance;
 200     }
 201 
 202     /** Initialize classes and packages, treating this as the definitive classreader. */
 203     public void init(Symtab syms) {
 204         init(syms, true);
 205     }
 206 
 207     /** Initialize classes and packages, optionally treating this as
 208      *  the definitive classreader.
 209      */
 210     private void init(Symtab syms, boolean definitive) {
 211         if (classes != null) return;
 212 
 213         if (definitive) {


 906                     List<Type> thrown = List.nil();
 907                     for (int j = 0; j < nexceptions; j++)
 908                         thrown = thrown.prepend(readClassSymbol(nextChar()).type);
 909                     if (sym.type.getThrownTypes().isEmpty())
 910                         sym.type.asMethodType().thrown = thrown.reverse();
 911                 }
 912             },
 913 
 914             new AttributeReader(names.InnerClasses, V45_3, CLASS_ATTRIBUTE) {
 915                 void read(Symbol sym, int attrLen) {
 916                     ClassSymbol c = (ClassSymbol) sym;
 917                     readInnerClasses(c);
 918                 }
 919             },
 920 
 921             new AttributeReader(names.LocalVariableTable, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
 922                 void read(Symbol sym, int attrLen) {
 923                     int newbp = bp + attrLen;
 924                     if (saveParameterNames) {
 925                         // pick up parameter names from the variable table
 926                         List<Name> parameterNames = List.nil();
 927                         int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;
 928                         int endParam = firstParam + Code.width(sym.type.getParameterTypes());
 929                         int numEntries = nextChar();
 930                         for (int i=0; i<numEntries; i++) {
 931                             int start_pc = nextChar();
 932                             int length = nextChar();
 933                             int nameIndex = nextChar();
 934                             int sigIndex = nextChar();
 935                             int register = nextChar();
 936                             if (start_pc == 0 &&
 937                                 firstParam <= register &&
 938                                 register < endParam) {
 939                                 int index = firstParam;
 940                                 for (Type t : sym.type.getParameterTypes()) {
 941                                     if (index == register) {
 942                                         parameterNames = parameterNames.prepend(readName(nameIndex));
 943                                         break;
 944                                     }
 945                                     index += Code.width(t);
 946                                 }
 947                             }
 948                         }
 949                         parameterNames = parameterNames.reverse();
 950                         ((MethodSymbol)sym).savedParameterNames = parameterNames;
 951                     }
 952                     bp = newbp;
 953                 }
 954             },
 955 
 956             new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) {
 957                 void read(Symbol sym, int attrLen) {
 958                     ClassSymbol c = (ClassSymbol) sym;
 959                     Name n = readName(nextChar());
 960                     c.sourcefile = new SourceFileObject(n, c.flatname);
 961                 }
 962             },
 963 
 964             new AttributeReader(names.Synthetic, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
 965                 void read(Symbol sym, int attrLen) {
 966                     // bridge methods are visible when generics not enabled
 967                     if (allowGenerics || (sym.flags_field & BRIDGE) == 0)
 968                         sym.flags_field |= SYNTHETIC;
 969                 }
 970             },
 971 


1822         return v;
1823     }
1824 
1825     /** Read a method.
1826      */
1827     MethodSymbol readMethod() {
1828         long flags = adjustMethodFlags(nextChar());
1829         Name name = readName(nextChar());
1830         Type type = readType(nextChar());
1831         if (name == names.init && currentOwner.hasOuterInstance()) {
1832             // Sometimes anonymous classes don't have an outer
1833             // instance, however, there is no reliable way to tell so
1834             // we never strip this$n
1835             if (!currentOwner.name.isEmpty())
1836                 type = new MethodType(type.getParameterTypes().tail,
1837                                       type.getReturnType(),
1838                                       type.getThrownTypes(),
1839                                       syms.methodClass);
1840         }
1841         MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner);


1842         Symbol prevOwner = currentOwner;
1843         currentOwner = m;
1844         try {
1845             readMemberAttrs(m);
1846         } finally {
1847             currentOwner = prevOwner;
1848         }


1849         return m;
1850     }
1851 



















































1852     /** Skip a field or method
1853      */
1854     void skipMember() {
1855         bp = bp + 6;
1856         char ac = nextChar();
1857         for (int i = 0; i < ac; i++) {
1858             bp = bp + 2;
1859             int attrLen = nextInt();
1860             bp = bp + attrLen;
1861         }
1862     }
1863 
1864     /** Enter type variables of this classtype and all enclosing ones in
1865      *  `typevars'.
1866      */
1867     protected void enterTypevars(Type t) {
1868         if (t.getEnclosingType() != null && t.getEnclosingType().tag == CLASS)
1869             enterTypevars(t.getEnclosingType());
1870         for (List<Type> xs = t.getTypeArguments(); xs.nonEmpty(); xs = xs.tail)
1871             typevars.enter(xs.head.tsym);




  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package com.sun.tools.javac.jvm;
  27 
  28 import java.io.*;
  29 import java.net.URI;
  30 import java.net.URISyntaxException;
  31 import java.nio.CharBuffer;
  32 import java.util.Arrays;
  33 import java.util.EnumSet;
  34 import java.util.HashMap;
  35 import java.util.Map;
  36 import java.util.Set;
  37 import javax.lang.model.SourceVersion;
  38 import javax.tools.JavaFileObject;
  39 import javax.tools.JavaFileManager;
  40 import javax.tools.JavaFileManager.Location;
  41 import javax.tools.StandardJavaFileManager;
  42 
  43 import static javax.tools.StandardLocation.*;
  44 
  45 import com.sun.tools.javac.comp.Annotate;
  46 import com.sun.tools.javac.code.*;
  47 import com.sun.tools.javac.code.Type.*;
  48 import com.sun.tools.javac.code.Symbol.*;
  49 import com.sun.tools.javac.code.Symtab;
  50 import com.sun.tools.javac.file.BaseFileObject;
  51 import com.sun.tools.javac.util.*;
  52 


 175     int bp;
 176 
 177     /** The objects of the constant pool.
 178      */
 179     Object[] poolObj;
 180 
 181     /** For every constant pool entry, an index into buf where the
 182      *  defining section of the entry is found.
 183      */
 184     int[] poolIdx;
 185 
 186     /** The major version number of the class file being read. */
 187     int majorVersion;
 188     /** The minor version number of the class file being read. */
 189     int minorVersion;
 190 
 191     /** Switch: debug output for JSR 308-related operations.
 192      */
 193     boolean debugJSR308;
 194 
 195     /** A table to hold the constant pool indices for method parameter
 196      * names, as given in LocalVariableTable attributes.
 197      */
 198     int[] parameterNameIndices;
 199 
 200     /** Get the ClassReader instance for this invocation. */
 201     public static ClassReader instance(Context context) {
 202         ClassReader instance = context.get(classReaderKey);
 203         if (instance == null)
 204             instance = new ClassReader(context, true);
 205         return instance;
 206     }
 207 
 208     /** Initialize classes and packages, treating this as the definitive classreader. */
 209     public void init(Symtab syms) {
 210         init(syms, true);
 211     }
 212 
 213     /** Initialize classes and packages, optionally treating this as
 214      *  the definitive classreader.
 215      */
 216     private void init(Symtab syms, boolean definitive) {
 217         if (classes != null) return;
 218 
 219         if (definitive) {


 912                     List<Type> thrown = List.nil();
 913                     for (int j = 0; j < nexceptions; j++)
 914                         thrown = thrown.prepend(readClassSymbol(nextChar()).type);
 915                     if (sym.type.getThrownTypes().isEmpty())
 916                         sym.type.asMethodType().thrown = thrown.reverse();
 917                 }
 918             },
 919 
 920             new AttributeReader(names.InnerClasses, V45_3, CLASS_ATTRIBUTE) {
 921                 void read(Symbol sym, int attrLen) {
 922                     ClassSymbol c = (ClassSymbol) sym;
 923                     readInnerClasses(c);
 924                 }
 925             },
 926 
 927             new AttributeReader(names.LocalVariableTable, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
 928                 void read(Symbol sym, int attrLen) {
 929                     int newbp = bp + attrLen;
 930                     if (saveParameterNames) {
 931                         // pick up parameter names from the variable table



 932                         int numEntries = nextChar();
 933                         for (int i = 0; i < numEntries; i++) {
 934                             int start_pc = nextChar();
 935                             int length = nextChar();
 936                             int nameIndex = nextChar();
 937                             int sigIndex = nextChar();
 938                             int register = nextChar();
 939                             if (start_pc == 0) {
 940                                 // ensure array large enough
 941                                 if (register >= parameterNameIndices.length) {
 942                                     int newSize = Math.max(register, parameterNameIndices.length + 8);
 943                                     parameterNameIndices =
 944                                             Arrays.copyOf(parameterNameIndices, newSize);


 945                                 }
 946                                 parameterNameIndices[register] = nameIndex;
 947                             }
 948                         }
 949                     }



 950                     bp = newbp;
 951                 }
 952             },
 953 
 954             new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) {
 955                 void read(Symbol sym, int attrLen) {
 956                     ClassSymbol c = (ClassSymbol) sym;
 957                     Name n = readName(nextChar());
 958                     c.sourcefile = new SourceFileObject(n, c.flatname);
 959                 }
 960             },
 961 
 962             new AttributeReader(names.Synthetic, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
 963                 void read(Symbol sym, int attrLen) {
 964                     // bridge methods are visible when generics not enabled
 965                     if (allowGenerics || (sym.flags_field & BRIDGE) == 0)
 966                         sym.flags_field |= SYNTHETIC;
 967                 }
 968             },
 969 


1820         return v;
1821     }
1822 
1823     /** Read a method.
1824      */
1825     MethodSymbol readMethod() {
1826         long flags = adjustMethodFlags(nextChar());
1827         Name name = readName(nextChar());
1828         Type type = readType(nextChar());
1829         if (name == names.init && currentOwner.hasOuterInstance()) {
1830             // Sometimes anonymous classes don't have an outer
1831             // instance, however, there is no reliable way to tell so
1832             // we never strip this$n
1833             if (!currentOwner.name.isEmpty())
1834                 type = new MethodType(type.getParameterTypes().tail,
1835                                       type.getReturnType(),
1836                                       type.getThrownTypes(),
1837                                       syms.methodClass);
1838         }
1839         MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner);
1840         if (saveParameterNames)
1841             initParameterNames(m);
1842         Symbol prevOwner = currentOwner;
1843         currentOwner = m;
1844         try {
1845             readMemberAttrs(m);
1846         } finally {
1847             currentOwner = prevOwner;
1848         }
1849         if (saveParameterNames)
1850             setParameterNames(m, type);
1851         return m;
1852     }
1853 
1854     void initParameterNames(MethodSymbol sym) {
1855         // make allowance for synthetic parameters.
1856         final int excessSlots = 4;
1857         int expectedParameterSlots =
1858                 Code.width(sym.type.getParameterTypes()) + excessSlots;
1859         if (parameterNameIndices == null
1860                 || parameterNameIndices.length < expectedParameterSlots) {
1861             parameterNameIndices = new int[expectedParameterSlots];
1862         } else
1863             Arrays.fill(parameterNameIndices, 0);
1864     }
1865 
1866     void setParameterNames(MethodSymbol sym, Type jvmType) {
1867         int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;
1868         // the code in readMethod may have skipped the first parameter when
1869         // setting up the MethodType. If so, we make a corresponding allowance
1870         // here for the position of the first parameter.  Note that this
1871         // assumes the skipped parameter has a width of 1 -- i.e. it is not
1872         // a double width type (long or double.)
1873         if (sym.name == names.init && currentOwner.hasOuterInstance()) {
1874             // Sometimes anonymous classes don't have an outer
1875             // instance, however, there is no reliable way to tell so
1876             // we never strip this$n
1877             if (!currentOwner.name.isEmpty())
1878                 firstParam += 1;
1879         }
1880 
1881         if (sym.type != jvmType) {
1882             // reading the method attributes has caused the symbol's type to
1883             // be changed. (i.e. the Signature attribute.)  This may happen if
1884             // there are hidden (synthetic) parameters in the descriptor, but
1885             // not in the Signature.  The position of these hidden parameters
1886             // is unspecified; for now, assume they are at the beginning, and
1887             // so skip over them. The primary case for this is two hidden
1888             // parameters passed into Enum constructors.
1889             int skip = Code.width(jvmType.getParameterTypes())
1890                     - Code.width(sym.type.getParameterTypes());
1891             firstParam += skip;
1892         }
1893         List<Name> paramNames = List.nil();
1894         int index = firstParam;
1895         for (Type t: sym.type.getParameterTypes()) {
1896             int nameIdx = (index < parameterNameIndices.length
1897                     ? parameterNameIndices[index] : 0);
1898             Name name = nameIdx == 0 ? names.empty : readName(nameIdx);
1899             paramNames = paramNames.prepend(name);
1900             index += Code.width(t);
1901         }
1902         sym.savedParameterNames = paramNames.reverse();
1903     }
1904 
1905     /** Skip a field or method
1906      */
1907     void skipMember() {
1908         bp = bp + 6;
1909         char ac = nextChar();
1910         for (int i = 0; i < ac; i++) {
1911             bp = bp + 2;
1912             int attrLen = nextInt();
1913             bp = bp + attrLen;
1914         }
1915     }
1916 
1917     /** Enter type variables of this classtype and all enclosing ones in
1918      *  `typevars'.
1919      */
1920     protected void enterTypevars(Type t) {
1921         if (t.getEnclosingType() != null && t.getEnclosingType().tag == CLASS)
1922             enterTypevars(t.getEnclosingType());
1923         for (List<Type> xs = t.getTypeArguments(); xs.nonEmpty(); xs = xs.tail)
1924             typevars.enter(xs.head.tsym);