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