1 package mockit.asm.exceptionHandling;
2
3 import edu.umd.cs.findbugs.annotations.NonNull;
4 import edu.umd.cs.findbugs.annotations.Nullable;
5
6 import java.util.ArrayList;
7 import java.util.List;
8
9 import mockit.asm.constantPool.ConstantPoolGeneration;
10 import mockit.asm.controlFlow.Edge;
11 import mockit.asm.controlFlow.FrameTypeMask;
12 import mockit.asm.controlFlow.Label;
13 import mockit.asm.util.ByteVector;
14
15 import org.checkerframework.checker.index.qual.NonNegative;
16
17 public final class ExceptionHandling {
18 @NonNull
19 private final List<ExceptionHandler> handlers;
20 @NonNull
21 private final ConstantPoolGeneration cp;
22
23 public ExceptionHandling(@NonNull ConstantPoolGeneration cp) {
24 handlers = new ArrayList<>();
25 this.cp = cp;
26 }
27
28 public void addHandler(@NonNull Label start, @NonNull Label end, @NonNull Label handler, @Nullable String type) {
29 int handlerType = type == null ? 0 : cp.newClass(type);
30 handlers.add(new ExceptionHandler(start, end, handler, type, handlerType));
31 }
32
33 public void completeControlFlowGraphWithExceptionHandlerBlocksFromComputedFrames() {
34 for (ExceptionHandler exceptionHandler : handlers) {
35 Label handler = exceptionHandler.handler.getFirst();
36 Label start = exceptionHandler.start.getFirst();
37 Label end = exceptionHandler.end.getFirst();
38
39
40 String catchType = exceptionHandler.getCatchTypeDesc();
41 int kindOfEdge = FrameTypeMask.OBJECT | cp.addNormalType(catchType);
42
43
44 handler.markAsTarget();
45
46 addHandlerLabelAsSuccessor(kindOfEdge, handler, start, end);
47 }
48 }
49
50 public void completeControlFlowGraphWithExceptionHandlerBlocks() {
51 for (ExceptionHandler exceptionHandler : handlers) {
52 addHandlerLabelAsSuccessor(Edge.EXCEPTION, exceptionHandler.handler, exceptionHandler.start,
53 exceptionHandler.end);
54 }
55 }
56
57
58 private static void addHandlerLabelAsSuccessor(int kindOfEdge, @NonNull Label handler, @NonNull Label start,
59 @NonNull Label end) {
60 while (start != end) {
61 Edge edge = new Edge(kindOfEdge, handler);
62
63 start = start.setSuccessors(edge);
64 }
65 }
66
67 public boolean hasHandlers() {
68 return !handlers.isEmpty();
69 }
70
71 @NonNegative
72 public int getSize() {
73 return 8 * handlers.size();
74 }
75
76 public void put(@NonNull ByteVector out) {
77 out.putShort(handlers.size());
78
79 for (ExceptionHandler exceptionHandler : handlers) {
80 exceptionHandler.put(out);
81 }
82 }
83 }