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