1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.generic;
18
19 import org.apache.bcel.classfile.CodeException;
20
21 /***
22 * This class represents an exception handler, i.e., specifies the region where
23 * a handler is active and an instruction where the actual handling is done.
24 * pool as parameters. Opposed to the JVM specification the end of the handled
25 * region is set to be inclusive, i.e. all instructions between start and end
26 * are protected including the start and end instructions (handles) themselves.
27 * The end of the region is automatically mapped to be exclusive when calling
28 * getCodeException(), i.e., there is no difference semantically.
29 *
30 * @version $Id: CodeExceptionGen.java 386056 2006-03-15 11:31:56Z tcurdt $
31 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
32 * @see MethodGen
33 * @see CodeException
34 * @see InstructionHandle
35 */
36 public final class CodeExceptionGen implements InstructionTargeter, Cloneable, java.io.Serializable {
37
38 private InstructionHandle start_pc;
39 private InstructionHandle end_pc;
40 private InstructionHandle handler_pc;
41 private ObjectType catch_type;
42
43
44 /***
45 * Add an exception handler, i.e., specify region where a handler is active and an
46 * instruction where the actual handling is done.
47 *
48 * @param start_pc Start of handled region (inclusive)
49 * @param end_pc End of handled region (inclusive)
50 * @param handler_pc Where handling is done
51 * @param catch_type which exception is handled, null for ANY
52 */
53 public CodeExceptionGen(InstructionHandle start_pc, InstructionHandle end_pc,
54 InstructionHandle handler_pc, ObjectType catch_type) {
55 setStartPC(start_pc);
56 setEndPC(end_pc);
57 setHandlerPC(handler_pc);
58 this.catch_type = catch_type;
59 }
60
61
62 /***
63 * Get CodeException object.<BR>
64 *
65 * This relies on that the instruction list has already been dumped
66 * to byte code or or that the `setPositions' methods has been
67 * called for the instruction list.
68 *
69 * @param cp constant pool
70 */
71 public CodeException getCodeException( ConstantPoolGen cp ) {
72 return new CodeException(start_pc.getPosition(), end_pc.getPosition()
73 + end_pc.getInstruction().getLength(), handler_pc.getPosition(),
74 (catch_type == null) ? 0 : cp.addClass(catch_type));
75 }
76
77
78
79
80
81 public void setStartPC( InstructionHandle start_pc ) {
82 BranchInstruction.notifyTarget(this.start_pc, start_pc, this);
83 this.start_pc = start_pc;
84 }
85
86
87
88
89
90 public void setEndPC( InstructionHandle end_pc ) {
91 BranchInstruction.notifyTarget(this.end_pc, end_pc, this);
92 this.end_pc = end_pc;
93 }
94
95
96
97
98
99 public void setHandlerPC( InstructionHandle handler_pc ) {
100 BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this);
101 this.handler_pc = handler_pc;
102 }
103
104
105 /***
106 * @param old_ih old target, either start or end
107 * @param new_ih new target
108 */
109 public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) {
110 boolean targeted = false;
111 if (start_pc == old_ih) {
112 targeted = true;
113 setStartPC(new_ih);
114 }
115 if (end_pc == old_ih) {
116 targeted = true;
117 setEndPC(new_ih);
118 }
119 if (handler_pc == old_ih) {
120 targeted = true;
121 setHandlerPC(new_ih);
122 }
123 if (!targeted) {
124 throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", "
125 + end_pc + ", " + handler_pc + "}");
126 }
127 }
128
129
130 /***
131 * @return true, if ih is target of this handler
132 */
133 public boolean containsTarget( InstructionHandle ih ) {
134 return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih);
135 }
136
137
138 /*** Sets the type of the Exception to catch. Set 'null' for ANY. */
139 public void setCatchType( ObjectType catch_type ) {
140 this.catch_type = catch_type;
141 }
142
143
144 /*** Gets the type of the Exception to catch, 'null' for ANY. */
145 public ObjectType getCatchType() {
146 return catch_type;
147 }
148
149
150 /*** @return start of handled region (inclusive)
151 */
152 public InstructionHandle getStartPC() {
153 return start_pc;
154 }
155
156
157 /*** @return end of handled region (inclusive)
158 */
159 public InstructionHandle getEndPC() {
160 return end_pc;
161 }
162
163
164 /*** @return start of handler
165 */
166 public InstructionHandle getHandlerPC() {
167 return handler_pc;
168 }
169
170
171 public String toString() {
172 return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")";
173 }
174
175
176 public Object clone() {
177 try {
178 return super.clone();
179 } catch (CloneNotSupportedException e) {
180 System.err.println(e);
181 return null;
182 }
183 }
184 }