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