    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one
    003 * or more contributor license agreements.  See the NOTICE file
    004 * distributed with this work for additional information
    005 * regarding copyright ownership.  The ASF licenses this file
    006 * to you under the Apache License, Version 2.0 (the
    007 * "License"); you may not use this file except in compliance
    008 * with the License.  You may obtain a copy of the License at
    009 *
    010 *   https://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 * Unless required by applicable law or agreed to in writing,
    013 * software distributed under the License is distributed on an
    014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015 * KIND, either express or implied.  See the License for the
    016 * specific language governing permissions and limitations
    017 * under the License.
    018 */
    019package org.apache.bcel.verifier.structurals;
    020
    021import org.apache.bcel.Const;
    022import org.apache.bcel.classfile.Constant;
    023import org.apache.bcel.classfile.ConstantClass;
    024import org.apache.bcel.classfile.ConstantDouble;
    025import org.apache.bcel.classfile.ConstantDynamic;
    026import org.apache.bcel.classfile.ConstantFloat;
    027import org.apache.bcel.classfile.ConstantInteger;
    028import org.apache.bcel.classfile.ConstantLong;
    029import org.apache.bcel.classfile.ConstantString;
    030// CHECKSTYLE:OFF (there are lots of references!)
    031import org.apache.bcel.generic.*;
    032//CHECKSTYLE:ON
    033
    034/**
    035 * This Visitor class may be used for a type-based Java Virtual Machine simulation.
    036 *
    037 * <p>
    038 * It does not check for correct types on the OperandStack or in the LocalVariables; nor does it check their sizes are
    039 * sufficiently big. Thus, to use this Visitor for bytecode verifying, you have to make sure externally that the type
    040 * constraints of the Java Virtual Machine instructions are satisfied. An InstConstraintVisitor may be used for this.
    041 * Anyway, this Visitor does not mandate it. For example, when you visitIADD(IADD o), then there are two stack slots
    042 * popped and one stack slot containing a Type.INT is pushed (where you could also pop only one slot if you know there
    043 * are two Type.INT on top of the stack). Monitor-specific behavior is not simulated.
    044 * </p>
    045 *
    046 * <strong>Conventions:</strong>
    047 *
    048 * <p>
    049 * Type.VOID will never be pushed onto the stack. Type.DOUBLE and Type.LONG that would normally take up two stack slots
    050 * (like Double_HIGH and Double_LOW) are represented by a simple single Type.DOUBLE or Type.LONG object on the stack
    051 * here.
    052 * </p>
    053 *
    054 * <p>
    055 * If a two-slot type is stored into a local variable, the next variable is given the type Type.UNKNOWN.
    056 * </p>
    057 *
    058 * @see #visitDSTORE(DSTORE o)
    059 * @see InstConstraintVisitor
    060 */
    061public class ExecutionVisitor extends EmptyVisitor {
    062
    063    /**
    064     * The executionframe we're operating on.
    065     */
    066    private Frame frame;
    067
    068    /**
    069     * The ConstantPoolGen we're working with.
    070     *
    071     * @see #setConstantPoolGen(ConstantPoolGen)
    072     */
    073    private ConstantPoolGen cpg;
    074
    075    /**
    076     * Constructs a new instance of this class.
    077     */
    078    public ExecutionVisitor() {
    079    }
    080
    081    /**
    082     * The LocalVariables from the current Frame we're operating on.
    083     *
    084     * @see #setFrame(Frame)
    085     */
    086    private LocalVariables locals() {
    087        return frame.getLocals();
    088    }
    089
    090    /**
    091     * Sets the ConstantPoolGen needed for symbolic execution.
    092     */
    093    public void setConstantPoolGen(final ConstantPoolGen cpg) { // TODO could be package-protected?
    094        this.cpg = cpg;
    095    }
    096
    097    /**
    098     * The only method granting access to the single instance of the ExecutionVisitor class. Before actively using this
    099     * instance, <B>SET THE ConstantPoolGen FIRST</B>.
    100     *
    101     * @see #setConstantPoolGen(ConstantPoolGen)
    102     */
    103    public void setFrame(final Frame f) { // TODO could be package-protected?
    104        this.frame = f;
    105    }
    106
    107    /**
    108     * The OperandStack from the current Frame we're operating on.
    109     *
    110     * @see #setFrame(Frame)
    111     */
    112    private OperandStack stack() {
    113        return frame.getStack();
    114    }
    115
    116    /// ** Symbolically executes the corresponding Java Virtual Machine instruction. */
    117    // public void visitWIDE(WIDE o) {
    118    // The WIDE instruction is modeled as a flag
    119    // of the embedded instructions in BCEL.
    120    // Therefore BCEL checks for possible errors
    121    // when parsing in the .class file: We don't
    122    // have even the possibility to care for WIDE
    123    // here.
    124    // }
    125
    126    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    127    @Override
    128    public void visitAALOAD(final AALOAD o) {
    129        stack().pop(); // pop the index int
    130        // System.out.print(stack().peek());
    131        final Type t = stack().pop(); // Pop Array type
    132        if (t == Type.NULL) {
    133            stack().push(Type.NULL);
    134        } else {
    135            final ArrayType at = (ArrayType) t;
    136            stack().push(at.getElementType());
    137        }
    138    }
    139
    140    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    141    @Override
    142    public void visitAASTORE(final AASTORE o) {
    143        stack().pop(3);
    144    }
    145
    146    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    147    @Override
    148    public void visitACONST_NULL(final ACONST_NULL o) {
    149        stack().push(Type.NULL);
    150    }
    151
    152    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    153    @Override
    154    public void visitALOAD(final ALOAD o) {
    155        stack().push(locals().get(o.getIndex()));
    156    }
    157
    158    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    159    @Override
    160    public void visitANEWARRAY(final ANEWARRAY o) {
    161        stack().pop(); // count
    162        stack().push(new ArrayType(o.getType(cpg), 1));
    163    }
    164
    165    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    166    @Override
    167    public void visitARETURN(final ARETURN o) {
    168        stack().pop();
    169    }
    170
    171    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    172    @Override
    173    public void visitARRAYLENGTH(final ARRAYLENGTH o) {
    174        stack().pop();
    175        stack().push(Type.INT);
    176    }
    177
    178    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    179    @Override
    180    public void visitASTORE(final ASTORE o) {
    181        locals().set(o.getIndex(), stack().pop());
    182        // System.err.println("TODO-DEBUG: set LV '"+o.getIndex()+"' to '"+locals().get(o.getIndex())+"'.");
    183    }
    184
    185    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    186    @Override
    187    public void visitATHROW(final ATHROW o) {
    188        final Type t = stack().pop();
    189        stack().clear();
    190        if (t.equals(Type.NULL)) {
    191            stack().push(Type.getType("Ljava/lang/NullPointerException;"));
    192        } else {
    193            stack().push(t);
    194        }
    195    }
    196
    197    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    198    @Override
    199    public void visitBALOAD(final BALOAD o) {
    200        stack().pop(2);
    201        stack().push(Type.INT);
    202    }
    203
    204    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    205    @Override
    206    public void visitBASTORE(final BASTORE o) {
    207        stack().pop(3);
    208    }
    209
    210    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    211    @Override
    212    public void visitBIPUSH(final BIPUSH o) {
    213        stack().push(Type.INT);
    214    }
    215
    216    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    217    @Override
    218    public void visitCALOAD(final CALOAD o) {
    219        stack().pop(2);
    220        stack().push(Type.INT);
    221    }
    222
    223    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    224    @Override
    225    public void visitCASTORE(final CASTORE o) {
    226        stack().pop(3);
    227    }
    228
    229    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    230    @Override
    231    public void visitCHECKCAST(final CHECKCAST o) {
    232        // It's possibly wrong to do so, but SUN's
    233        // ByteCode verifier seems to do (only) this, too.
    234        // TODO: One could use a sophisticated analysis here to check
    235        // if a type cannot possibly be cated to another and by
    236        // so doing predict the ClassCastException at run-time.
    237        stack().pop();
    238        stack().push(o.getType(cpg));
    239    }
    240
    241    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    242    @Override
    243    public void visitD2F(final D2F o) {
    244        stack().pop();
    245        stack().push(Type.FLOAT);
    246    }
    247
    248    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    249    @Override
    250    public void visitD2I(final D2I o) {
    251        stack().pop();
    252        stack().push(Type.INT);
    253    }
    254
    255    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    256    @Override
    257    public void visitD2L(final D2L o) {
    258        stack().pop();
    259        stack().push(Type.LONG);
    260    }
    261
    262    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    263    @Override
    264    public void visitDADD(final DADD o) {
    265        stack().pop(2);
    266        stack().push(Type.DOUBLE);
    267    }
    268
    269    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    270    @Override
    271    public void visitDALOAD(final DALOAD o) {
    272        stack().pop(2);
    273        stack().push(Type.DOUBLE);
    274    }
    275
    276    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    277    @Override
    278    public void visitDASTORE(final DASTORE o) {
    279        stack().pop(3);
    280    }
    281
    282    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    283    @Override
    284    public void visitDCMPG(final DCMPG o) {
    285        stack().pop(2);
    286        stack().push(Type.INT);
    287    }
    288
    289    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    290    @Override
    291    public void visitDCMPL(final DCMPL o) {
    292        stack().pop(2);
    293        stack().push(Type.INT);
    294    }
    295
    296    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    297    @Override
    298    public void visitDCONST(final DCONST o) {
    299        stack().push(Type.DOUBLE);
    300    }
    301
    302    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    303    @Override
    304    public void visitDDIV(final DDIV o) {
    305        stack().pop(2);
    306        stack().push(Type.DOUBLE);
    307    }
    308
    309    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    310    @Override
    311    public void visitDLOAD(final DLOAD o) {
    312        stack().push(Type.DOUBLE);
    313    }
    314
    315    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    316    @Override
    317    public void visitDMUL(final DMUL o) {
    318        stack().pop(2);
    319        stack().push(Type.DOUBLE);
    320    }
    321
    322    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    323    @Override
    324    public void visitDNEG(final DNEG o) {
    325        stack().pop();
    326        stack().push(Type.DOUBLE);
    327    }
    328
    329    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    330    @Override
    331    public void visitDREM(final DREM o) {
    332        stack().pop(2);
    333        stack().push(Type.DOUBLE);
    334    }
    335
    336    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    337    @Override
    338    public void visitDRETURN(final DRETURN o) {
    339        stack().pop();
    340    }
    341
    342    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    343    @Override
    344    public void visitDSTORE(final DSTORE o) {
    345        locals().set(o.getIndex(), stack().pop());
    346        locals().set(o.getIndex() + 1, Type.UNKNOWN);
    347    }
    348
    349    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    350    @Override
    351    public void visitDSUB(final DSUB o) {
    352        stack().pop(2);
    353        stack().push(Type.DOUBLE);
    354    }
    355
    356    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    357    @Override
    358    public void visitDUP(final DUP o) {
    359        final Type t = stack().pop();
    360        stack().push(t);
    361        stack().push(t);
    362    }
    363
    364    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    365    @Override
    366    public void visitDUP_X1(final DUP_X1 o) {
    367        final Type w1 = stack().pop();
    368        final Type w2 = stack().pop();
    369        stack().push(w1);
    370        stack().push(w2);
    371        stack().push(w1);
    372    }
    373
    374    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    375    @Override
    376    public void visitDUP_X2(final DUP_X2 o) {
    377        final Type w1 = stack().pop();
    378        final Type w2 = stack().pop();
    379        if (w2.getSize() == 2) {
    380            stack().push(w1);
    381        } else {
    382            final Type w3 = stack().pop();
    383            stack().push(w1);
    384            stack().push(w3);
    385        }
    386        stack().push(w2);
    387        stack().push(w1);
    388    }
    389
    390    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    391    @Override
    392    public void visitDUP2(final DUP2 o) {
    393        final Type t = stack().pop();
    394        if (t.getSize() == 2) {
    395            stack().push(t);
    396        } else { // t.getSize() is 1
    397            final Type u = stack().pop();
    398            stack().push(u);
    399            stack().push(t);
    400            stack().push(u);
    401        }
    402        stack().push(t);
    403    }
    404
    405    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    406    @Override
    407    public void visitDUP2_X1(final DUP2_X1 o) {
    408        final Type t = stack().pop();
    409        if (t.getSize() == 2) {
    410            final Type u = stack().pop();
    411            stack().push(t);
    412            stack().push(u);
    413        } else { // t.getSize() is1
    414            final Type u = stack().pop();
    415            final Type v = stack().pop();
    416            stack().push(u);
    417            stack().push(t);
    418            stack().push(v);
    419            stack().push(u);
    420        }
    421        stack().push(t);
    422    }
    423
    424    /** Symbolically executes the corresponding Java Virtual Machine instruction. */
    425    @Override
    426    public void visitDUP2_X2(final DUP2_X2 o) {
    427        final Type t = stack().pop();
    428        if (t.getSize() == 2) {
    429            final Type u = stack().pop();
    430            if (u.getSize() == 2) {
    431                stack().push(t);
    432            } else {
    433                final Type v = stack().pop();
    434                stack().push(t);
    435                stack().push(v);
    436            }
    437            stack().push(u);
    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        }
    453        stack().push(t);
    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}