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