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.io.DataOutputStream;
20 import java.io.IOException;
21
22 import org.apache.bcel.util.ByteSequence;
23
24
25
26
27
28
29
30
31
32
33
34 public abstract class Select extends BranchInstruction implements VariableLengthInstruction, StackConsumer , StackProducer {
35
36
37
38
39 @Deprecated
40 protected int[] match;
41
42
43
44
45 @Deprecated
46 protected int[] indices;
47
48
49
50
51 @Deprecated
52 protected InstructionHandle[] targets;
53
54
55
56
57 @Deprecated
58 protected int fixed_length;
59
60
61
62
63 @Deprecated
64 protected int match_length;
65
66
67
68
69 @Deprecated
70 protected int padding;
71
72
73
74
75 Select() {
76 }
77
78
79
80
81
82
83
84
85 Select(final short opcode, final int[] match, final InstructionHandle[] targets, final InstructionHandle defaultTarget) {
86
87 super(opcode, null);
88 this.match = match;
89 this.targets = targets;
90
91 setTarget(defaultTarget);
92 for (final InstructionHandle target2 : targets) {
93 notifyTarget(null, target2, this);
94 }
95 if ((match_length = match.length) != targets.length) {
96 throw new ClassGenException("Match and target array have not the same length: Match length: " + match.length + " Target length: " + targets.length);
97 }
98 indices = new int[match_length];
99 }
100
101 @Override
102 protected Object clone() throws CloneNotSupportedException {
103 final Select copy = (Select) super.clone();
104 copy.match = match.clone();
105 copy.indices = indices.clone();
106 copy.targets = targets.clone();
107 return copy;
108 }
109
110
111
112
113 @Override
114 public boolean containsTarget(final InstructionHandle ih) {
115 if (super.getTarget() == ih) {
116 return true;
117 }
118 for (final InstructionHandle target2 : targets) {
119 if (target2 == ih) {
120 return true;
121 }
122 }
123 return false;
124 }
125
126
127
128
129 @Override
130 void dispose() {
131 super.dispose();
132 for (final InstructionHandle target2 : targets) {
133 target2.removeTargeter(this);
134 }
135 }
136
137
138
139
140
141
142 @Override
143 public void dump(final DataOutputStream out) throws IOException {
144 out.writeByte(super.getOpcode());
145 for (int i = 0; i < padding; i++) {
146 out.writeByte(0);
147 }
148 super.setIndex(getTargetOffset());
149 out.writeInt(super.getIndex());
150 }
151
152
153
154
155
156 final int getFixedLength() {
157 return fixed_length;
158 }
159
160
161
162
163 public int[] getIndices() {
164 return indices;
165 }
166
167
168
169
170
171 final int getIndices(final int index) {
172 return indices[index];
173 }
174
175
176
177
178
179 final int getMatch(final int index) {
180 return match[index];
181 }
182
183
184
185
186
187 final int getMatchLength() {
188 return match_length;
189 }
190
191
192
193
194 public int[] getMatchs() {
195 return match;
196 }
197
198
199
200
201
202
203 final int getPadding() {
204 return padding;
205 }
206
207
208
209
210
211 final InstructionHandle getTarget(final int index) {
212 return targets[index];
213 }
214
215
216
217
218 public InstructionHandle[] getTargets() {
219 return targets;
220 }
221
222
223
224
225 @Override
226 protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
227 padding = (4 - bytes.getIndex() % 4) % 4;
228 for (int i = 0; i < padding; i++) {
229 bytes.readByte();
230 }
231
232 super.setIndex(bytes.readInt());
233 }
234
235
236
237
238
239 final void setFixedLength(final int fixedLength) {
240 this.fixed_length = fixedLength;
241 }
242
243
244 final int setIndices(final int i, final int value) {
245 indices[i] = value;
246 return value;
247 }
248
249
250
251
252
253
254 final void setIndices(final int[] array) {
255 indices = array;
256 }
257
258
259
260
261
262
263
264 final void setMatch(final int index, final int value) {
265 match[index] = value;
266 }
267
268
269
270
271
272
273 final void setMatches(final int[] array) {
274 match = array;
275 }
276
277
278
279
280
281 final int setMatchLength(final int matchLength) {
282 this.match_length = matchLength;
283 return matchLength;
284 }
285
286
287
288
289 public void setTarget(final int i, final InstructionHandle target) {
290 notifyTarget(targets[i], target, this);
291 targets[i] = target;
292 }
293
294
295
296
297
298
299 final void setTargets(final InstructionHandle[] array) {
300 targets = array;
301 }
302
303
304
305
306 @Override
307 public String toString(final boolean verbose) {
308 final StringBuilder buf = new StringBuilder(super.toString(verbose));
309 if (verbose) {
310 for (int i = 0; i < match_length; i++) {
311 String s = "null";
312 if (targets[i] != null) {
313 if (targets[i].getInstruction() == this) {
314 s = "<points to itself>";
315 } else {
316 s = targets[i].getInstruction().toString();
317 }
318 }
319 buf.append("(").append(match[i]).append(", ").append(s).append(" = {").append(indices[i]).append("})");
320 }
321 } else {
322 buf.append(" ...");
323 }
324 return buf.toString();
325 }
326
327
328
329
330
331
332
333
334
335
336
337
338
339 @Override
340 protected int updatePosition(final int offset, final int maxOffset) {
341 setPosition(getPosition() + offset);
342 final short oldLength = (short) super.getLength();
343
344
345
346 padding = (4 - (getPosition() + 1) % 4) % 4;
347 super.setLength((short) (fixed_length + padding));
348 return super.getLength() - oldLength;
349 }
350
351
352
353
354
355 @Override
356 public void updateTarget(final InstructionHandle oldIh, final InstructionHandle newIh) {
357 boolean targeted = false;
358 if (super.getTarget() == oldIh) {
359 targeted = true;
360 setTarget(newIh);
361 }
362 for (int i = 0; i < targets.length; i++) {
363 if (targets[i] == oldIh) {
364 targeted = true;
365 setTarget(i, newIh);
366 }
367 }
368 if (!targeted) {
369 throw new ClassGenException("Not targeting " + oldIh);
370 }
371 }
372 }