📄 classreader.java
字号:
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);
Label start = labels[label];
if (start == null) {
labels[label] = start = new Label();
}
label = readUnsignedShort(v + 2);
Label end = labels[label];
if (end == null) {
labels[label] = end = new Label();
}
label = readUnsignedShort(v + 4);
Label handler = labels[label];
if (handler == null) {
labels[label] = handler = new Label();
}
int type = readUnsignedShort(v + 6);
if (type == 0) {
mv.visitTryCatchBlock(start, end, handler, null);
} else {
mv.visitTryCatchBlock(start,
end,
handler,
readUTF8(items[type], c));
}
v += 8;
}
// parses the local variable, line number tables, and code
// attributes
int varTable = 0;
int varTypeTable = 0;
int stackMap = 0;
int frameCount = 0;
int frameMode = 0;
int frameOffset = 0;
int frameLocalCount = 0;
int frameLocalDiff = 0;
int frameStackCount = 0;
Object[] frameLocal = null;
Object[] frameStack = null;
boolean zip = true;
cattrs = null;
j = readUnsignedShort(v);
v += 2;
for (; j > 0; --j) {
attrName = readUTF8(v, c);
if (attrName.equals("LocalVariableTable")) {
if (!skipDebug) {
varTable = v + 6;
k = readUnsignedShort(v + 6);
w = v + 8;
for (; k > 0; --k) {
label = readUnsignedShort(w);
if (labels[label] == null) {
labels[label] = new Label(true);
}
label += readUnsignedShort(w + 2);
if (labels[label] == null) {
labels[label] = new Label(true);
}
w += 10;
}
}
} else if (attrName.equals("LocalVariableTypeTable")) {
varTypeTable = v + 6;
} 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(true);
}
labels[label].line = readUnsignedShort(w + 2);
w += 4;
}
}
} else if (attrName.equals("StackMapTable")) {
if ((flags & SKIP_FRAMES) == 0) {
stackMap = v + 8;
frameCount = readUnsignedShort(v + 6);
}
/*
* here we do not extract the labels corresponding to
* the attribute content. This would require a full
* parsing of the attribute, which would need to be
* repeated in the second phase (see below). Instead the
* content of the attribute is read one frame at a time
* (i.e. after a frame has been visited, the next frame
* is read), and the labels it contains are also
* extracted one frame at a time. Thanks to the ordering
* of frames, having only a "one frame lookahead" is not
* a problem, i.e. it is not possible to see an offset
* smaller than the offset of the current insn and for
* which no Label exist.
*/
// TODO true for frame offsets,
// but for UNINITIALIZED type offsets?
} else if (attrName.equals("StackMap")) {
if ((flags & SKIP_FRAMES) == 0) {
stackMap = v + 8;
frameCount = readUnsignedShort(v + 6);
zip = false;
}
/*
* IMPORTANT! here we assume that the frames are
* ordered, as in the StackMapTable attribute, although
* this is not guaranteed by the attribute format.
*/
} 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
if (stackMap != 0) {
// creates the very first (implicit) frame from the method
// descriptor
frameLocal = new Object[maxLocals];
frameStack = new Object[maxStack];
if (unzip) {
int local = 0;
if ((access & Opcodes.ACC_STATIC) == 0) {
if (name.equals("<init>")) {
frameLocal[local++] = Opcodes.UNINITIALIZED_THIS;
} else {
frameLocal[local++] = readClass(header + 2, c);
}
}
j = 1;
loop: while (true) {
k = j;
switch (desc.charAt(j++)) {
case 'Z':
case 'C':
case 'B':
case 'S':
case 'I':
frameLocal[local++] = Opcodes.INTEGER;
break;
case 'F':
frameLocal[local++] = Opcodes.FLOAT;
break;
case 'J':
frameLocal[local++] = Opcodes.LONG;
break;
case 'D':
frameLocal[local++] = Opcodes.DOUBLE;
break;
case '[':
while (desc.charAt(j) == '[') {
++j;
}
if (desc.charAt(j) == 'L') {
++j;
while (desc.charAt(j) != ';') {
++j;
}
}
frameLocal[local++] = desc.substring(k, ++j);
break;
case 'L':
while (desc.charAt(j) != ';') {
++j;
}
frameLocal[local++] = desc.substring(k + 1,
j++);
break;
default:
break loop;
}
}
frameLocalCount = local;
}
/*
* for the first explicit frame the offset is not
* offset_delta + 1 but only offset_delta; setting the
* implicit frame offset to -1 allow the use of the
* "offset_delta + 1" rule in all cases
*/
frameOffset = -1;
}
v = codeStart;
Label l;
while (v < codeEnd) {
w = v - codeStart;
l = labels[w];
if (l != null) {
mv.visitLabel(l);
if (!skipDebug && l.line > 0) {
mv.visitLineNumber(l.line, l);
}
}
while (frameLocal != null
&& (frameOffset == w || frameOffset == -1))
{
// if there is a frame for this offset,
// makes the visitor visit it,
// and reads the next frame if there is one.
if (!zip || unzip) {
mv.visitFrame(Opcodes.F_NEW,
frameLocalCount,
frameLocal,
frameStackCount,
frameStack);
} else if (frameOffset != -1) {
mv.visitFrame(frameMode,
frameLocalDiff,
frameLocal,
frameStackCount,
frameStack);
}
if (frameCount > 0) {
int tag, delta, n;
if (zip) {
tag = b[stackMap++] & 0xFF;
} else {
tag = MethodWriter.FULL_FRAME;
frameOffset = -1;
}
frameLocalDiff = 0;
if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME)
{
delta = tag;
frameMode = Opcodes.F_SAME;
frameStackCount = 0;
} else if (tag < MethodWriter.RESERVED) {
delta = tag
- MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
stackMap = readFrameType(frameStack,
0,
stackMap,
c,
labels);
frameMode = Opcodes.F_SAME1;
frameStackCount = 1;
} else {
delta = readUnsignedShort(stackMap);
stackMap += 2;
if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
{
stackMap = readFrameType(frameStack,
0,
stackMap,
c,
labels);
frameMode = Opcodes.F_SAME1;
frameStackCount = 1;
} else if (tag >= MethodWriter.CHOP_FRAME
&& tag < MethodWriter.SAME_FRAME_EXTENDED)
{
frameMode = Opcodes.F_CHOP;
frameLocalDiff = MethodWriter.SAME_FRAME_EXTENDED
- tag;
frameLocalCount -= frameLocalDiff;
frameStackCount = 0;
} else if (tag == MethodWriter.SAME_FRAME_EXTENDED)
{
frameMode = Opcodes.F_SAME;
frameStackCount = 0;
} else if (tag < MethodWriter.FULL_FRAME) {
j = unzip ? frameLocalCount : 0;
for (k = tag
- MethodWriter.SAME_FRAME_EXTENDED; k > 0; k--)
{
stackMap = readFrameType(frameLocal,
j++,
stackMap,
c,
labels);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -