    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 */
    017package org.apache.bcel.verifier.structurals;
    018
    019import org.apache.bcel.Const;
    020import org.apache.bcel.classfile.Constant;
    021import org.apache.bcel.classfile.ConstantClass;
    022import org.apache.bcel.classfile.ConstantDouble;
    023import org.apache.bcel.classfile.ConstantDynamic;
    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     * 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 modeled 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 possibility 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    private void visitInvokedInternals(final InvokeInstruction o) {
    815        stack().pop(o.getArgumentTypes(cpg).length);
    816        // We are sure the invoked method will xRETURN eventually
    817        // We simulate xRETURNs functionality here because we
    818        // don't really "jump into" and simulate the invoked
    819        // method.
    820        if (o.getReturnType(cpg) != Type.VOID) {
    821            Type t = o.getReturnType(cpg);
    822            if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
    823                t = Type.INT;
    824            }
    825            stack().push(t);
    826        }
    827    }
    828
    829    /**
    830     * Symbolically executes the corresponding Java Virtual Machine instruction.
    831     *
    832     * @since 6.0
    833     */
    834    @Override
    835    public void visitINVOKEDYNAMIC(final INVOKEDYNAMIC o) {
    836        visitInvokedInternals(o);
    837    }
    838
    839    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    840    @Override
    841    public void visitINVOKEINTERFACE(final INVOKEINTERFACE o) {
    842        stack().pop(); // objectref
    843        stack().pop(o.getArgumentTypes(cpg).length);
    844        // We are sure the invoked method will xRETURN eventually
    845        // We simulate xRETURNs functionality here because we
    846        // don't really "jump into" and simulate the invoked
    847        // method.
    848        if (o.getReturnType(cpg) != Type.VOID) {
    849            Type t = o.getReturnType(cpg);
    850            if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
    851                t = Type.INT;
    852            }
    853            stack().push(t);
    854        }
    855    }
    856
    857    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    858    @Override
    859    public void visitINVOKESPECIAL(final INVOKESPECIAL o) {
    860        if (o.getMethodName(cpg).equals(Const.CONSTRUCTOR_NAME)) {
    861            final UninitializedObjectType t = (UninitializedObjectType) stack().peek(o.getArgumentTypes(cpg).length);
    862            if (t == Frame.getThis()) {
    863                Frame.setThis(null);
    864            }
    865            stack().initializeObject(t);
    866            locals().initializeObject(t);
    867        }
    868        stack().pop(); // objectref
    869        stack().pop(o.getArgumentTypes(cpg).length);
    870        // We are sure the invoked method will xRETURN eventually
    871        // We simulate xRETURNs functionality here because we
    872        // don't really "jump into" and simulate the invoked
    873        // method.
    874        if (o.getReturnType(cpg) != Type.VOID) {
    875            Type t = o.getReturnType(cpg);
    876            if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
    877                t = Type.INT;
    878            }
    879            stack().push(t);
    880        }
    881    }
    882
    883    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    884    @Override
    885    public void visitINVOKESTATIC(final INVOKESTATIC o) {
    886        visitInvokedInternals(o);
    887    }
    888
    889    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    890    @Override
    891    public void visitINVOKEVIRTUAL(final INVOKEVIRTUAL o) {
    892        stack().pop(); // objectref
    893        stack().pop(o.getArgumentTypes(cpg).length);
    894        // We are sure the invoked method will xRETURN eventually
    895        // We simulate xRETURNs functionality here because we
    896        // don't really "jump into" and simulate the invoked
    897        // method.
    898        if (o.getReturnType(cpg) != Type.VOID) {
    899            Type t = o.getReturnType(cpg);
    900            if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
    901                t = Type.INT;
    902            }
    903            stack().push(t);
    904        }
    905    }
    906
    907    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    908    @Override
    909    public void visitIOR(final IOR o) {
    910        stack().pop(2);
    911        stack().push(Type.INT);
    912    }
    913
    914    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    915    @Override
    916    public void visitIREM(final IREM 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 visitIRETURN(final IRETURN o) {
    924        stack().pop();
    925    }
    926
    927    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    928    @Override
    929    public void visitISHL(final ISHL o) {
    930        stack().pop(2);
    931        stack().push(Type.INT);
    932    }
    933
    934    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    935    @Override
    936    public void visitISHR(final ISHR 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 visitISTORE(final ISTORE o) {
    944        locals().set(o.getIndex(), stack().pop());
    945    }
    946
    947    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    948    @Override
    949    public void visitISUB(final ISUB o) {
    950        stack().pop(2);
    951        stack().push(Type.INT);
    952    }
    953
    954    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    955    @Override
    956    public void visitIUSHR(final IUSHR 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 visitIXOR(final IXOR 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 visitJSR(final JSR o) {
    971        stack().push(new ReturnaddressType(o.physicalSuccessor()));
    972//System.err.println("TODO-----------:"+o.physicalSuccessor());
    973    }
    974
    975    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    976    @Override
    977    public void visitJSR_W(final JSR_W o) {
    978        stack().push(new ReturnaddressType(o.physicalSuccessor()));
    979    }
    980
    981    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    982    @Override
    983    public void visitL2D(final L2D o) {
    984        stack().pop();
    985        stack().push(Type.DOUBLE);
    986    }
    987
    988    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    989    @Override
    990    public void visitL2F(final L2F o) {
    991        stack().pop();
    992        stack().push(Type.FLOAT);
    993    }
    994
    995    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    996    @Override
    997    public void visitL2I(final L2I o) {
    998        stack().pop();
    999        stack().push(Type.INT);
    1000    }
    1001
    1002    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1003    @Override
    1004    public void visitLADD(final LADD o) {
    1005        stack().pop(2);
    1006        stack().push(Type.LONG);
    1007    }
    1008
    1009    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1010    @Override
    1011    public void visitLALOAD(final LALOAD 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 visitLAND(final LAND 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 visitLASTORE(final LASTORE o) {
    1026        stack().pop(3);
    1027    }
    1028
    1029    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1030    @Override
    1031    public void visitLCMP(final LCMP o) {
    1032        stack().pop(2);
    1033        stack().push(Type.INT);
    1034    }
    1035
    1036    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1037    @Override
    1038    public void visitLCONST(final LCONST o) {
    1039        stack().push(Type.LONG);
    1040    }
    1041
    1042    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1043    @Override
    1044    public void visitLDC(final LDC o) {
    1045        final Constant c = cpg.getConstant(o.getIndex());
    1046        if (c instanceof ConstantInteger) {
    1047            stack().push(Type.INT);
    1048        }
    1049        if (c instanceof ConstantFloat) {
    1050            stack().push(Type.FLOAT);
    1051        }
    1052        if (c instanceof ConstantString) {
    1053            stack().push(Type.STRING);
    1054        }
    1055        if (c instanceof ConstantClass) {
    1056            stack().push(Type.CLASS);
    1057        }
    1058        if (c instanceof ConstantDynamic) {
    1059            stack().push(Type.OBJECT);
    1060        }
    1061    }
    1062
    1063    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1064    public void visitLDC_W(final LDC_W o) {
    1065        final Constant c = cpg.getConstant(o.getIndex());
    1066        if (c instanceof ConstantInteger) {
    1067            stack().push(Type.INT);
    1068        }
    1069        if (c instanceof ConstantFloat) {
    1070            stack().push(Type.FLOAT);
    1071        }
    1072        if (c instanceof ConstantString) {
    1073            stack().push(Type.STRING);
    1074        }
    1075        if (c instanceof ConstantClass) {
    1076            stack().push(Type.CLASS);
    1077        }
    1078    }
    1079
    1080    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1081    @Override
    1082    public void visitLDC2_W(final LDC2_W o) {
    1083        final Constant c = cpg.getConstant(o.getIndex());
    1084        if (c instanceof ConstantLong) {
    1085            stack().push(Type.LONG);
    1086        }
    1087        if (c instanceof ConstantDouble) {
    1088            stack().push(Type.DOUBLE);
    1089        }
    1090    }
    1091
    1092    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1093    @Override
    1094    public void visitLDIV(final LDIV o) {
    1095        stack().pop(2);
    1096        stack().push(Type.LONG);
    1097    }
    1098
    1099    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1100    @Override
    1101    public void visitLLOAD(final LLOAD o) {
    1102        stack().push(locals().get(o.getIndex()));
    1103    }
    1104
    1105    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1106    @Override
    1107    public void visitLMUL(final LMUL o) {
    1108        stack().pop(2);
    1109        stack().push(Type.LONG);
    1110    }
    1111
    1112    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1113    @Override
    1114    public void visitLNEG(final LNEG o) {
    1115        stack().pop();
    1116        stack().push(Type.LONG);
    1117    }
    1118
    1119    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1120    @Override
    1121    public void visitLOOKUPSWITCH(final LOOKUPSWITCH o) {
    1122        stack().pop(); // key
    1123    }
    1124
    1125    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1126    @Override
    1127    public void visitLOR(final LOR o) {
    1128        stack().pop(2);
    1129        stack().push(Type.LONG);
    1130    }
    1131
    1132    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1133    @Override
    1134    public void visitLREM(final LREM 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 visitLRETURN(final LRETURN o) {
    1142        stack().pop();
    1143    }
    1144
    1145    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1146    @Override
    1147    public void visitLSHL(final LSHL o) {
    1148        stack().pop(2);
    1149        stack().push(Type.LONG);
    1150    }
    1151
    1152    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1153    @Override
    1154    public void visitLSHR(final LSHR 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 visitLSTORE(final LSTORE o) {
    1162        locals().set(o.getIndex(), stack().pop());
    1163        locals().set(o.getIndex() + 1, Type.UNKNOWN);
    1164    }
    1165
    1166    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1167    @Override
    1168    public void visitLSUB(final LSUB o) {
    1169        stack().pop(2);
    1170        stack().push(Type.LONG);
    1171    }
    1172
    1173    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1174    @Override
    1175    public void visitLUSHR(final LUSHR 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 visitLXOR(final LXOR 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 visitMONITORENTER(final MONITORENTER o) {
    1190        stack().pop();
    1191    }
    1192
    1193    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1194    @Override
    1195    public void visitMONITOREXIT(final MONITOREXIT o) {
    1196        stack().pop();
    1197    }
    1198
    1199    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1200    @Override
    1201    public void visitMULTIANEWARRAY(final MULTIANEWARRAY o) {
    1202        stack().pop(o.getDimensions());
    1203        stack().push(o.getType(cpg));
    1204    }
    1205
    1206    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1207    @Override
    1208    public void visitNEW(final NEW o) {
    1209        stack().push(new UninitializedObjectType((ObjectType) o.getType(cpg)));
    1210    }
    1211
    1212    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1213    @Override
    1214    public void visitNEWARRAY(final NEWARRAY o) {
    1215        stack().pop();
    1216        stack().push(o.getType());
    1217    }
    1218
    1219    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1220    @Override
    1221    public void visitNOP(final NOP o) {
    1222    }
    1223
    1224    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1225    @Override
    1226    public void visitPOP(final POP o) {
    1227        stack().pop();
    1228    }
    1229
    1230    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1231    @Override
    1232    public void visitPOP2(final POP2 o) {
    1233        final Type t = stack().pop();
    1234        if (t.getSize() == 1) {
    1235            stack().pop();
    1236        }
    1237    }
    1238
    1239    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1240    @Override
    1241    public void visitPUTFIELD(final PUTFIELD o) {
    1242        stack().pop(2);
    1243    }
    1244
    1245    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1246    @Override
    1247    public void visitPUTSTATIC(final PUTSTATIC o) {
    1248        stack().pop();
    1249    }
    1250
    1251    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1252    @Override
    1253    public void visitRET(final RET o) {
    1254        // do nothing, return address
    1255        // is in the local variables.
    1256    }
    1257
    1258    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1259    @Override
    1260    public void visitRETURN(final RETURN o) {
    1261        // do nothing.
    1262    }
    1263
    1264    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1265    @Override
    1266    public void visitSALOAD(final SALOAD o) {
    1267        stack().pop(2);
    1268        stack().push(Type.INT);
    1269    }
    1270
    1271    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1272    @Override
    1273    public void visitSASTORE(final SASTORE o) {
    1274        stack().pop(3);
    1275    }
    1276
    1277    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1278    @Override
    1279    public void visitSIPUSH(final SIPUSH o) {
    1280        stack().push(Type.INT);
    1281    }
    1282
    1283    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1284    @Override
    1285    public void visitSWAP(final SWAP o) {
    1286        final Type t = stack().pop();
    1287        final Type u = stack().pop();
    1288        stack().push(t);
    1289        stack().push(u);
    1290    }
    1291
    1292    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    1293    @Override
    1294    public void visitTABLESWITCH(final TABLESWITCH o) {
    1295        stack().pop();
    1296    }
    1297}