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

changeset 428
2485f5641ed0
parent 424
86b773b7cb40
child 484
732510cc3538
equal deleted inserted replaced
427:6ba399eff2cb 428:2485f5641ed0
27 27
28 import java.io.*; 28 import java.io.*;
29 import java.net.URI; 29 import java.net.URI;
30 import java.net.URISyntaxException; 30 import java.net.URISyntaxException;
31 import java.nio.CharBuffer; 31 import java.nio.CharBuffer;
32 import java.util.Arrays;
32 import java.util.EnumSet; 33 import java.util.EnumSet;
33 import java.util.HashMap; 34 import java.util.HashMap;
34 import java.util.Map; 35 import java.util.Map;
35 import java.util.Set; 36 import java.util.Set;
36 import javax.lang.model.SourceVersion; 37 import javax.lang.model.SourceVersion;
188 int minorVersion; 189 int minorVersion;
189 190
190 /** Switch: debug output for JSR 308-related operations. 191 /** Switch: debug output for JSR 308-related operations.
191 */ 192 */
192 boolean debugJSR308; 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 /**
201 * Whether or not any parameter names have been found.
202 */
203 boolean haveParameterNameIndices;
193 204
194 /** Get the ClassReader instance for this invocation. */ 205 /** Get the ClassReader instance for this invocation. */
195 public static ClassReader instance(Context context) { 206 public static ClassReader instance(Context context) {
196 ClassReader instance = context.get(classReaderKey); 207 ClassReader instance = context.get(classReaderKey);
197 if (instance == null) 208 if (instance == null)
920 931
921 new AttributeReader(names.LocalVariableTable, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) { 932 new AttributeReader(names.LocalVariableTable, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
922 void read(Symbol sym, int attrLen) { 933 void read(Symbol sym, int attrLen) {
923 int newbp = bp + attrLen; 934 int newbp = bp + attrLen;
924 if (saveParameterNames) { 935 if (saveParameterNames) {
925 // pick up parameter names from the variable table 936 // Pick up parameter names from the variable table.
926 List<Name> parameterNames = List.nil(); 937 // Parameter names are not explicitly identified as such,
927 int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0; 938 // but all parameter name entries in the LocalVariableTable
928 int endParam = firstParam + Code.width(sym.type.getParameterTypes()); 939 // have a start_pc of 0. Therefore, we record the name
940 // indicies of all slots with a start_pc of zero in the
941 // parameterNameIndicies array.
942 // Note that this implicitly honors the JVMS spec that
943 // there may be more than one LocalVariableTable, and that
944 // there is no specified ordering for the entries.
929 int numEntries = nextChar(); 945 int numEntries = nextChar();
930 for (int i=0; i<numEntries; i++) { 946 for (int i = 0; i < numEntries; i++) {
931 int start_pc = nextChar(); 947 int start_pc = nextChar();
932 int length = nextChar(); 948 int length = nextChar();
933 int nameIndex = nextChar(); 949 int nameIndex = nextChar();
934 int sigIndex = nextChar(); 950 int sigIndex = nextChar();
935 int register = nextChar(); 951 int register = nextChar();
936 if (start_pc == 0 && 952 if (start_pc == 0) {
937 firstParam <= register && 953 // ensure array large enough
938 register < endParam) { 954 if (register >= parameterNameIndices.length) {
939 int index = firstParam; 955 int newSize = Math.max(register, parameterNameIndices.length + 8);
940 for (Type t : sym.type.getParameterTypes()) { 956 parameterNameIndices =
941 if (index == register) { 957 Arrays.copyOf(parameterNameIndices, newSize);
942 parameterNames = parameterNames.prepend(readName(nameIndex));
943 break;
944 }
945 index += Code.width(t);
946 } 958 }
959 parameterNameIndices[register] = nameIndex;
960 haveParameterNameIndices = true;
947 } 961 }
948 } 962 }
949 parameterNames = parameterNames.reverse();
950 ((MethodSymbol)sym).savedParameterNames = parameterNames;
951 } 963 }
952 bp = newbp; 964 bp = newbp;
953 } 965 }
954 }, 966 },
955 967
1837 type.getReturnType(), 1849 type.getReturnType(),
1838 type.getThrownTypes(), 1850 type.getThrownTypes(),
1839 syms.methodClass); 1851 syms.methodClass);
1840 } 1852 }
1841 MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner); 1853 MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner);
1854 if (saveParameterNames)
1855 initParameterNames(m);
1842 Symbol prevOwner = currentOwner; 1856 Symbol prevOwner = currentOwner;
1843 currentOwner = m; 1857 currentOwner = m;
1844 try { 1858 try {
1845 readMemberAttrs(m); 1859 readMemberAttrs(m);
1846 } finally { 1860 } finally {
1847 currentOwner = prevOwner; 1861 currentOwner = prevOwner;
1848 } 1862 }
1863 if (saveParameterNames)
1864 setParameterNames(m, type);
1849 return m; 1865 return m;
1866 }
1867
1868 /**
1869 * Init the parameter names array.
1870 * Parameter names are currently inferred from the names in the
1871 * LocalVariableTable attributes of a Code attribute.
1872 * (Note: this means parameter names are currently not available for
1873 * methods without a Code attribute.)
1874 * This method initializes an array in which to store the name indexes
1875 * of parameter names found in LocalVariableTable attributes. It is
1876 * slightly supersized to allow for additional slots with a start_pc of 0.
1877 */
1878 void initParameterNames(MethodSymbol sym) {
1879 // make allowance for synthetic parameters.
1880 final int excessSlots = 4;
1881 int expectedParameterSlots =
1882 Code.width(sym.type.getParameterTypes()) + excessSlots;
1883 if (parameterNameIndices == null
1884 || parameterNameIndices.length < expectedParameterSlots) {
1885 parameterNameIndices = new int[expectedParameterSlots];
1886 } else
1887 Arrays.fill(parameterNameIndices, 0);
1888 haveParameterNameIndices = false;
1889 }
1890
1891 /**
1892 * Set the parameter names for a symbol from the name index in the
1893 * parameterNameIndicies array. The type of the symbol may have changed
1894 * while reading the method attributes (see the Signature attribute).
1895 * This may be because of generic information or because anonymous
1896 * synthetic parameters were added. The original type (as read from
1897 * the method descriptor) is used to help guess the existence of
1898 * anonymous synthetic parameters.
1899 * On completion, sym.savedParameter names will either be null (if
1900 * no parameter names were found in the class file) or will be set to a
1901 * list of names, one per entry in sym.type.getParameterTypes, with
1902 * any missing names represented by the empty name.
1903 */
1904 void setParameterNames(MethodSymbol sym, Type jvmType) {
1905 // if no names were found in the class file, there's nothing more to do
1906 if (!haveParameterNameIndices)
1907 return;
1908
1909 int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;
1910 // the code in readMethod may have skipped the first parameter when
1911 // setting up the MethodType. If so, we make a corresponding allowance
1912 // here for the position of the first parameter. Note that this
1913 // assumes the skipped parameter has a width of 1 -- i.e. it is not
1914 // a double width type (long or double.)
1915 if (sym.name == names.init && currentOwner.hasOuterInstance()) {
1916 // Sometimes anonymous classes don't have an outer
1917 // instance, however, there is no reliable way to tell so
1918 // we never strip this$n
1919 if (!currentOwner.name.isEmpty())
1920 firstParam += 1;
1921 }
1922
1923 if (sym.type != jvmType) {
1924 // reading the method attributes has caused the symbol's type to
1925 // be changed. (i.e. the Signature attribute.) This may happen if
1926 // there are hidden (synthetic) parameters in the descriptor, but
1927 // not in the Signature. The position of these hidden parameters
1928 // is unspecified; for now, assume they are at the beginning, and
1929 // so skip over them. The primary case for this is two hidden
1930 // parameters passed into Enum constructors.
1931 int skip = Code.width(jvmType.getParameterTypes())
1932 - Code.width(sym.type.getParameterTypes());
1933 firstParam += skip;
1934 }
1935 List<Name> paramNames = List.nil();
1936 int index = firstParam;
1937 for (Type t: sym.type.getParameterTypes()) {
1938 int nameIdx = (index < parameterNameIndices.length
1939 ? parameterNameIndices[index] : 0);
1940 Name name = nameIdx == 0 ? names.empty : readName(nameIdx);
1941 paramNames = paramNames.prepend(name);
1942 index += Code.width(t);
1943 }
1944 sym.savedParameterNames = paramNames.reverse();
1850 } 1945 }
1851 1946
1852 /** Skip a field or method 1947 /** Skip a field or method
1853 */ 1948 */
1854 void skipMember() { 1949 void skipMember() {

mercurial