View Javadoc
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 }