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