if (length < 12) {
return throwSeverelyTruncated();
}
ByteArray bytes = cf.getBytes();
ConstantPool pool = cf.getConstantPool();
int maxStack = bytes.getUnsignedShort(offset); // u2 max_stack
int maxLocals = bytes.getUnsignedShort(offset + 2); // u2 max_locals
int codeLength = bytes.getInt(offset + 4); // u4 code_length
int origOffset = offset;
if (observer != null) {
observer.parsed(bytes, offset, 2,
"max_stack: " + Hex.u2(maxStack));
observer.parsed(bytes, offset + 2, 2,
"max_locals: " + Hex.u2(maxLocals));
observer.parsed(bytes, offset + 4, 4,
"code_length: " + Hex.u4(codeLength));
}
offset += 8;
length -= 8;
if (length < (codeLength + 4)) {
return throwTruncated();
}
int codeOffset = offset;
offset += codeLength;
length -= codeLength;
BytecodeArray code =
new BytecodeArray(bytes.slice(codeOffset, codeOffset + codeLength),
pool);
if (observer != null) {
code.forEach(new CodeObserver(code.getBytes(), observer));
}
// u2 exception_table_length
int exceptionTableLength = bytes.getUnsignedShort(offset);
ByteCatchList catches = (exceptionTableLength == 0) ?
ByteCatchList.EMPTY :
new ByteCatchList(exceptionTableLength);
if (observer != null) {
observer.parsed(bytes, offset, 2,
"exception_table_length: " +
Hex.u2(exceptionTableLength));
}
offset += 2;
length -= 2;
if (length < (exceptionTableLength * 8 + 2)) {
return throwTruncated();
}
for (int i = 0; i < exceptionTableLength; i++) {
if (observer != null) {
observer.changeIndent(1);
}
int startPc = bytes.getUnsignedShort(offset);
int endPc = bytes.getUnsignedShort(offset + 2);
int handlerPc = bytes.getUnsignedShort(offset + 4);
int catchTypeIdx = bytes.getUnsignedShort(offset + 6);
CstType catchType = (CstType) pool.get0Ok(catchTypeIdx);
catches.set(i, startPc, endPc, handlerPc, catchType);
if (observer != null) {
observer.parsed(bytes, offset, 8,
Hex.u2(startPc) + ".." + Hex.u2(endPc) +
" -> " + Hex.u2(handlerPc) + " " +