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