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