1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.bcel.verifier.structurals;
18
19 import org.apache.bcel.Const;
20 import org.apache.bcel.classfile.Constant;
21 import org.apache.bcel.classfile.ConstantClass;
22 import org.apache.bcel.classfile.ConstantDouble;
23 import org.apache.bcel.classfile.ConstantDynamic;
24 import org.apache.bcel.classfile.ConstantFloat;
25 import org.apache.bcel.classfile.ConstantInteger;
26 import org.apache.bcel.classfile.ConstantLong;
27 import org.apache.bcel.classfile.ConstantString;
28 // CHECKSTYLE:OFF (there are lots of references!)
29 import org.apache.bcel.generic.*;
30 //CHECKSTYLE:ON
31
32 /**
33 * This Visitor class may be used for a type-based Java Virtual Machine simulation.
34 *
35 * <p>
36 * It does not check for correct types on the OperandStack or in the LocalVariables; nor does it check their sizes are
37 * sufficiently big. Thus, to use this Visitor for bytecode verifying, you have to make sure externally that the type
38 * constraints of the Java Virtual Machine instructions are satisfied. An InstConstraintVisitor may be used for this.
39 * Anyway, this Visitor does not mandate it. For example, when you visitIADD(IADD o), then there are two stack slots
40 * popped and one stack slot containing a Type.INT is pushed (where you could also pop only one slot if you know there
41 * are two Type.INT on top of the stack). Monitor-specific behavior is not simulated.
42 * </p>
43 *
44 * <b>Conventions:</b>
45 *
46 * <p>
47 * Type.VOID will never be pushed onto the stack. Type.DOUBLE and Type.LONG that would normally take up two stack slots
48 * (like Double_HIGH and Double_LOW) are represented by a simple single Type.DOUBLE or Type.LONG object on the stack
49 * here.
50 * </p>
51 *
52 * <p>
53 * If a two-slot type is stored into a local variable, the next variable is given the type Type.UNKNOWN.
54 * </p>
55 *
56 * @see #visitDSTORE(DSTORE o)
57 * @see InstConstraintVisitor
58 */
59 public class ExecutionVisitor extends EmptyVisitor {
60
61 /**
62 * The executionframe we're operating on.
63 */
64 private Frame frame;
65
66 /**
67 * The ConstantPoolGen we're working with.
68 *
69 * @see #setConstantPoolGen(ConstantPoolGen)
70 */
71 private ConstantPoolGen cpg;
72
73 /**
74 * Constructs a new instance of this class.
75 */
76 public ExecutionVisitor() {
77 }
78
79 /**
80 * The LocalVariables from the current Frame we're operating on.
81 *
82 * @see #setFrame(Frame)
83 */
84 private LocalVariables locals() {
85 return frame.getLocals();
86 }
87
88 /**
89 * Sets the ConstantPoolGen needed for symbolic execution.
90 */
91 public void setConstantPoolGen(final ConstantPoolGen cpg) { // TODO could be package-protected?
92 this.cpg = cpg;
93 }
94
95 /**
96 * The only method granting access to the single instance of the ExecutionVisitor class. Before actively using this
97 * instance, <B>SET THE ConstantPoolGen FIRST</B>.
98 *
99 * @see #setConstantPoolGen(ConstantPoolGen)
100 */
101 public void setFrame(final Frame f) { // TODO could be package-protected?
102 this.frame = f;
103 }
104
105 /**
106 * The OperandStack from the current Frame we're operating on.
107 *
108 * @see #setFrame(Frame)
109 */
110 private OperandStack stack() {
111 return frame.getStack();
112 }
113
114 /// ** Symbolically executes the corresponding Java Virtual Machine instruction. */
115 // public void visitWIDE(WIDE o) {
116 // The WIDE instruction is modeled as a flag
117 // of the embedded instructions in BCEL.
118 // Therefore BCEL checks for possible errors
119 // when parsing in the .class file: We don't
120 // have even the possibility to care for WIDE
121 // here.
122 // }
123
124 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
125 @Override
126 public void visitAALOAD(final AALOAD o) {
127 stack().pop(); // pop the index int
128 //System.out.print(stack().peek());
129 final Type t = stack().pop(); // Pop Array type
130 if (t == Type.NULL) {
131 stack().push(Type.NULL);
132 } // Do nothing stackwise --- a NullPointerException is thrown at Run-Time
133 else {
134 final ArrayType at = (ArrayType) t;
135 stack().push(at.getElementType());
136 }
137 }
138
139 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
140 @Override
141 public void visitAASTORE(final AASTORE o) {
142 stack().pop(3);
143 }
144
145 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
146 @Override
147 public void visitACONST_NULL(final ACONST_NULL o) {
148 stack().push(Type.NULL);
149 }
150
151 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
152 @Override
153 public void visitALOAD(final ALOAD o) {
154 stack().push(locals().get(o.getIndex()));
155 }
156
157 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
158 @Override
159 public void visitANEWARRAY(final ANEWARRAY o) {
160 stack().pop(); // count
161 stack().push(new ArrayType(o.getType(cpg), 1));
162 }
163
164 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
165 @Override
166 public void visitARETURN(final ARETURN o) {
167 stack().pop();
168 }
169
170 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
171 @Override
172 public void visitARRAYLENGTH(final ARRAYLENGTH o) {
173 stack().pop();
174 stack().push(Type.INT);
175 }
176
177 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
178 @Override
179 public void visitASTORE(final ASTORE o) {
180 locals().set(o.getIndex(), stack().pop());
181 // System.err.println("TODO-DEBUG: set LV '"+o.getIndex()+"' to '"+locals().get(o.getIndex())+"'.");
182 }
183
184 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
185 @Override
186 public void visitATHROW(final ATHROW o) {
187 final Type t = stack().pop();
188 stack().clear();
189 if (t.equals(Type.NULL)) {
190 stack().push(Type.getType("Ljava/lang/NullPointerException;"));
191 } else {
192 stack().push(t);
193 }
194 }
195
196 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
197 @Override
198 public void visitBALOAD(final BALOAD o) {
199 stack().pop(2);
200 stack().push(Type.INT);
201 }
202
203 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
204 @Override
205 public void visitBASTORE(final BASTORE o) {
206 stack().pop(3);
207 }
208
209 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
210 @Override
211 public void visitBIPUSH(final BIPUSH o) {
212 stack().push(Type.INT);
213 }
214
215 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
216 @Override
217 public void visitCALOAD(final CALOAD o) {
218 stack().pop(2);
219 stack().push(Type.INT);
220 }
221
222 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
223 @Override
224 public void visitCASTORE(final CASTORE o) {
225 stack().pop(3);
226 }
227
228 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
229 @Override
230 public void visitCHECKCAST(final CHECKCAST o) {
231 // It's possibly wrong to do so, but SUN's
232 // ByteCode verifier seems to do (only) this, too.
233 // TODO: One could use a sophisticated analysis here to check
234 // if a type cannot possibly be cated to another and by
235 // so doing predict the ClassCastException at run-time.
236 stack().pop();
237 stack().push(o.getType(cpg));
238 }
239
240 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
241 @Override
242 public void visitD2F(final D2F o) {
243 stack().pop();
244 stack().push(Type.FLOAT);
245 }
246
247 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
248 @Override
249 public void visitD2I(final D2I o) {
250 stack().pop();
251 stack().push(Type.INT);
252 }
253
254 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
255 @Override
256 public void visitD2L(final D2L o) {
257 stack().pop();
258 stack().push(Type.LONG);
259 }
260
261 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
262 @Override
263 public void visitDADD(final DADD o) {
264 stack().pop(2);
265 stack().push(Type.DOUBLE);
266 }
267
268 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
269 @Override
270 public void visitDALOAD(final DALOAD o) {
271 stack().pop(2);
272 stack().push(Type.DOUBLE);
273 }
274
275 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
276 @Override
277 public void visitDASTORE(final DASTORE o) {
278 stack().pop(3);
279 }
280
281 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
282 @Override
283 public void visitDCMPG(final DCMPG o) {
284 stack().pop(2);
285 stack().push(Type.INT);
286 }
287
288 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
289 @Override
290 public void visitDCMPL(final DCMPL o) {
291 stack().pop(2);
292 stack().push(Type.INT);
293 }
294
295 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
296 @Override
297 public void visitDCONST(final DCONST o) {
298 stack().push(Type.DOUBLE);
299 }
300
301 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
302 @Override
303 public void visitDDIV(final DDIV o) {
304 stack().pop(2);
305 stack().push(Type.DOUBLE);
306 }
307
308 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
309 @Override
310 public void visitDLOAD(final DLOAD o) {
311 stack().push(Type.DOUBLE);
312 }
313
314 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
315 @Override
316 public void visitDMUL(final DMUL o) {
317 stack().pop(2);
318 stack().push(Type.DOUBLE);
319 }
320
321 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
322 @Override
323 public void visitDNEG(final DNEG o) {
324 stack().pop();
325 stack().push(Type.DOUBLE);
326 }
327
328 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
329 @Override
330 public void visitDREM(final DREM o) {
331 stack().pop(2);
332 stack().push(Type.DOUBLE);
333 }
334
335 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
336 @Override
337 public void visitDRETURN(final DRETURN o) {
338 stack().pop();
339 }
340
341 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
342 @Override
343 public void visitDSTORE(final DSTORE o) {
344 locals().set(o.getIndex(), stack().pop());
345 locals().set(o.getIndex() + 1, Type.UNKNOWN);
346 }
347
348 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
349 @Override
350 public void visitDSUB(final DSUB o) {
351 stack().pop(2);
352 stack().push(Type.DOUBLE);
353 }
354
355 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
356 @Override
357 public void visitDUP(final DUP o) {
358 final Type t = stack().pop();
359 stack().push(t);
360 stack().push(t);
361 }
362
363 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
364 @Override
365 public void visitDUP_X1(final DUP_X1 o) {
366 final Type w1 = stack().pop();
367 final Type w2 = stack().pop();
368 stack().push(w1);
369 stack().push(w2);
370 stack().push(w1);
371 }
372
373 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
374 @Override
375 public void visitDUP_X2(final DUP_X2 o) {
376 final Type w1 = stack().pop();
377 final Type w2 = stack().pop();
378 if (w2.getSize() == 2) {
379 stack().push(w1);
380 } else {
381 final Type w3 = stack().pop();
382 stack().push(w1);
383 stack().push(w3);
384 }
385 stack().push(w2);
386 stack().push(w1);
387 }
388
389 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
390 @Override
391 public void visitDUP2(final DUP2 o) {
392 final Type t = stack().pop();
393 if (t.getSize() == 2) {
394 stack().push(t);
395 } else { // t.getSize() is 1
396 final Type u = stack().pop();
397 stack().push(u);
398 stack().push(t);
399 stack().push(u);
400 }
401 stack().push(t);
402 }
403
404 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
405 @Override
406 public void visitDUP2_X1(final DUP2_X1 o) {
407 final Type t = stack().pop();
408 if (t.getSize() == 2) {
409 final Type u = stack().pop();
410 stack().push(t);
411 stack().push(u);
412 } else { // t.getSize() is1
413 final Type u = stack().pop();
414 final Type v = stack().pop();
415 stack().push(u);
416 stack().push(t);
417 stack().push(v);
418 stack().push(u);
419 }
420 stack().push(t);
421 }
422
423 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
424 @Override
425 public void visitDUP2_X2(final DUP2_X2 o) {
426 final Type t = stack().pop();
427 if (t.getSize() == 2) {
428 final Type u = stack().pop();
429 if (u.getSize() == 2) {
430 stack().push(t);
431 } else {
432 final Type v = stack().pop();
433 stack().push(t);
434 stack().push(v);
435 }
436 stack().push(u);
437 stack().push(t);
438 } else { // t.getSize() is 1
439 final Type u = stack().pop();
440 final Type v = stack().pop();
441 if (v.getSize() == 2) {
442 stack().push(u);
443 stack().push(t);
444 } else {
445 final Type w = stack().pop();
446 stack().push(u);
447 stack().push(t);
448 stack().push(w);
449 }
450 stack().push(v);
451 stack().push(u);
452 stack().push(t);
453 }
454 }
455
456 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
457 @Override
458 public void visitF2D(final F2D o) {
459 stack().pop();
460 stack().push(Type.DOUBLE);
461 }
462
463 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
464 @Override
465 public void visitF2I(final F2I o) {
466 stack().pop();
467 stack().push(Type.INT);
468 }
469
470 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
471 @Override
472 public void visitF2L(final F2L o) {
473 stack().pop();
474 stack().push(Type.LONG);
475 }
476
477 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
478 @Override
479 public void visitFADD(final FADD o) {
480 stack().pop(2);
481 stack().push(Type.FLOAT);
482 }
483
484 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
485 @Override
486 public void visitFALOAD(final FALOAD o) {
487 stack().pop(2);
488 stack().push(Type.FLOAT);
489 }
490
491 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
492 @Override
493 public void visitFASTORE(final FASTORE o) {
494 stack().pop(3);
495 }
496
497 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
498 @Override
499 public void visitFCMPG(final FCMPG o) {
500 stack().pop(2);
501 stack().push(Type.INT);
502 }
503
504 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
505 @Override
506 public void visitFCMPL(final FCMPL o) {
507 stack().pop(2);
508 stack().push(Type.INT);
509 }
510
511 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
512 @Override
513 public void visitFCONST(final FCONST o) {
514 stack().push(Type.FLOAT);
515 }
516
517 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
518 @Override
519 public void visitFDIV(final FDIV o) {
520 stack().pop(2);
521 stack().push(Type.FLOAT);
522 }
523
524 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
525 @Override
526 public void visitFLOAD(final FLOAD o) {
527 stack().push(Type.FLOAT);
528 }
529
530 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
531 @Override
532 public void visitFMUL(final FMUL o) {
533 stack().pop(2);
534 stack().push(Type.FLOAT);
535 }
536
537 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
538 @Override
539 public void visitFNEG(final FNEG o) {
540 stack().pop();
541 stack().push(Type.FLOAT);
542 }
543
544 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
545 @Override
546 public void visitFREM(final FREM o) {
547 stack().pop(2);
548 stack().push(Type.FLOAT);
549 }
550
551 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
552 @Override
553 public void visitFRETURN(final FRETURN o) {
554 stack().pop();
555 }
556
557 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
558 @Override
559 public void visitFSTORE(final FSTORE o) {
560 locals().set(o.getIndex(), stack().pop());
561 }
562
563 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
564 @Override
565 public void visitFSUB(final FSUB o) {
566 stack().pop(2);
567 stack().push(Type.FLOAT);
568 }
569
570 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
571 @Override
572 public void visitGETFIELD(final GETFIELD o) {
573 stack().pop();
574 Type t = o.getFieldType(cpg);
575 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
576 t = Type.INT;
577 }
578 stack().push(t);
579 }
580
581 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
582 @Override
583 public void visitGETSTATIC(final GETSTATIC o) {
584 Type t = o.getFieldType(cpg);
585 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
586 t = Type.INT;
587 }
588 stack().push(t);
589 }
590
591 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
592 @Override
593 public void visitGOTO(final GOTO o) {
594 // no stack changes.
595 }
596
597 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
598 @Override
599 public void visitGOTO_W(final GOTO_W o) {
600 // no stack changes.
601 }
602
603 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
604 @Override
605 public void visitI2B(final I2B o) {
606 stack().pop();
607 stack().push(Type.INT);
608 }
609
610 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
611 @Override
612 public void visitI2C(final I2C o) {
613 stack().pop();
614 stack().push(Type.INT);
615 }
616
617 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
618 @Override
619 public void visitI2D(final I2D o) {
620 stack().pop();
621 stack().push(Type.DOUBLE);
622 }
623
624 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
625 @Override
626 public void visitI2F(final I2F o) {
627 stack().pop();
628 stack().push(Type.FLOAT);
629 }
630
631 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
632 @Override
633 public void visitI2L(final I2L o) {
634 stack().pop();
635 stack().push(Type.LONG);
636 }
637
638 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
639 @Override
640 public void visitI2S(final I2S o) {
641 stack().pop();
642 stack().push(Type.INT);
643 }
644
645 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
646 @Override
647 public void visitIADD(final IADD o) {
648 stack().pop(2);
649 stack().push(Type.INT);
650 }
651
652 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
653 @Override
654 public void visitIALOAD(final IALOAD o) {
655 stack().pop(2);
656 stack().push(Type.INT);
657 }
658
659 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
660 @Override
661 public void visitIAND(final IAND o) {
662 stack().pop(2);
663 stack().push(Type.INT);
664 }
665
666 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
667 @Override
668 public void visitIASTORE(final IASTORE o) {
669 stack().pop(3);
670 }
671
672 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
673 @Override
674 public void visitICONST(final ICONST o) {
675 stack().push(Type.INT);
676 }
677
678 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
679 @Override
680 public void visitIDIV(final IDIV o) {
681 stack().pop(2);
682 stack().push(Type.INT);
683 }
684
685 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
686 @Override
687 public void visitIF_ACMPEQ(final IF_ACMPEQ o) {
688 stack().pop(2);
689 }
690
691 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
692 @Override
693 public void visitIF_ACMPNE(final IF_ACMPNE o) {
694 stack().pop(2);
695 }
696
697 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
698 @Override
699 public void visitIF_ICMPEQ(final IF_ICMPEQ o) {
700 stack().pop(2);
701 }
702
703 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
704 @Override
705 public void visitIF_ICMPGE(final IF_ICMPGE o) {
706 stack().pop(2);
707 }
708
709 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
710 @Override
711 public void visitIF_ICMPGT(final IF_ICMPGT o) {
712 stack().pop(2);
713 }
714
715 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
716 @Override
717 public void visitIF_ICMPLE(final IF_ICMPLE o) {
718 stack().pop(2);
719 }
720
721 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
722 @Override
723 public void visitIF_ICMPLT(final IF_ICMPLT o) {
724 stack().pop(2);
725 }
726
727 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
728 @Override
729 public void visitIF_ICMPNE(final IF_ICMPNE o) {
730 stack().pop(2);
731 }
732
733 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
734 @Override
735 public void visitIFEQ(final IFEQ o) {
736 stack().pop();
737 }
738
739 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
740 @Override
741 public void visitIFGE(final IFGE o) {
742 stack().pop();
743 }
744
745 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
746 @Override
747 public void visitIFGT(final IFGT o) {
748 stack().pop();
749 }
750
751 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
752 @Override
753 public void visitIFLE(final IFLE o) {
754 stack().pop();
755 }
756
757 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
758 @Override
759 public void visitIFLT(final IFLT o) {
760 stack().pop();
761 }
762
763 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
764 @Override
765 public void visitIFNE(final IFNE o) {
766 stack().pop();
767 }
768
769 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
770 @Override
771 public void visitIFNONNULL(final IFNONNULL o) {
772 stack().pop();
773 }
774
775 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
776 @Override
777 public void visitIFNULL(final IFNULL o) {
778 stack().pop();
779 }
780
781 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
782 @Override
783 public void visitIINC(final IINC o) {
784 // stack is not changed.
785 }
786
787 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
788 @Override
789 public void visitILOAD(final ILOAD o) {
790 stack().push(Type.INT);
791 }
792
793 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
794 @Override
795 public void visitIMUL(final IMUL o) {
796 stack().pop(2);
797 stack().push(Type.INT);
798 }
799
800 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
801 @Override
802 public void visitINEG(final INEG o) {
803 stack().pop();
804 stack().push(Type.INT);
805 }
806
807 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
808 @Override
809 public void visitINSTANCEOF(final INSTANCEOF o) {
810 stack().pop();
811 stack().push(Type.INT);
812 }
813
814 private void visitInvokedInternals(final InvokeInstruction o) {
815 stack().pop(o.getArgumentTypes(cpg).length);
816 // We are sure the invoked method will xRETURN eventually
817 // We simulate xRETURNs functionality here because we
818 // don't really "jump into" and simulate the invoked
819 // method.
820 if (o.getReturnType(cpg) != Type.VOID) {
821 Type t = o.getReturnType(cpg);
822 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
823 t = Type.INT;
824 }
825 stack().push(t);
826 }
827 }
828
829 /**
830 * Symbolically executes the corresponding Java Virtual Machine instruction.
831 *
832 * @since 6.0
833 */
834 @Override
835 public void visitINVOKEDYNAMIC(final INVOKEDYNAMIC o) {
836 visitInvokedInternals(o);
837 }
838
839 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
840 @Override
841 public void visitINVOKEINTERFACE(final INVOKEINTERFACE o) {
842 stack().pop(); // objectref
843 stack().pop(o.getArgumentTypes(cpg).length);
844 // We are sure the invoked method will xRETURN eventually
845 // We simulate xRETURNs functionality here because we
846 // don't really "jump into" and simulate the invoked
847 // method.
848 if (o.getReturnType(cpg) != Type.VOID) {
849 Type t = o.getReturnType(cpg);
850 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
851 t = Type.INT;
852 }
853 stack().push(t);
854 }
855 }
856
857 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
858 @Override
859 public void visitINVOKESPECIAL(final INVOKESPECIAL o) {
860 if (o.getMethodName(cpg).equals(Const.CONSTRUCTOR_NAME)) {
861 final UninitializedObjectType t = (UninitializedObjectType) stack().peek(o.getArgumentTypes(cpg).length);
862 if (t == Frame.getThis()) {
863 Frame.setThis(null);
864 }
865 stack().initializeObject(t);
866 locals().initializeObject(t);
867 }
868 stack().pop(); // objectref
869 stack().pop(o.getArgumentTypes(cpg).length);
870 // We are sure the invoked method will xRETURN eventually
871 // We simulate xRETURNs functionality here because we
872 // don't really "jump into" and simulate the invoked
873 // method.
874 if (o.getReturnType(cpg) != Type.VOID) {
875 Type t = o.getReturnType(cpg);
876 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
877 t = Type.INT;
878 }
879 stack().push(t);
880 }
881 }
882
883 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
884 @Override
885 public void visitINVOKESTATIC(final INVOKESTATIC o) {
886 visitInvokedInternals(o);
887 }
888
889 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
890 @Override
891 public void visitINVOKEVIRTUAL(final INVOKEVIRTUAL o) {
892 stack().pop(); // objectref
893 stack().pop(o.getArgumentTypes(cpg).length);
894 // We are sure the invoked method will xRETURN eventually
895 // We simulate xRETURNs functionality here because we
896 // don't really "jump into" and simulate the invoked
897 // method.
898 if (o.getReturnType(cpg) != Type.VOID) {
899 Type t = o.getReturnType(cpg);
900 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
901 t = Type.INT;
902 }
903 stack().push(t);
904 }
905 }
906
907 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
908 @Override
909 public void visitIOR(final IOR o) {
910 stack().pop(2);
911 stack().push(Type.INT);
912 }
913
914 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
915 @Override
916 public void visitIREM(final IREM o) {
917 stack().pop(2);
918 stack().push(Type.INT);
919 }
920
921 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
922 @Override
923 public void visitIRETURN(final IRETURN o) {
924 stack().pop();
925 }
926
927 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
928 @Override
929 public void visitISHL(final ISHL o) {
930 stack().pop(2);
931 stack().push(Type.INT);
932 }
933
934 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
935 @Override
936 public void visitISHR(final ISHR o) {
937 stack().pop(2);
938 stack().push(Type.INT);
939 }
940
941 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
942 @Override
943 public void visitISTORE(final ISTORE o) {
944 locals().set(o.getIndex(), stack().pop());
945 }
946
947 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
948 @Override
949 public void visitISUB(final ISUB o) {
950 stack().pop(2);
951 stack().push(Type.INT);
952 }
953
954 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
955 @Override
956 public void visitIUSHR(final IUSHR o) {
957 stack().pop(2);
958 stack().push(Type.INT);
959 }
960
961 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
962 @Override
963 public void visitIXOR(final IXOR o) {
964 stack().pop(2);
965 stack().push(Type.INT);
966 }
967
968 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
969 @Override
970 public void visitJSR(final JSR o) {
971 stack().push(new ReturnaddressType(o.physicalSuccessor()));
972 //System.err.println("TODO-----------:"+o.physicalSuccessor());
973 }
974
975 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
976 @Override
977 public void visitJSR_W(final JSR_W o) {
978 stack().push(new ReturnaddressType(o.physicalSuccessor()));
979 }
980
981 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
982 @Override
983 public void visitL2D(final L2D o) {
984 stack().pop();
985 stack().push(Type.DOUBLE);
986 }
987
988 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
989 @Override
990 public void visitL2F(final L2F o) {
991 stack().pop();
992 stack().push(Type.FLOAT);
993 }
994
995 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
996 @Override
997 public void visitL2I(final L2I o) {
998 stack().pop();
999 stack().push(Type.INT);
1000 }
1001
1002 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1003 @Override
1004 public void visitLADD(final LADD o) {
1005 stack().pop(2);
1006 stack().push(Type.LONG);
1007 }
1008
1009 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1010 @Override
1011 public void visitLALOAD(final LALOAD o) {
1012 stack().pop(2);
1013 stack().push(Type.LONG);
1014 }
1015
1016 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1017 @Override
1018 public void visitLAND(final LAND o) {
1019 stack().pop(2);
1020 stack().push(Type.LONG);
1021 }
1022
1023 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1024 @Override
1025 public void visitLASTORE(final LASTORE o) {
1026 stack().pop(3);
1027 }
1028
1029 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1030 @Override
1031 public void visitLCMP(final LCMP o) {
1032 stack().pop(2);
1033 stack().push(Type.INT);
1034 }
1035
1036 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1037 @Override
1038 public void visitLCONST(final LCONST o) {
1039 stack().push(Type.LONG);
1040 }
1041
1042 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1043 @Override
1044 public void visitLDC(final LDC o) {
1045 final Constant c = cpg.getConstant(o.getIndex());
1046 if (c instanceof ConstantInteger) {
1047 stack().push(Type.INT);
1048 }
1049 if (c instanceof ConstantFloat) {
1050 stack().push(Type.FLOAT);
1051 }
1052 if (c instanceof ConstantString) {
1053 stack().push(Type.STRING);
1054 }
1055 if (c instanceof ConstantClass) {
1056 stack().push(Type.CLASS);
1057 }
1058 if (c instanceof ConstantDynamic) {
1059 stack().push(Type.OBJECT);
1060 }
1061 }
1062
1063 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1064 public void visitLDC_W(final LDC_W o) {
1065 final Constant c = cpg.getConstant(o.getIndex());
1066 if (c instanceof ConstantInteger) {
1067 stack().push(Type.INT);
1068 }
1069 if (c instanceof ConstantFloat) {
1070 stack().push(Type.FLOAT);
1071 }
1072 if (c instanceof ConstantString) {
1073 stack().push(Type.STRING);
1074 }
1075 if (c instanceof ConstantClass) {
1076 stack().push(Type.CLASS);
1077 }
1078 }
1079
1080 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1081 @Override
1082 public void visitLDC2_W(final LDC2_W o) {
1083 final Constant c = cpg.getConstant(o.getIndex());
1084 if (c instanceof ConstantLong) {
1085 stack().push(Type.LONG);
1086 }
1087 if (c instanceof ConstantDouble) {
1088 stack().push(Type.DOUBLE);
1089 }
1090 }
1091
1092 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1093 @Override
1094 public void visitLDIV(final LDIV o) {
1095 stack().pop(2);
1096 stack().push(Type.LONG);
1097 }
1098
1099 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1100 @Override
1101 public void visitLLOAD(final LLOAD o) {
1102 stack().push(locals().get(o.getIndex()));
1103 }
1104
1105 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1106 @Override
1107 public void visitLMUL(final LMUL o) {
1108 stack().pop(2);
1109 stack().push(Type.LONG);
1110 }
1111
1112 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1113 @Override
1114 public void visitLNEG(final LNEG o) {
1115 stack().pop();
1116 stack().push(Type.LONG);
1117 }
1118
1119 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1120 @Override
1121 public void visitLOOKUPSWITCH(final LOOKUPSWITCH o) {
1122 stack().pop(); // key
1123 }
1124
1125 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1126 @Override
1127 public void visitLOR(final LOR o) {
1128 stack().pop(2);
1129 stack().push(Type.LONG);
1130 }
1131
1132 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1133 @Override
1134 public void visitLREM(final LREM o) {
1135 stack().pop(2);
1136 stack().push(Type.LONG);
1137 }
1138
1139 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1140 @Override
1141 public void visitLRETURN(final LRETURN o) {
1142 stack().pop();
1143 }
1144
1145 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1146 @Override
1147 public void visitLSHL(final LSHL o) {
1148 stack().pop(2);
1149 stack().push(Type.LONG);
1150 }
1151
1152 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1153 @Override
1154 public void visitLSHR(final LSHR o) {
1155 stack().pop(2);
1156 stack().push(Type.LONG);
1157 }
1158
1159 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1160 @Override
1161 public void visitLSTORE(final LSTORE o) {
1162 locals().set(o.getIndex(), stack().pop());
1163 locals().set(o.getIndex() + 1, Type.UNKNOWN);
1164 }
1165
1166 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1167 @Override
1168 public void visitLSUB(final LSUB o) {
1169 stack().pop(2);
1170 stack().push(Type.LONG);
1171 }
1172
1173 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1174 @Override
1175 public void visitLUSHR(final LUSHR o) {
1176 stack().pop(2);
1177 stack().push(Type.LONG);
1178 }
1179
1180 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1181 @Override
1182 public void visitLXOR(final LXOR o) {
1183 stack().pop(2);
1184 stack().push(Type.LONG);
1185 }
1186
1187 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1188 @Override
1189 public void visitMONITORENTER(final MONITORENTER o) {
1190 stack().pop();
1191 }
1192
1193 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1194 @Override
1195 public void visitMONITOREXIT(final MONITOREXIT o) {
1196 stack().pop();
1197 }
1198
1199 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1200 @Override
1201 public void visitMULTIANEWARRAY(final MULTIANEWARRAY o) {
1202 stack().pop(o.getDimensions());
1203 stack().push(o.getType(cpg));
1204 }
1205
1206 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1207 @Override
1208 public void visitNEW(final NEW o) {
1209 stack().push(new UninitializedObjectType((ObjectType) o.getType(cpg)));
1210 }
1211
1212 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1213 @Override
1214 public void visitNEWARRAY(final NEWARRAY o) {
1215 stack().pop();
1216 stack().push(o.getType());
1217 }
1218
1219 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1220 @Override
1221 public void visitNOP(final NOP o) {
1222 }
1223
1224 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1225 @Override
1226 public void visitPOP(final POP o) {
1227 stack().pop();
1228 }
1229
1230 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1231 @Override
1232 public void visitPOP2(final POP2 o) {
1233 final Type t = stack().pop();
1234 if (t.getSize() == 1) {
1235 stack().pop();
1236 }
1237 }
1238
1239 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1240 @Override
1241 public void visitPUTFIELD(final PUTFIELD o) {
1242 stack().pop(2);
1243 }
1244
1245 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1246 @Override
1247 public void visitPUTSTATIC(final PUTSTATIC o) {
1248 stack().pop();
1249 }
1250
1251 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1252 @Override
1253 public void visitRET(final RET o) {
1254 // do nothing, return address
1255 // is in the local variables.
1256 }
1257
1258 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1259 @Override
1260 public void visitRETURN(final RETURN o) {
1261 // do nothing.
1262 }
1263
1264 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1265 @Override
1266 public void visitSALOAD(final SALOAD o) {
1267 stack().pop(2);
1268 stack().push(Type.INT);
1269 }
1270
1271 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1272 @Override
1273 public void visitSASTORE(final SASTORE o) {
1274 stack().pop(3);
1275 }
1276
1277 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1278 @Override
1279 public void visitSIPUSH(final SIPUSH o) {
1280 stack().push(Type.INT);
1281 }
1282
1283 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1284 @Override
1285 public void visitSWAP(final SWAP o) {
1286 final Type t = stack().pop();
1287 final Type u = stack().pop();
1288 stack().push(t);
1289 stack().push(u);
1290 }
1291
1292 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
1293 @Override
1294 public void visitTABLESWITCH(final TABLESWITCH o) {
1295 stack().pop();
1296 }
1297 }