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 java.util.Collection;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.apache.bcel.classfile.Utility;
26
27
28
29
30
31
32
33
34
35
36
37
38
39 public class InstructionHandle {
40
41
42
43
44
45
46 public static final InstructionHandle[] EMPTY_ARRAY = {};
47
48
49
50
51 static final InstructionTargeter[] EMPTY_INSTRUCTION_TARGETER_ARRAY = {};
52
53
54
55
56 static InstructionHandle getInstructionHandle(final Instruction i) {
57 return new InstructionHandle(i);
58 }
59
60 private InstructionHandle next;
61 private InstructionHandle prev;
62
63 private Instruction instruction;
64
65
66
67
68 @Deprecated
69 protected int i_position = -1;
70 private Set<InstructionTargeter> targeters;
71
72 private Map<Object, Object> attributes;
73
74 protected InstructionHandle(final Instruction i) {
75 setInstruction(i);
76 }
77
78
79
80
81
82
83 public void accept(final Visitor v) {
84 instruction.accept(v);
85 }
86
87
88
89
90
91
92
93 public void addAttribute(final Object key, final Object attr) {
94 if (attributes == null) {
95 attributes = new HashMap<>(3);
96 }
97 attributes.put(key, attr);
98 }
99
100
101
102
103
104
105 @Deprecated
106 protected void addHandle() {
107
108 }
109
110
111
112
113 public void addTargeter(final InstructionTargeter t) {
114 if (targeters == null) {
115 targeters = new HashSet<>();
116 }
117
118 targeters.add(t);
119 }
120
121
122
123
124 void dispose() {
125 next = prev = null;
126 instruction.dispose();
127 instruction = null;
128 i_position = -1;
129 attributes = null;
130 removeAllTargeters();
131 }
132
133
134
135
136
137
138 public Object getAttribute(final Object key) {
139 return attributes != null ? attributes.get(key) : null;
140 }
141
142
143
144
145 public Collection<Object> getAttributes() {
146 if (attributes == null) {
147 attributes = new HashMap<>(3);
148 }
149 return attributes.values();
150 }
151
152 public final Instruction getInstruction() {
153 return instruction;
154 }
155
156 public final InstructionHandle getNext() {
157 return next;
158 }
159
160
161
162
163
164 public int getPosition() {
165 return i_position;
166 }
167
168 public final InstructionHandle getPrev() {
169 return prev;
170 }
171
172
173
174
175 public InstructionTargeter[] getTargeters() {
176 if (!hasTargeters()) {
177 return EMPTY_INSTRUCTION_TARGETER_ARRAY;
178 }
179 final InstructionTargeter[] t = new InstructionTargeter[targeters.size()];
180 targeters.toArray(t);
181 return t;
182 }
183
184 public boolean hasTargeters() {
185 return targeters != null && !targeters.isEmpty();
186 }
187
188
189
190
191 public void removeAllTargeters() {
192 if (targeters != null) {
193 targeters.clear();
194 }
195 }
196
197
198
199
200
201
202 public void removeAttribute(final Object key) {
203 if (attributes != null) {
204 attributes.remove(key);
205 }
206 }
207
208
209
210
211 public void removeTargeter(final InstructionTargeter t) {
212 if (targeters != null) {
213 targeters.remove(t);
214 }
215 }
216
217
218
219
220 public void setInstruction(final Instruction i) {
221 if (i == null) {
222 throw new ClassGenException("Assigning null to handle");
223 }
224 if (this.getClass() != BranchHandle.class && i instanceof BranchInstruction) {
225 throw new ClassGenException("Assigning branch instruction " + i + " to plain handle");
226 }
227 if (instruction != null) {
228 instruction.dispose();
229 }
230 instruction = i;
231 }
232
233
234
235
236
237 final InstructionHandle setNext(final InstructionHandle next) {
238 this.next = next;
239 return next;
240 }
241
242
243
244
245 void setPosition(final int pos) {
246 i_position = pos;
247 }
248
249
250
251
252
253 final InstructionHandle setPrev(final InstructionHandle prev) {
254 this.prev = prev;
255 return prev;
256 }
257
258
259
260
261
262
263
264
265
266
267 public Instruction swapInstruction(final Instruction i) {
268 final Instruction oldInstruction = instruction;
269 instruction = i;
270 return oldInstruction;
271 }
272
273
274
275
276 @Override
277 public String toString() {
278 return toString(true);
279 }
280
281
282
283
284 public String toString(final boolean verbose) {
285 return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose);
286 }
287
288
289
290
291
292
293
294
295
296
297 protected int updatePosition(final int offset, final int maxOffset) {
298 i_position += offset;
299 return 0;
300 }
301 }