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