📄 classreader.java
字号:
} else if (attrName.equals("RuntimeVisibleAnnotations")) {
anns = u + 6;
} else if (attrName.equals("RuntimeInvisibleAnnotations")) {
ianns = u + 6;
} else {
attr = readAttribute(attrs,
attrName,
u + 6,
readInt(u + 2),
c,
-1,
null);
if (attr != null) {
attr.next = cattrs;
cattrs = attr;
}
}
u += 6 + readInt(u + 2);
}
// visits the field
FieldVisitor fv = classVisitor.visitField(access,
name,
desc,
signature,
fieldValueItem == 0 ? null : readConst(fieldValueItem, c));
// visits the field annotations and attributes
if (fv != null) {
for (j = 1; j >= 0; --j) {
v = j == 0 ? ianns : anns;
if (v != 0) {
k = readUnsignedShort(v);
v += 2;
for (; k > 0; --k) {
v = readAnnotationValues(v + 2,
c,
true,
fv.visitAnnotation(readUTF8(v, c), j != 0));
}
}
}
while (cattrs != null) {
attr = cattrs.next;
cattrs.next = null;
fv.visitAttribute(cattrs);
cattrs = attr;
}
fv.visitEnd();
}
}
// visits the methods
i = readUnsignedShort(u);
u += 2;
for (; i > 0; --i) {
int u0 = u + 6;
access = readUnsignedShort(u);
name = readUTF8(u + 2, c);
desc = readUTF8(u + 4, c);
signature = null;
anns = 0;
ianns = 0;
int dann = 0;
int mpanns = 0;
int impanns = 0;
cattrs = null;
v = 0;
w = 0;
// looks for Code and Exceptions attributes
j = readUnsignedShort(u + 6);
u += 8;
for (; j > 0; --j) {
attrName = readUTF8(u, c);
int attrSize = readInt(u + 2);
u += 6;
// tests are sorted in decreasing frequency order
// (based on frequencies observed on typical classes)
if (attrName.equals("Code")) {
if (!skipCode) {
v = u;
}
} else if (attrName.equals("Exceptions")) {
w = u;
} else if (attrName.equals("Signature")) {
signature = readUTF8(u, c);
} else if (attrName.equals("Deprecated")) {
access |= Opcodes.ACC_DEPRECATED;
} else if (attrName.equals("RuntimeVisibleAnnotations")) {
anns = u;
} else if (attrName.equals("AnnotationDefault")) {
dann = u;
} else if (attrName.equals("Synthetic")) {
access |= Opcodes.ACC_SYNTHETIC;
} else if (attrName.equals("RuntimeInvisibleAnnotations")) {
ianns = u;
} else if (attrName.equals("RuntimeVisibleParameterAnnotations"))
{
mpanns = u;
} else if (attrName.equals("RuntimeInvisibleParameterAnnotations"))
{
impanns = u;
} else {
attr = readAttribute(attrs,
attrName,
u,
attrSize,
c,
-1,
null);
if (attr != null) {
attr.next = cattrs;
cattrs = attr;
}
}
u += attrSize;
}
// reads declared exceptions
String[] exceptions;
if (w == 0) {
exceptions = null;
} else {
exceptions = new String[readUnsignedShort(w)];
w += 2;
for (j = 0; j < exceptions.length; ++j) {
exceptions[j] = readClass(w, c);
w += 2;
}
}
// visits the method's code, if any
MethodVisitor mv = classVisitor.visitMethod(access,
name,
desc,
signature,
exceptions);
if (mv != null) {
/*
* if the returned MethodVisitor is in fact a MethodWriter, it
* means there is no method adapter between the reader and the
* writer. If, in addition, the writer's constant pool was
* copied from this reader (mw.cw.cr == this), and the signature
* and exceptions of the method have not been changed, then it
* is possible to skip all visit events and just copy the
* original code of the method to the writer (the access, name
* and descriptor can have been changed, this is not important
* since they are not copied as is from the reader).
*/
if (mv instanceof MethodWriter) {
MethodWriter mw = (MethodWriter) mv;
if (mw.cw.cr == this) {
if (signature == mw.signature) {
boolean sameExceptions = false;
if (exceptions == null) {
sameExceptions = mw.exceptionCount == 0;
} else {
if (exceptions.length == mw.exceptionCount) {
sameExceptions = true;
for (j = exceptions.length - 1; j >= 0; --j)
{
w -= 2;
if (mw.exceptions[j] != readUnsignedShort(w))
{
sameExceptions = false;
break;
}
}
}
}
if (sameExceptions) {
/*
* we do not copy directly the code into
* MethodWriter to save a byte array copy
* operation. The real copy will be done in
* ClassWriter.toByteArray().
*/
mw.classReaderOffset = u0;
mw.classReaderLength = u - u0;
continue;
}
}
}
}
if (dann != 0) {
AnnotationVisitor dv = mv.visitAnnotationDefault();
readAnnotationValue(dann, c, null, dv);
if (dv != null) {
dv.visitEnd();
}
}
for (j = 1; j >= 0; --j) {
w = j == 0 ? ianns : anns;
if (w != 0) {
k = readUnsignedShort(w);
w += 2;
for (; k > 0; --k) {
w = readAnnotationValues(w + 2,
c,
true,
mv.visitAnnotation(readUTF8(w, c), j != 0));
}
}
}
if (mpanns != 0) {
readParameterAnnotations(mpanns, c, true, mv);
}
if (impanns != 0) {
readParameterAnnotations(impanns, c, false, mv);
}
while (cattrs != null) {
attr = cattrs.next;
cattrs.next = null;
mv.visitAttribute(cattrs);
cattrs = attr;
}
}
if (mv != null && v != 0) {
int maxStack = readUnsignedShort(v);
int maxLocals = readUnsignedShort(v + 2);
int codeLength = readInt(v + 4);
v += 8;
int codeStart = v;
int codeEnd = v + codeLength;
mv.visitCode();
// 1st phase: finds the labels
int label;
Label[] labels = new Label[codeLength + 1];
while (v < codeEnd) {
int opcode = b[v] & 0xFF;
switch (ClassWriter.TYPE[opcode]) {
case ClassWriter.NOARG_INSN:
case ClassWriter.IMPLVAR_INSN:
v += 1;
break;
case ClassWriter.LABEL_INSN:
label = v - codeStart + readShort(v + 1);
if (labels[label] == null) {
labels[label] = new Label();
}
v += 3;
break;
case ClassWriter.LABELW_INSN:
label = v - codeStart + readInt(v + 1);
if (labels[label] == null) {
labels[label] = new Label();
}
v += 5;
break;
case ClassWriter.WIDE_INSN:
opcode = b[v + 1] & 0xFF;
if (opcode == Opcodes.IINC) {
v += 6;
} else {
v += 4;
}
break;
case ClassWriter.TABL_INSN:
// skips 0 to 3 padding bytes
w = v - codeStart;
v = v + 4 - (w & 3);
// reads instruction
label = w + readInt(v);
if (labels[label] == null) {
labels[label] = new Label();
}
j = readInt(v + 8) - readInt(v + 4) + 1;
v += 12;
for (; j > 0; --j) {
label = w + readInt(v);
v += 4;
if (labels[label] == null) {
labels[label] = new Label();
}
}
break;
case ClassWriter.LOOK_INSN:
// skips 0 to 3 padding bytes
w = v - codeStart;
v = v + 4 - (w & 3);
// reads instruction
label = w + readInt(v);
if (labels[label] == null) {
labels[label] = new Label();
}
j = readInt(v + 4);
v += 8;
for (; j > 0; --j) {
label = w + readInt(v + 4);
v += 8;
if (labels[label] == null) {
labels[label] = new Label();
}
}
break;
case ClassWriter.VAR_INSN:
case ClassWriter.SBYTE_INSN:
case ClassWriter.LDC_INSN:
v += 2;
break;
case ClassWriter.SHORT_INSN:
case ClassWriter.LDCW_INSN:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -