📄 classreader.java
字号:
} else if (attrName.equals("Synthetic")) {
access |= Constants.ACC_SYNTHETIC;
} else if (attrName.equals("Deprecated")) {
access |= Constants.ACC_DEPRECATED;
} else {
attr = readAttribute(
attrs, attrName, u + 6, readInt(u + 2), c, -1, null);
if (attr != null) {
attr.next = fattrs;
fattrs = attr;
}
}
u += 6 + readInt(u + 2);
}
// reads the field's value, if any
Object value = (fieldValueItem == 0 ? null : readConst(fieldValueItem, c));
// visits the field
classVisitor.visitField(access, fieldName, fieldDesc, value, fattrs);
}
// visits the methods
i = readUnsignedShort(u); u += 2;
for ( ; i > 0; --i) {
access = readUnsignedShort(u);
String methName = readUTF8(u + 2, c);
String methDesc = readUTF8(u + 4, c);
Attribute mattrs = null;
Attribute cattrs = null;
v = 0;
w = 0;
// looks for Code and Exceptions attributes
j = readUnsignedShort(u + 6);
u += 8;
for ( ; j > 0; --j) {
String attrName = readUTF8(u, c); u += 2;
int attrSize = readInt(u); u += 4;
if (attrName.equals("Code")) {
v = u;
} else if (attrName.equals("Exceptions")) {
w = u;
} else if (attrName.equals("Synthetic")) {
access |= Constants.ACC_SYNTHETIC;
} else if (attrName.equals("Deprecated")) {
access |= Constants.ACC_DEPRECATED;
} else {
attr = readAttribute(attrs, attrName, u, attrSize, c, -1, null);
if (attr != null) {
attr.next = mattrs;
mattrs = 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
CodeVisitor cv;
cv = classVisitor.visitMethod(
access, methName, methDesc, exceptions, mattrs);
if (cv != 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;
// 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 == Constants.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); v += 4;
if (labels[label] == null) {
labels[label] = new Label();
}
j = readInt(v); v += 4;
j = readInt(v) - j + 1; v += 4;
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); v += 4;
if (labels[label] == null) {
labels[label] = new Label();
}
j = readInt(v); v += 4;
for ( ; j > 0; --j) {
v += 4; // skips key
label = w + readInt(v); v += 4;
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:
case ClassWriter.FIELDORMETH_INSN:
case ClassWriter.TYPE_INSN:
case ClassWriter.IINC_INSN:
v += 3;
break;
case ClassWriter.ITFMETH_INSN:
v += 5;
break;
// case MANA_INSN:
default:
v += 4;
break;
}
}
// parses the try catch entries
j = readUnsignedShort(v); v += 2;
for ( ; j > 0; --j) {
label = readUnsignedShort(v);
if (labels[label] == null) {
labels[label] = new Label();
}
label = readUnsignedShort(v + 2);
if (labels[label] == null) {
labels[label] = new Label();
}
label = readUnsignedShort(v + 4);
if (labels[label] == null) {
labels[label] = new Label();
}
v += 8;
}
// parses the local variable, line number tables, and code attributes
j = readUnsignedShort(v); v += 2;
for ( ; j > 0; --j) {
String attrName = readUTF8(v, c);
if (attrName.equals("LocalVariableTable")) {
if (!skipDebug) {
k = readUnsignedShort(v + 6);
w = v + 8;
for ( ; k > 0; --k) {
label = readUnsignedShort(w);
if (labels[label] == null) {
labels[label] = new Label();
}
label += readUnsignedShort(w + 2);
if (labels[label] == null) {
labels[label] = new Label();
}
w += 10;
}
}
} else if (attrName.equals("LineNumberTable")) {
if (!skipDebug) {
k = readUnsignedShort(v + 6);
w = v + 8;
for ( ; k > 0; --k) {
label = readUnsignedShort(w);
if (labels[label] == null) {
labels[label] = new Label();
}
labels[label].line = readUnsignedShort(w + 2);
w += 4;
}
}
} else {
for (k = 0; k < attrs.length; ++k) {
if (attrs[k].type.equals(attrName)) {
attr = attrs[k].read(
this, v + 6, readInt(v + 2), c, codeStart - 8, labels);
if (attr != null) {
attr.next = cattrs;
cattrs = attr;
}
}
}
}
v += 6 + readInt(v + 2);
}
// 2nd phase: visits each instruction
v = codeStart;
Label l;
while (v < codeEnd) {
w = v - codeStart;
l = labels[w];
if (l != null) {
cv.visitLabel(l);
if (!skipDebug && l.line > 0) {
cv.visitLineNumber(l.line, l);
}
}
int opcode = b[v] & 0xFF;
switch (ClassWriter.TYPE[opcode]) {
case ClassWriter.NOARG_INSN:
cv.visitInsn(opcode);
v += 1;
break;
case ClassWriter.IMPLVAR_INSN:
if (opcode > Constants.ISTORE) {
opcode -= 59; //ISTORE_0
cv.visitVarInsn(Constants.ISTORE + (opcode >> 2), opcode & 0x3);
} else {
opcode -= 26; //ILOAD_0
cv.visitVarInsn(Constants.ILOAD + (opcode >> 2), opcode & 0x3);
}
v += 1;
break;
case ClassWriter.LABEL_INSN:
cv.visitJumpInsn(opcode, labels[w + readShort(v + 1)]);
v += 3;
break;
case ClassWriter.LABELW_INSN:
cv.visitJumpInsn(opcode, labels[w + readInt(v + 1)]);
v += 5;
break;
case ClassWriter.WIDE_INSN:
opcode = b[v + 1] & 0xFF;
if (opcode == Constants.IINC) {
cv.visitIincInsn(readUnsignedShort(v + 2), readShort(v + 4));
v += 6;
} else {
cv.visitVarInsn(opcode, readUnsignedShort(v + 2));
v += 4;
}
break;
case ClassWriter.TABL_INSN:
// skips 0 to 3 padding bytes
v = v + 4 - (w & 3);
// reads instruction
label = w + readInt(v); v += 4;
int min = readInt(v); v += 4;
int max = readInt(v); v += 4;
Label[] table = new Label[max - min + 1];
for (j = 0; j < table.length; ++j) {
table[j] = labels[w + readInt(v)];
v += 4;
}
cv.visitTableSwitchInsn(min, max, labels[label], table);
break;
case ClassWriter.LOOK_INSN:
// skips 0 to 3 padding bytes
v = v + 4 - (w & 3);
// reads instruction
label = w + readInt(v); v += 4;
j = readInt(v); v += 4;
int[] keys = new int[j];
Label[] values = new Label[j];
for (j = 0; j < keys.length; ++j) {
keys[j] = readInt(v); v += 4;
values[j] = labels[w + readInt(v)]; v += 4;
}
cv.visitLookupSwitchInsn(labels[label], keys, values);
break;
case ClassWriter.VAR_INSN:
cv.visitVarInsn(opcode, b[v + 1] & 0xFF);
v += 2;
break;
case ClassWriter.SBYTE_INSN:
cv.visitIntInsn(opcode, b[v + 1]);
v += 2;
break;
case ClassWriter.SHORT_INSN:
cv.visitIntInsn(opcode, readShort(v + 1));
v += 3;
break;
case ClassWriter.LDC_INSN:
cv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c));
v += 2;
break;
case ClassWriter.LDCW_INSN:
cv.visitLdcInsn(readConst(readUnsignedShort(v + 1), c));
v += 3;
break;
case ClassWriter.FIELDORMETH_INSN:
case ClassWriter.ITFMETH_INSN:
int cpIndex = items[readUnsignedShort(v + 1)];
String iowner = readClass(cpIndex, c);
cpIndex = items[readUnsignedShort(cpIndex + 2)];
String iname = readUTF8(cpIndex, c);
String idesc = readUTF8(cpIndex + 2, c);
if (opcode < Constants.INVOKEVIRTUAL) {
cv.visitFieldInsn(opcode, iowner, iname, idesc);
} else {
cv.visitMethodInsn(opcode, iowner, iname, idesc);
}
if (opcode == Constants.INVOKEINTERFACE) {
v += 5;
} else {
v += 3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -