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