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