1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * https://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.bcel.verifier.structurals;
20
21 import org.apache.bcel.Const;
22 import org.apache.bcel.classfile.Constant;
23 import org.apache.bcel.classfile.ConstantClass;
24 import org.apache.bcel.classfile.ConstantDouble;
25 import org.apache.bcel.classfile.ConstantDynamic;
26 import org.apache.bcel.classfile.ConstantFloat;
27 import org.apache.bcel.classfile.ConstantInteger;
28 import org.apache.bcel.classfile.ConstantLong;
29 import org.apache.bcel.classfile.ConstantString;
30 // CHECKSTYLE:OFF (there are lots of references!)
31 import org.apache.bcel.generic.*;
32 //CHECKSTYLE:ON
33
34 /**
35 * This Visitor class may be used for a type-based Java Virtual Machine simulation.
36 *
37 * <p>
38 * It does not check for correct types on the OperandStack or in the LocalVariables; nor does it check their sizes are
39 * sufficiently big. Thus, to use this Visitor for bytecode verifying, you have to make sure externally that the type
40 * constraints of the Java Virtual Machine instructions are satisfied. An InstConstraintVisitor may be used for this.
41 * Anyway, this Visitor does not mandate it. For example, when you visitIADD(IADD o), then there are two stack slots
42 * popped and one stack slot containing a Type.INT is pushed (where you could also pop only one slot if you know there
43 * are two Type.INT on top of the stack). Monitor-specific behavior is not simulated.
44 * </p>
45 *
46 * <strong>Conventions:</strong>
47 *
48 * <p>
49 * Type.VOID will never be pushed onto the stack. Type.DOUBLE and Type.LONG that would normally take up two stack slots
50 * (like Double_HIGH and Double_LOW) are represented by a simple single Type.DOUBLE or Type.LONG object on the stack
51 * here.
52 * </p>
53 *
54 * <p>
55 * If a two-slot type is stored into a local variable, the next variable is given the type Type.UNKNOWN.
56 * </p>
57 *
58 * @see #visitDSTORE(DSTORE o)
59 * @see InstConstraintVisitor
60 */
61 public class ExecutionVisitor extends EmptyVisitor {
62
63 /**
64 * The executionframe we're operating on.
65 */
66 private Frame frame;
67
68 /**
69 * The ConstantPoolGen we're working with.
70 *
71 * @see #setConstantPoolGen(ConstantPoolGen)
72 */
73 private ConstantPoolGen cpg;
74
75 /**
76 * Constructs a new instance of this class.
77 */
78 public ExecutionVisitor() {
79 }
80
81 /**
82 * The LocalVariables from the current Frame we're operating on.
83 *
84 * @see #setFrame(Frame)
85 */
86 private LocalVariables locals() {
87 return frame.getLocals();
88 }
89
90 /**
91 * Sets the ConstantPoolGen needed for symbolic execution.
92 */
93 public void setConstantPoolGen(final ConstantPoolGen cpg) { // TODO could be package-protected?
94 this.cpg = cpg;
95 }
96
97 /**
98 * The only method granting access to the single instance of the ExecutionVisitor class. Before actively using this
99 * instance, <B>SET THE ConstantPoolGen FIRST</B>.
100 *
101 * @see #setConstantPoolGen(ConstantPoolGen)
102 */
103 public void setFrame(final Frame f) { // TODO could be package-protected?
104 this.frame = f;
105 }
106
107 /**
108 * The OperandStack from the current Frame we're operating on.
109 *
110 * @see #setFrame(Frame)
111 */
112 private OperandStack stack() {
113 return frame.getStack();
114 }
115
116 /// ** Symbolically executes the corresponding Java Virtual Machine instruction. */
117 // public void visitWIDE(WIDE o) {
118 // The WIDE instruction is modeled as a flag
119 // of the embedded instructions in BCEL.
120 // Therefore BCEL checks for possible errors
121 // when parsing in the .class file: We don't
122 // have even the possibility to care for WIDE
123 // here.
124 // }
125
126 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
127 @Override
128 public void visitAALOAD(final AALOAD o) {
129 stack().pop(); // pop the index int
130 // System.out.print(stack().peek());
131 final Type t = stack().pop(); // Pop Array type
132 if (t == Type.NULL) {
133 stack().push(Type.NULL);
134 } else {
135 final ArrayType at = (ArrayType) t;
136 stack().push(at.getElementType());
137 }
138 }
139
140 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
141 @Override
142 public void visitAASTORE(final AASTORE o) {
143 stack().pop(3);
144 }
145
146 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
147 @Override
148 public void visitACONST_NULL(final ACONST_NULL o) {
149 stack().push(Type.NULL);
150 }
151
152 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
153 @Override
154 public void visitALOAD(final ALOAD o) {
155 stack().push(locals().get(o.getIndex()));
156 }
157
158 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
159 @Override
160 public void visitANEWARRAY(final ANEWARRAY o) {
161 stack().pop(); // count
162 stack().push(new ArrayType(o.getType(cpg), 1));
163 }
164
165 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
166 @Override
167 public void visitARETURN(final ARETURN o) {
168 stack().pop();
169 }
170
171 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
172 @Override
173 public void visitARRAYLENGTH(final ARRAYLENGTH o) {
174 stack().pop();
175 stack().push(Type.INT);
176 }
177
178 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
179 @Override
180 public void visitASTORE(final ASTORE o) {
181 locals().set(o.getIndex(), stack().pop());
182 // System.err.println("TODO-DEBUG: set LV '"+o.getIndex()+"' to '"+locals().get(o.getIndex())+"'.");
183 }
184
185 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
186 @Override
187 public void visitATHROW(final ATHROW o) {
188 final Type t = stack().pop();
189 stack().clear();
190 if (t.equals(Type.NULL)) {
191 stack().push(Type.getType("Ljava/lang/NullPointerException;"));
192 } else {
193 stack().push(t);
194 }
195 }
196
197 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
198 @Override
199 public void visitBALOAD(final BALOAD o) {
200 stack().pop(2);
201 stack().push(Type.INT);
202 }
203
204 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
205 @Override
206 public void visitBASTORE(final BASTORE o) {
207 stack().pop(3);
208 }
209
210 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
211 @Override
212 public void visitBIPUSH(final BIPUSH o) {
213 stack().push(Type.INT);
214 }
215
216 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
217 @Override
218 public void visitCALOAD(final CALOAD o) {
219 stack().pop(2);
220 stack().push(Type.INT);
221 }
222
223 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
224 @Override
225 public void visitCASTORE(final CASTORE o) {
226 stack().pop(3);
227 }
228
229 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
230 @Override
231 public void visitCHECKCAST(final CHECKCAST o) {
232 // It's possibly wrong to do so, but SUN's
233 // ByteCode verifier seems to do (only) this, too.
234 // TODO: One could use a sophisticated analysis here to check
235 // if a type cannot possibly be cated to another and by
236 // so doing predict the ClassCastException at run-time.
237 stack().pop();
238 stack().push(o.getType(cpg));
239 }
240
241 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
242 @Override
243 public void visitD2F(final D2F o) {
244 stack().pop();
245 stack().push(Type.FLOAT);
246 }
247
248 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
249 @Override
250 public void visitD2I(final D2I o) {
251 stack().pop();
252 stack().push(Type.INT);
253 }
254
255 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
256 @Override
257 public void visitD2L(final D2L o) {
258 stack().pop();
259 stack().push(Type.LONG);
260 }
261
262 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
263 @Override
264 public void visitDADD(final DADD o) {
265 stack().pop(2);
266 stack().push(Type.DOUBLE);
267 }
268
269 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
270 @Override
271 public void visitDALOAD(final DALOAD o) {
272 stack().pop(2);
273 stack().push(Type.DOUBLE);
274 }
275
276 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
277 @Override
278 public void visitDASTORE(final DASTORE o) {
279 stack().pop(3);
280 }
281
282 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
283 @Override
284 public void visitDCMPG(final DCMPG o) {
285 stack().pop(2);
286 stack().push(Type.INT);
287 }
288
289 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
290 @Override
291 public void visitDCMPL(final DCMPL o) {
292 stack().pop(2);
293 stack().push(Type.INT);
294 }
295
296 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
297 @Override
298 public void visitDCONST(final DCONST o) {
299 stack().push(Type.DOUBLE);
300 }
301
302 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
303 @Override
304 public void visitDDIV(final DDIV o) {
305 stack().pop(2);
306 stack().push(Type.DOUBLE);
307 }
308
309 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
310 @Override
311 public void visitDLOAD(final DLOAD o) {
312 stack().push(Type.DOUBLE);
313 }
314
315 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
316 @Override
317 public void visitDMUL(final DMUL o) {
318 stack().pop(2);
319 stack().push(Type.DOUBLE);
320 }
321
322 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
323 @Override
324 public void visitDNEG(final DNEG o) {
325 stack().pop();
326 stack().push(Type.DOUBLE);
327 }
328
329 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
330 @Override
331 public void visitDREM(final DREM o) {
332 stack().pop(2);
333 stack().push(Type.DOUBLE);
334 }
335
336 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
337 @Override
338 public void visitDRETURN(final DRETURN o) {
339 stack().pop();
340 }
341
342 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
343 @Override
344 public void visitDSTORE(final DSTORE o) {
345 locals().set(o.getIndex(), stack().pop());
346 locals().set(o.getIndex() + 1, Type.UNKNOWN);
347 }
348
349 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
350 @Override
351 public void visitDSUB(final DSUB o) {
352 stack().pop(2);
353 stack().push(Type.DOUBLE);
354 }
355
356 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
357 @Override
358 public void visitDUP(final DUP o) {
359 final Type t = stack().pop();
360 stack().push(t);
361 stack().push(t);
362 }
363
364 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
365 @Override
366 public void visitDUP_X1(final DUP_X1 o) {
367 final Type w1 = stack().pop();
368 final Type w2 = stack().pop();
369 stack().push(w1);
370 stack().push(w2);
371 stack().push(w1);
372 }
373
374 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
375 @Override
376 public void visitDUP_X2(final DUP_X2 o) {
377 final Type w1 = stack().pop();
378 final Type w2 = stack().pop();
379 if (w2.getSize() == 2) {
380 stack().push(w1);
381 } else {
382 final Type w3 = stack().pop();
383 stack().push(w1);
384 stack().push(w3);
385 }
386 stack().push(w2);
387 stack().push(w1);
388 }
389
390 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
391 @Override
392 public void visitDUP2(final DUP2 o) {
393 final Type t = stack().pop();
394 if (t.getSize() == 2) {
395 stack().push(t);
396 } else { // t.getSize() is 1
397 final Type u = stack().pop();
398 stack().push(u);
399 stack().push(t);
400 stack().push(u);
401 }
402 stack().push(t);
403 }
404
405 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
406 @Override
407 public void visitDUP2_X1(final DUP2_X1 o) {
408 final Type t = stack().pop();
409 if (t.getSize() == 2) {
410 final Type u = stack().pop();
411 stack().push(t);
412 stack().push(u);
413 } else { // t.getSize() is1
414 final Type u = stack().pop();
415 final Type v = stack().pop();
416 stack().push(u);
417 stack().push(t);
418 stack().push(v);
419 stack().push(u);
420 }
421 stack().push(t);
422 }
423
424 /** Symbolically executes the corresponding Java Virtual Machine instruction. */
425 @Override
426 public void visitDUP2_X2(final DUP2_X2 o) {
427 final Type t = stack().pop();
428 if (t.getSize() == 2) {
429 final Type u = stack().pop();
430 if (u.getSize() == 2) {
431 stack().push(t);
432 } else {
433 final Type v = stack().pop();
434 stack().push(t);
435 stack().push(v);
436 }
437 stack().push(u);
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 }
453 stack().push(t);
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 }