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