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 behaviour 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 * @version $Id: ExecutionVisitor.java 1749603 2016-06-21 20:50:19Z ggregory $
059 * @see #visitDSTORE(DSTORE o)
060 * @see InstConstraintVisitor
061 */
062public class ExecutionVisitor extends EmptyVisitor{
063
064    /**
065     * The executionframe we're operating on.
066     */
067    private Frame frame = null;
068
069    /**
070     * The ConstantPoolGen we're working with.
071     * @see #setConstantPoolGen(ConstantPoolGen)
072     */
073    private ConstantPoolGen cpg = null;
074
075    /**
076     * Constructor. Constructs a new instance of this class.
077     */
078    public ExecutionVisitor() {}
079
080    /**
081     * The OperandStack from the current Frame we're operating on.
082     * @see #setFrame(Frame)
083     */
084    private OperandStack stack() {
085        return frame.getStack();
086    }
087
088    /**
089     * The LocalVariables from the current Frame we're operating on.
090     * @see #setFrame(Frame)
091     */
092    private LocalVariables locals() {
093        return frame.getLocals();
094    }
095
096    /**
097     * Sets the ConstantPoolGen needed for symbolic execution.
098     */
099    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}