private void populateExceptionHandlerInfo(final InstructionCollection body, final List<ExceptionTableEntry> exceptionTable) {
if (body.isEmpty()) {
return;
}
final Instruction bodyEndInstruction = body.get(body.size() - 1);
final List<HandlerWithRange> entries = new ArrayList<>(exceptionTable.size());
for (final ExceptionTableEntry entry : exceptionTable) {
entries.add(
new HandlerWithRange(
entry,
new Range(entry.getHandlerOffset(), Integer.MAX_VALUE)
)
);
}
// Collections.sort(entries);
final ControlFlowGraph cfg = ControlFlowGraphBuilder.build(body, Collections.<ExceptionHandler>emptyList());
cfg.computeDominance();
cfg.computeDominanceFrontier();
final List<ControlFlowNode> nodes = cfg.getNodes();
final Map<Instruction, ControlFlowNode> nodeLookup = new IdentityHashMap<>();
for (int j = 0; j < nodes.size(); j++) {
final ControlFlowNode node = nodes.get(j);
if (node.getNodeType() != ControlFlowNodeType.Normal) {
continue;
}
for (Instruction i = node.getStart();
i != null && i.getOffset() < node.getEnd().getEndOffset();
i = i.getNext()) {
nodeLookup.put(i, node);
}
}
for (int i = 0; i < entries.size(); i++) {
int minOffset = Integer.MAX_VALUE;
final HandlerWithRange entry = entries.get(i);
ControlFlowNode tryEnd = null;
for (int j = 0; j < nodes.size(); j++) {
final ControlFlowNode node = nodes.get(j);
final Instruction end = node.getEnd();
if (end != null && end.getOffset() == entry.entry.getEndOffset()) {
final Instruction previousInstruction = node.getStart().getPrevious();
final HandlerWithRange nearestHandler = findNearestHandler(entries, entry);
final Instruction firstHandlerInstruction = body.atOffset(nearestHandler.range.getStart());
if (end.getOpCode() == OpCode.GOTO && end.getNext() == firstHandlerInstruction) {
tryEnd = nodeLookup.get(end);
}
else if (previousInstruction != null) {
tryEnd = nodeLookup.get(previousInstruction);
}
break;
}
}
for (int j = 0; j < nodes.size(); j++) {
final ControlFlowNode node = nodes.get(j);
if (node.getNodeType() != ControlFlowNodeType.Normal) {
continue;
}
if (node.getStart().getOffset() == entry.range.getStart()) {
final ControlFlowNode end = findHandlerEnd(node, tryEnd, new LinkedHashSet<ControlFlowNode>(), cfg.getRegularExit());
if (end != null && end.getNodeType() == ControlFlowNodeType.Normal) {
minOffset = end.getEnd().getEndOffset();
}
else {
minOffset = node.getEnd().getEndOffset();
}
for (int k = 0; k < entries.size(); k++) {
final HandlerWithRange other = entries.get(k);
if (k != i &&
entry.entry.getStartOffset() >= other.entry.getStartOffset() &&
entry.entry.getHandlerOffset() < other.entry.getHandlerOffset() &&
entry.entry.getEndOffset() <= other.entry.getEndOffset() &&
other.range.getStart() < minOffset) {
minOffset = other.range.getStart();
}
}
break;
}
}
if (minOffset != Integer.MAX_VALUE) {
entry.range.setEnd(minOffset);
}
}
// Collections.sort(entries);
final List<ExceptionHandler> exceptionHandlers = _methodBody.getExceptionHandlers();
for (final HandlerWithRange entry : entries) {
final int startOffset = entry.entry.getStartOffset();
final int endOffset = entry.entry.getEndOffset();
final int handlerStart = entry.range.getStart();
final int handlerEnd = entry.range.getEnd();
final TypeReference catchType = entry.entry.getCatchType();
final Instruction firstInstruction = body.tryGetAtOffset(startOffset);
final Instruction lastInstruction;
final Instruction handlerFirstInstruction = body.tryGetAtOffset(handlerStart);
final Instruction handlerLastInstruction;
if (endOffset <= bodyEndInstruction.getOffset()) {
lastInstruction = body.tryGetAtOffset(endOffset).getPrevious();
}
else if (endOffset == bodyEndInstruction.getEndOffset()) {
lastInstruction = bodyEndInstruction;
}
else {
lastInstruction = new Instruction(endOffset, OpCode.NOP);
}
if (handlerEnd <= bodyEndInstruction.getOffset()) {
handlerLastInstruction = body.tryGetAtOffset(handlerEnd).getPrevious();
}
else if (handlerEnd == bodyEndInstruction.getEndOffset()) {
handlerLastInstruction = bodyEndInstruction;
}
else {
handlerLastInstruction = new Instruction(handlerEnd, OpCode.NOP);
}
final ExceptionHandler handler;
if (catchType == null) {