1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.bcel.generic;
19
20 import java.io.DataOutputStream;
21 import java.io.IOException;
22 import java.io.Serializable;
23 import org.apache.bcel.Constants;
24 import org.apache.bcel.classfile.ConstantPool;
25 import org.apache.bcel.util.ByteSequence;
26
27
28
29
30
31
32
33 public abstract class Instruction implements Cloneable, Serializable {
34
35 private static final long serialVersionUID = -2518741982574515847L;
36 protected short length = 1;
37 protected short opcode = -1;
38 private static InstructionComparator cmp = InstructionComparator.DEFAULT;
39
40
41
42
43
44
45 Instruction() {
46 }
47
48
49 public Instruction(short opcode, short length) {
50 this.length = length;
51 this.opcode = opcode;
52 }
53
54
55
56
57
58
59 public void dump( DataOutputStream out ) throws IOException {
60 out.writeByte(opcode);
61 }
62
63
64
65
66 public String getName() {
67 return Constants.OPCODE_NAMES[opcode];
68 }
69
70
71
72
73
74
75
76
77
78
79
80 public String toString( boolean verbose ) {
81 if (verbose) {
82 return getName() + "[" + opcode + "](" + length + ")";
83 } else {
84 return getName();
85 }
86 }
87
88
89
90
91
92 @Override
93 public String toString() {
94 return toString(true);
95 }
96
97
98
99
100
101 public String toString( ConstantPool cp ) {
102 return toString(false);
103 }
104
105
106
107
108
109
110
111
112
113
114 public Instruction copy() {
115 Instruction i = null;
116
117 if (InstructionConstants.INSTRUCTIONS[this.getOpcode()] != null) {
118 i = this;
119 } else {
120 try {
121 i = (Instruction) clone();
122 } catch (CloneNotSupportedException e) {
123 System.err.println(e);
124 }
125 }
126 return i;
127 }
128
129
130
131
132
133
134
135
136 protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
137 }
138
139
140
141
142
143
144
145
146
147 public static final Instruction readInstruction( ByteSequence bytes ) throws IOException {
148 boolean wide = false;
149 short opcode = (short) bytes.readUnsignedByte();
150 Instruction obj = null;
151 if (opcode == Constants.WIDE) {
152 wide = true;
153 opcode = (short) bytes.readUnsignedByte();
154 }
155 if (InstructionConstants.INSTRUCTIONS[opcode] != null) {
156 return InstructionConstants.INSTRUCTIONS[opcode];
157 }
158
159 switch (opcode) {
160 case Constants.BIPUSH:
161 obj = new BIPUSH();
162 break;
163 case Constants.SIPUSH:
164 obj = new SIPUSH();
165 break;
166 case Constants.LDC:
167 obj = new LDC();
168 break;
169 case Constants.LDC_W:
170 obj = new LDC_W();
171 break;
172 case Constants.LDC2_W:
173 obj = new LDC2_W();
174 break;
175 case Constants.ILOAD:
176 obj = new ILOAD();
177 break;
178 case Constants.LLOAD:
179 obj = new LLOAD();
180 break;
181 case Constants.FLOAD:
182 obj = new FLOAD();
183 break;
184 case Constants.DLOAD:
185 obj = new DLOAD();
186 break;
187 case Constants.ALOAD:
188 obj = new ALOAD();
189 break;
190 case Constants.ILOAD_0:
191 obj = new ILOAD(0);
192 break;
193 case Constants.ILOAD_1:
194 obj = new ILOAD(1);
195 break;
196 case Constants.ILOAD_2:
197 obj = new ILOAD(2);
198 break;
199 case Constants.ILOAD_3:
200 obj = new ILOAD(3);
201 break;
202 case Constants.LLOAD_0:
203 obj = new LLOAD(0);
204 break;
205 case Constants.LLOAD_1:
206 obj = new LLOAD(1);
207 break;
208 case Constants.LLOAD_2:
209 obj = new LLOAD(2);
210 break;
211 case Constants.LLOAD_3:
212 obj = new LLOAD(3);
213 break;
214 case Constants.FLOAD_0:
215 obj = new FLOAD(0);
216 break;
217 case Constants.FLOAD_1:
218 obj = new FLOAD(1);
219 break;
220 case Constants.FLOAD_2:
221 obj = new FLOAD(2);
222 break;
223 case Constants.FLOAD_3:
224 obj = new FLOAD(3);
225 break;
226 case Constants.DLOAD_0:
227 obj = new DLOAD(0);
228 break;
229 case Constants.DLOAD_1:
230 obj = new DLOAD(1);
231 break;
232 case Constants.DLOAD_2:
233 obj = new DLOAD(2);
234 break;
235 case Constants.DLOAD_3:
236 obj = new DLOAD(3);
237 break;
238 case Constants.ALOAD_0:
239 obj = new ALOAD(0);
240 break;
241 case Constants.ALOAD_1:
242 obj = new ALOAD(1);
243 break;
244 case Constants.ALOAD_2:
245 obj = new ALOAD(2);
246 break;
247 case Constants.ALOAD_3:
248 obj = new ALOAD(3);
249 break;
250 case Constants.ISTORE:
251 obj = new ISTORE();
252 break;
253 case Constants.LSTORE:
254 obj = new LSTORE();
255 break;
256 case Constants.FSTORE:
257 obj = new FSTORE();
258 break;
259 case Constants.DSTORE:
260 obj = new DSTORE();
261 break;
262 case Constants.ASTORE:
263 obj = new ASTORE();
264 break;
265 case Constants.ISTORE_0:
266 obj = new ISTORE(0);
267 break;
268 case Constants.ISTORE_1:
269 obj = new ISTORE(1);
270 break;
271 case Constants.ISTORE_2:
272 obj = new ISTORE(2);
273 break;
274 case Constants.ISTORE_3:
275 obj = new ISTORE(3);
276 break;
277 case Constants.LSTORE_0:
278 obj = new LSTORE(0);
279 break;
280 case Constants.LSTORE_1:
281 obj = new LSTORE(1);
282 break;
283 case Constants.LSTORE_2:
284 obj = new LSTORE(2);
285 break;
286 case Constants.LSTORE_3:
287 obj = new LSTORE(3);
288 break;
289 case Constants.FSTORE_0:
290 obj = new FSTORE(0);
291 break;
292 case Constants.FSTORE_1:
293 obj = new FSTORE(1);
294 break;
295 case Constants.FSTORE_2:
296 obj = new FSTORE(2);
297 break;
298 case Constants.FSTORE_3:
299 obj = new FSTORE(3);
300 break;
301 case Constants.DSTORE_0:
302 obj = new DSTORE(0);
303 break;
304 case Constants.DSTORE_1:
305 obj = new DSTORE(1);
306 break;
307 case Constants.DSTORE_2:
308 obj = new DSTORE(2);
309 break;
310 case Constants.DSTORE_3:
311 obj = new DSTORE(3);
312 break;
313 case Constants.ASTORE_0:
314 obj = new ASTORE(0);
315 break;
316 case Constants.ASTORE_1:
317 obj = new ASTORE(1);
318 break;
319 case Constants.ASTORE_2:
320 obj = new ASTORE(2);
321 break;
322 case Constants.ASTORE_3:
323 obj = new ASTORE(3);
324 break;
325 case Constants.IINC:
326 obj = new IINC();
327 break;
328 case Constants.IFEQ:
329 obj = new IFEQ();
330 break;
331 case Constants.IFNE:
332 obj = new IFNE();
333 break;
334 case Constants.IFLT:
335 obj = new IFLT();
336 break;
337 case Constants.IFGE:
338 obj = new IFGE();
339 break;
340 case Constants.IFGT:
341 obj = new IFGT();
342 break;
343 case Constants.IFLE:
344 obj = new IFLE();
345 break;
346 case Constants.IF_ICMPEQ:
347 obj = new IF_ICMPEQ();
348 break;
349 case Constants.IF_ICMPNE:
350 obj = new IF_ICMPNE();
351 break;
352 case Constants.IF_ICMPLT:
353 obj = new IF_ICMPLT();
354 break;
355 case Constants.IF_ICMPGE:
356 obj = new IF_ICMPGE();
357 break;
358 case Constants.IF_ICMPGT:
359 obj = new IF_ICMPGT();
360 break;
361 case Constants.IF_ICMPLE:
362 obj = new IF_ICMPLE();
363 break;
364 case Constants.IF_ACMPEQ:
365 obj = new IF_ACMPEQ();
366 break;
367 case Constants.IF_ACMPNE:
368 obj = new IF_ACMPNE();
369 break;
370 case Constants.GOTO:
371 obj = new GOTO();
372 break;
373 case Constants.JSR:
374 obj = new JSR();
375 break;
376 case Constants.RET:
377 obj = new RET();
378 break;
379 case Constants.TABLESWITCH:
380 obj = new TABLESWITCH();
381 break;
382 case Constants.LOOKUPSWITCH:
383 obj = new LOOKUPSWITCH();
384 break;
385 case Constants.GETSTATIC:
386 obj = new GETSTATIC();
387 break;
388 case Constants.PUTSTATIC:
389 obj = new PUTSTATIC();
390 break;
391 case Constants.GETFIELD:
392 obj = new GETFIELD();
393 break;
394 case Constants.PUTFIELD:
395 obj = new PUTFIELD();
396 break;
397 case Constants.INVOKEVIRTUAL:
398 obj = new INVOKEVIRTUAL();
399 break;
400 case Constants.INVOKESPECIAL:
401 obj = new INVOKESPECIAL();
402 break;
403 case Constants.INVOKESTATIC:
404 obj = new INVOKESTATIC();
405 break;
406 case Constants.INVOKEINTERFACE:
407 obj = new INVOKEINTERFACE();
408 break;
409 case Constants.NEW:
410 obj = new NEW();
411 break;
412 case Constants.NEWARRAY:
413 obj = new NEWARRAY();
414 break;
415 case Constants.ANEWARRAY:
416 obj = new ANEWARRAY();
417 break;
418 case Constants.CHECKCAST:
419 obj = new CHECKCAST();
420 break;
421 case Constants.INSTANCEOF:
422 obj = new INSTANCEOF();
423 break;
424 case Constants.MULTIANEWARRAY:
425 obj = new MULTIANEWARRAY();
426 break;
427 case Constants.IFNULL:
428 obj = new IFNULL();
429 break;
430 case Constants.IFNONNULL:
431 obj = new IFNONNULL();
432 break;
433 case Constants.GOTO_W:
434 obj = new GOTO_W();
435 break;
436 case Constants.JSR_W:
437 obj = new JSR_W();
438 break;
439 case Constants.BREAKPOINT:
440 obj = new BREAKPOINT();
441 break;
442 case Constants.IMPDEP1:
443 obj = new IMPDEP1();
444 break;
445 case Constants.IMPDEP2:
446 obj = new IMPDEP2();
447 break;
448 default:
449 throw new ClassGenException("Illegal opcode detected: " + opcode);
450
451 }
452
453 if (wide
454 && !((obj instanceof LocalVariableInstruction) || (obj instanceof IINC) || (obj instanceof RET))) {
455 throw new ClassGenException("Illegal opcode after wide: " + opcode);
456 }
457 obj.setOpcode(opcode);
458 obj.initFromFile(bytes, wide);
459 return obj;
460 }
461
462
463
464
465
466
467
468
469 public int consumeStack( ConstantPoolGen cpg ) {
470 return Constants.CONSUME_STACK[opcode];
471 }
472
473
474
475
476
477
478
479
480
481 public int produceStack( ConstantPoolGen cpg ) {
482 return Constants.PRODUCE_STACK[opcode];
483 }
484
485
486
487
488
489 public short getOpcode() {
490 return opcode;
491 }
492
493
494
495
496
497 public int getLength() {
498 return length;
499 }
500
501
502
503
504
505 private void setOpcode( short opcode ) {
506 this.opcode = opcode;
507 }
508
509
510
511
512 void dispose() {
513 }
514
515
516
517
518
519
520
521
522
523
524 public abstract void accept( Visitor v );
525
526
527
528
529
530
531
532
533 @Deprecated
534 public static InstructionComparator getComparator() {
535 return cmp;
536 }
537
538
539
540
541
542 @Deprecated
543 public static void setComparator( InstructionComparator c ) {
544 cmp = c;
545 }
546
547
548
549
550
551 @Override
552 public boolean equals( Object that ) {
553 return (that instanceof Instruction) ? cmp.equals(this, (Instruction) that) : false;
554 }
555 }