langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
Print this page
*** 27,36 ****
--- 27,37 ----
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.CharBuffer;
+ import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.lang.model.SourceVersion;
*** 189,198 ****
--- 190,204 ----
/** Switch: debug output for JSR 308-related operations.
*/
boolean debugJSR308;
+ /** A table to hold the constant pool indices for method parameter
+ * names, as given in LocalVariableTable attributes.
+ */
+ int[] parameterNameIndices;
+
/** Get the ClassReader instance for this invocation. */
public static ClassReader instance(Context context) {
ClassReader instance = context.get(classReaderKey);
if (instance == null)
instance = new ClassReader(context, true);
*** 921,956 ****
new AttributeReader(names.LocalVariableTable, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
void read(Symbol sym, int attrLen) {
int newbp = bp + attrLen;
if (saveParameterNames) {
// pick up parameter names from the variable table
- List<Name> parameterNames = List.nil();
- int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;
- int endParam = firstParam + Code.width(sym.type.getParameterTypes());
int numEntries = nextChar();
! for (int i=0; i<numEntries; i++) {
int start_pc = nextChar();
int length = nextChar();
int nameIndex = nextChar();
int sigIndex = nextChar();
int register = nextChar();
! if (start_pc == 0 &&
! firstParam <= register &&
! register < endParam) {
! int index = firstParam;
! for (Type t : sym.type.getParameterTypes()) {
! if (index == register) {
! parameterNames = parameterNames.prepend(readName(nameIndex));
! break;
}
! index += Code.width(t);
}
}
}
- parameterNames = parameterNames.reverse();
- ((MethodSymbol)sym).savedParameterNames = parameterNames;
- }
bp = newbp;
}
},
new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) {
--- 927,954 ----
new AttributeReader(names.LocalVariableTable, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
void read(Symbol sym, int attrLen) {
int newbp = bp + attrLen;
if (saveParameterNames) {
// pick up parameter names from the variable table
int numEntries = nextChar();
! for (int i = 0; i < numEntries; i++) {
int start_pc = nextChar();
int length = nextChar();
int nameIndex = nextChar();
int sigIndex = nextChar();
int register = nextChar();
! if (start_pc == 0) {
! // ensure array large enough
! if (register >= parameterNameIndices.length) {
! int newSize = Math.max(register, parameterNameIndices.length + 8);
! parameterNameIndices =
! Arrays.copyOf(parameterNameIndices, newSize);
}
! parameterNameIndices[register] = nameIndex;
}
}
}
bp = newbp;
}
},
new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) {
*** 1837,1856 ****
--- 1835,1909 ----
type.getReturnType(),
type.getThrownTypes(),
syms.methodClass);
}
MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner);
+ if (saveParameterNames)
+ initParameterNames(m);
Symbol prevOwner = currentOwner;
currentOwner = m;
try {
readMemberAttrs(m);
} finally {
currentOwner = prevOwner;
}
+ if (saveParameterNames)
+ setParameterNames(m, type);
return m;
}
+ void initParameterNames(MethodSymbol sym) {
+ // make allowance for synthetic parameters.
+ final int excessSlots = 4;
+ int expectedParameterSlots =
+ Code.width(sym.type.getParameterTypes()) + excessSlots;
+ if (parameterNameIndices == null
+ || parameterNameIndices.length < expectedParameterSlots) {
+ parameterNameIndices = new int[expectedParameterSlots];
+ } else
+ Arrays.fill(parameterNameIndices, 0);
+ }
+
+ void setParameterNames(MethodSymbol sym, Type jvmType) {
+ int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;
+ // the code in readMethod may have skipped the first parameter when
+ // setting up the MethodType. If so, we make a corresponding allowance
+ // here for the position of the first parameter. Note that this
+ // assumes the skipped parameter has a width of 1 -- i.e. it is not
+ // a double width type (long or double.)
+ if (sym.name == names.init && currentOwner.hasOuterInstance()) {
+ // Sometimes anonymous classes don't have an outer
+ // instance, however, there is no reliable way to tell so
+ // we never strip this$n
+ if (!currentOwner.name.isEmpty())
+ firstParam += 1;
+ }
+
+ if (sym.type != jvmType) {
+ // reading the method attributes has caused the symbol's type to
+ // be changed. (i.e. the Signature attribute.) This may happen if
+ // there are hidden (synthetic) parameters in the descriptor, but
+ // not in the Signature. The position of these hidden parameters
+ // is unspecified; for now, assume they are at the beginning, and
+ // so skip over them. The primary case for this is two hidden
+ // parameters passed into Enum constructors.
+ int skip = Code.width(jvmType.getParameterTypes())
+ - Code.width(sym.type.getParameterTypes());
+ firstParam += skip;
+ }
+ List<Name> paramNames = List.nil();
+ int index = firstParam;
+ for (Type t: sym.type.getParameterTypes()) {
+ int nameIdx = (index < parameterNameIndices.length
+ ? parameterNameIndices[index] : 0);
+ Name name = nameIdx == 0 ? names.empty : readName(nameIdx);
+ paramNames = paramNames.prepend(name);
+ index += Code.width(t);
+ }
+ sym.savedParameterNames = paramNames.reverse();
+ }
+
/** Skip a field or method
*/
void skipMember() {
bp = bp + 6;
char ac = nextChar();