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