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