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