📄 classreader.java
字号:
if ( typeTable != null ) {
for ( int a = 0; a < typeTable.length; a += 3 ) {
if ( typeTable[a] == start && typeTable[a + 1] == index ) {
vsignature = readUTF8( typeTable[a + 2],
c );
break;
}
}
}
mv.visitLocalVariable( readUTF8( w + 4,
c ),
readUTF8( w + 6,
c ),
vsignature,
labels[start],
labels[start + length],
index );
w += 10;
}
}
// visits the other attributes
while ( cattrs != null ) {
attr = cattrs.next;
cattrs.next = null;
mv.visitAttribute( cattrs );
cattrs = attr;
}
// visits the max stack and max locals values
mv.visitMaxs( maxStack,
maxLocals );
}
if ( mv != null ) {
mv.visitEnd();
}
}
// visits the end of the class
classVisitor.visitEnd();
}
/**
* Reads parameter annotations and makes the given visitor visit them.
*
* @param v start offset in {@link #b b} of the annotations to be read.
* @param buf buffer to be used to call {@link #readUTF8 readUTF8},
* {@link #readClass(int,char[]) readClass} or
* {@link #readConst readConst}.
* @param visible <tt>true</tt> if the annotations to be read are visible
* at runtime.
* @param mv the visitor that must visit the annotations.
*/
private void readParameterAnnotations(int v,
final char[] buf,
final boolean visible,
final MethodVisitor mv) {
final int n = this.b[v++] & 0xFF;
for ( int i = 0; i < n; ++i ) {
int j = readUnsignedShort( v );
v += 2;
for ( ; j > 0; --j ) {
final String desc = readUTF8( v,
buf );
v += 2;
final AnnotationVisitor av = mv.visitParameterAnnotation( i,
desc,
visible );
v = readAnnotationValues( v,
buf,
av );
}
}
}
/**
* Reads the values of an annotation and makes the given visitor visit them.
*
* @param v the start offset in {@link #b b} of the values to be read
* (including the unsigned short that gives the number of values).
* @param buf buffer to be used to call {@link #readUTF8 readUTF8},
* {@link #readClass(int,char[]) readClass} or
* {@link #readConst readConst}.
* @param av the visitor that must visit the values.
* @return the end offset of the annotations values.
*/
private int readAnnotationValues(int v,
final char[] buf,
final AnnotationVisitor av) {
int i = readUnsignedShort( v );
v += 2;
for ( ; i > 0; --i ) {
final String name = readUTF8( v,
buf );
v += 2;
v = readAnnotationValue( v,
buf,
name,
av );
}
av.visitEnd();
return v;
}
/**
* Reads a value of an annotation and makes the given visitor visit it.
*
* @param v the start offset in {@link #b b} of the value to be read (<i>not
* including the value name constant pool index</i>).
* @param buf buffer to be used to call {@link #readUTF8 readUTF8},
* {@link #readClass(int,char[]) readClass} or
* {@link #readConst readConst}.
* @param name the name of the value to be read.
* @param av the visitor that must visit the value.
* @return the end offset of the annotation value.
*/
private int readAnnotationValue(int v,
final char[] buf,
final String name,
final AnnotationVisitor av) {
int i;
switch ( readByte( v++ ) ) {
case 'I' : // pointer to CONSTANT_Integer
case 'J' : // pointer to CONSTANT_Long
case 'F' : // pointer to CONSTANT_Float
case 'D' : // pointer to CONSTANT_Double
av.visit( name,
readConst( readUnsignedShort( v ),
buf ) );
v += 2;
break;
case 'B' : // pointer to CONSTANT_Byte
av.visit( name,
new Byte( (byte) readInt( this.items[readUnsignedShort( v )] ) ) );
v += 2;
break;
case 'Z' : // pointer to CONSTANT_Boolean
final boolean b = readInt( this.items[readUnsignedShort( v )] ) == 0;
av.visit( name,
b ? Boolean.FALSE : Boolean.TRUE );
v += 2;
break;
case 'S' : // pointer to CONSTANT_Short
av.visit( name,
new Short( (short) readInt( this.items[readUnsignedShort( v )] ) ) );
v += 2;
break;
case 'C' : // pointer to CONSTANT_Char
av.visit( name,
new Character( (char) readInt( this.items[readUnsignedShort( v )] ) ) );
v += 2;
break;
case 's' : // pointer to CONSTANT_Utf8
av.visit( name,
readUTF8( v,
buf ) );
v += 2;
break;
case 'e' : // enum_const_value
av.visitEnum( name,
readUTF8( v,
buf ),
readUTF8( v + 2,
buf ) );
v += 4;
break;
case 'c' : // class_info
av.visit( name,
Type.getType( readUTF8( v,
buf ) ) );
v += 2;
break;
case '@' : // annotation_value
final String desc = readUTF8( v,
buf );
v += 2;
v = readAnnotationValues( v,
buf,
av.visitAnnotation( name,
desc ) );
break;
case '[' : // array_value
final int size = readUnsignedShort( v );
v += 2;
if ( size == 0 ) {
av.visitArray( name ).visitEnd();
return v;
}
switch ( readByte( v++ ) ) {
case 'B' :
final byte[] bv = new byte[size];
for ( i = 0; i < size; i++ ) {
bv[i] = (byte) readInt( this.items[readUnsignedShort( v )] );
v += 3;
}
av.visit( name,
bv );
--v;
break;
case 'Z' :
final boolean[] zv = new boolean[size];
for ( i = 0; i < size; i++ ) {
zv[i] = readInt( this.items[readUnsignedShort( v )] ) != 0;
v += 3;
}
av.visit( name,
zv );
--v;
break;
case 'S' :
final short[] sv = new short[size];
for ( i = 0; i < size; i++ ) {
sv[i] = (short) readInt( this.items[readUnsignedShort( v )] );
v += 3;
}
av.visit( name,
sv );
--v;
break;
case 'C' :
final char[] cv = new char[size];
for ( i = 0; i < size; i++ ) {
cv[i] = (char) readInt( this.items[readUnsignedShort( v )] );
v += 3;
}
av.visit( name,
cv );
--v;
break;
case 'I' :
final int[] iv = new int[size];
for ( i = 0; i < size; i++ ) {
iv[i] = readInt( this.items[readUnsignedShort( v )] );
v += 3;
}
av.visit( name,
iv );
--v;
break;
case 'J' :
final long[] lv = new long[size];
for ( i = 0; i < size; i++ ) {
lv[i] = readLong( this.items[readUnsignedShort( v )] );
v += 3;
}
av.visit( name,
lv );
--v;
break;
case 'F' :
final float[] fv = new float[size];
for ( i = 0; i < size; i++ ) {
fv[i] = Float.intBitsToFloat( readInt( this.items[readUnsignedShort( v )] ) );
v += 3;
}
av.visit( name,
fv );
--v;
break;
case 'D' :
final double[] dv = new double[size];
for ( i = 0; i < size; i++ ) {
dv[i] = Double.longBitsToDouble( readLong( this.items[readUnsignedShort( v )] ) );
v += 3;
}
av.visit( name,
dv );
--v;
break;
default :
v--;
final AnnotationVisitor aav = av.visitArray( name );
for ( i = size; i > 0; --i ) {
v = readAnnotationValue( v,
buf,
null,
aav );
}
aav.visitEnd();
}
}
return v;
}
/**
* Reads an attribute in {@link #b b}.
*
* @param attrs prototypes of the attributes that must be parsed during the
* visit of the class. Any attribute whose type is not equal to the
* type of one the prototypes is ignored (i.e. an empty
* {@link Attribute} instance is returned).
* @param type the type of the attribute.
* @param off index of the first byte of the attribute's content in
* {@link #b b}. The 6 attribute header bytes, containing the type
* and the length of the attribute, are not taken into account here
* (they have already been read).
* @param len the length of the attribute's content.
* @param buf buffer to be
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -