129 |
130 |
130 return new LocalVariable(start_pc, length, name_index, |
131 return new LocalVariable(start_pc, length, name_index, |
131 signature_index, index, cp.getConstantPool()); |
132 signature_index, index, cp.getConstantPool()); |
132 } |
133 } |
133 |
134 |
134 public void setIndex(int index) { this.index = index; } |
135 public int getIndex() { return index; } |
135 public int getIndex() { return index; } |
136 @Override |
136 public void setName(String name) { this.name = name; } |
137 public void setName(String name) { this.name = name; } |
|
138 @Override |
137 public String getName() { return name; } |
139 public String getName() { return name; } |
|
140 @Override |
138 public void setType(Type type) { this.type = type; } |
141 public void setType(Type type) { this.type = type; } |
|
142 @Override |
139 public Type getType() { return type; } |
143 public Type getType() { return type; } |
140 |
144 |
141 public InstructionHandle getStart() { return start; } |
145 public InstructionHandle getStart() { return start; } |
142 public InstructionHandle getEnd() { return end; } |
146 public InstructionHandle getEnd() { return end; } |
143 |
147 |
144 public void setStart(InstructionHandle start) { |
148 /** |
145 BranchInstruction.notifyTarget(this.start, start, this); |
149 * Remove this from any known HashSet in which it might be registered. |
|
150 */ |
|
151 void notifyTargetChanging() { |
|
152 // hashCode depends on 'index', 'start', and 'end'. |
|
153 // Therefore before changing any of these values we |
|
154 // need to unregister 'this' from any HashSet where |
|
155 // this is registered, and then we need to add it |
|
156 // back... |
|
157 |
|
158 // Unregister 'this' from the HashSet held by 'start'. |
|
159 BranchInstruction.notifyTargetChanging(this.start, this); |
|
160 if (this.end != this.start) { |
|
161 // Since hashCode() is going to change we need to unregister |
|
162 // 'this' both form 'start' and 'end'. |
|
163 // Unregister 'this' from the HashSet held by 'end'. |
|
164 BranchInstruction.notifyTargetChanging(this.end, this); |
|
165 } |
|
166 } |
|
167 |
|
168 /** |
|
169 * Add back 'this' in all HashSet in which it should be registered. |
|
170 **/ |
|
171 void notifyTargetChanged() { |
|
172 // hashCode depends on 'index', 'start', and 'end'. |
|
173 // Therefore before changing any of these values we |
|
174 // need to unregister 'this' from any HashSet where |
|
175 // this is registered, and then we need to add it |
|
176 // back... |
|
177 |
|
178 // Register 'this' in the HashSet held by start. |
|
179 BranchInstruction.notifyTargetChanged(this.start, this); |
|
180 if (this.end != this.start) { |
|
181 // Since hashCode() has changed we need to register |
|
182 // 'this' again in 'end'. |
|
183 // Add back 'this' in the HashSet held by 'end'. |
|
184 BranchInstruction.notifyTargetChanged(this.end, this); |
|
185 } |
|
186 } |
|
187 |
|
188 public final void setStart(InstructionHandle start) { |
|
189 |
|
190 // Call notifyTargetChanging *before* modifying this, |
|
191 // as the code triggered by notifyTargetChanging |
|
192 // depends on this pointing to the 'old' start. |
|
193 notifyTargetChanging(); |
|
194 |
146 this.start = start; |
195 this.start = start; |
147 } |
196 |
148 |
197 // call notifyTargetChanged *after* modifying this, |
149 public void setEnd(InstructionHandle end) { |
198 // as the code triggered by notifyTargetChanged |
150 BranchInstruction.notifyTarget(this.end, end, this); |
199 // depends on this pointing to the 'new' start. |
|
200 notifyTargetChanged(); |
|
201 } |
|
202 |
|
203 public final void setEnd(InstructionHandle end) { |
|
204 // call notifyTargetChanging *before* modifying this, |
|
205 // as the code triggered by notifyTargetChanging |
|
206 // depends on this pointing to the 'old' end. |
|
207 // Unregister 'this' from the HashSet held by the 'old' end. |
|
208 notifyTargetChanging(); |
|
209 |
151 this.end = end; |
210 this.end = end; |
|
211 |
|
212 // call notifyTargetChanged *after* modifying this, |
|
213 // as the code triggered by notifyTargetChanged |
|
214 // depends on this pointing to the 'new' end. |
|
215 // Register 'this' in the HashSet held by the 'new' end. |
|
216 notifyTargetChanged(); |
|
217 |
152 } |
218 } |
153 |
219 |
154 /** |
220 /** |
155 * @param old_ih old target, either start or end |
221 * @param old_ih old target, either start or end |
156 * @param new_ih new target |
222 * @param new_ih new target |
157 */ |
223 */ |
|
224 @Override |
158 public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { |
225 public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { |
159 boolean targeted = false; |
226 boolean targeted = false; |
160 |
227 |
161 if(start == old_ih) { |
228 if(start == old_ih) { |
162 targeted = true; |
229 targeted = true; |
174 } |
241 } |
175 |
242 |
176 /** |
243 /** |
177 * @return true, if ih is target of this variable |
244 * @return true, if ih is target of this variable |
178 */ |
245 */ |
|
246 @Override |
179 public boolean containsTarget(InstructionHandle ih) { |
247 public boolean containsTarget(InstructionHandle ih) { |
180 return (start == ih) || (end == ih); |
248 return (start == ih) || (end == ih); |
181 } |
249 } |
182 |
250 |
183 /** |
251 /** |
184 * We consider to local variables to be equal, if the use the same index and |
252 * We consider two local variables to be equal, if they use the same index and |
185 * are valid in the same range. |
253 * are valid in the same range. |
186 */ |
254 */ |
|
255 @Override |
187 public boolean equals(Object o) { |
256 public boolean equals(Object o) { |
|
257 if (o==this) |
|
258 return true; |
|
259 |
188 if(!(o instanceof LocalVariableGen)) |
260 if(!(o instanceof LocalVariableGen)) |
189 return false; |
261 return false; |
190 |
262 |
191 LocalVariableGen l = (LocalVariableGen)o; |
263 LocalVariableGen l = (LocalVariableGen)o; |
192 return (l.index == index) && (l.start == start) && (l.end == end); |
264 return (l.index == index) && (l.start == start) && (l.end == end); |
193 } |
265 } |
194 |
266 |
|
267 @Override |
|
268 public int hashCode() { |
|
269 int hash = 7; |
|
270 hash = 59 * hash + this.index; |
|
271 hash = 59 * hash + Objects.hashCode(this.start); |
|
272 hash = 59 * hash + Objects.hashCode(this.end); |
|
273 return hash; |
|
274 } |
|
275 |
|
276 @Override |
195 public String toString() { |
277 public String toString() { |
196 return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")"; |
278 return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")"; |
197 } |
279 } |
198 |
280 |
|
281 @Override |
199 public Object clone() { |
282 public Object clone() { |
200 try { |
283 try { |
201 return super.clone(); |
284 return super.clone(); |
202 } catch(CloneNotSupportedException e) { |
285 } catch(CloneNotSupportedException e) { |
203 System.err.println(e); |
286 System.err.println(e); |