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