ExecutionVisitor.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.bcel.verifier.structurals;

  18. import org.apache.bcel.Const;
  19. import org.apache.bcel.classfile.Constant;
  20. import org.apache.bcel.classfile.ConstantClass;
  21. import org.apache.bcel.classfile.ConstantDouble;
  22. import org.apache.bcel.classfile.ConstantDynamic;
  23. import org.apache.bcel.classfile.ConstantFloat;
  24. import org.apache.bcel.classfile.ConstantInteger;
  25. import org.apache.bcel.classfile.ConstantLong;
  26. import org.apache.bcel.classfile.ConstantString;
  27. // CHECKSTYLE:OFF (there are lots of references!)
  28. import org.apache.bcel.generic.*;
  29. //CHECKSTYLE:ON

  30. /**
  31.  * This Visitor class may be used for a type-based Java Virtual Machine simulation.
  32.  *
  33.  * <p>
  34.  * It does not check for correct types on the OperandStack or in the LocalVariables; nor does it check their sizes are
  35.  * sufficiently big. Thus, to use this Visitor for bytecode verifying, you have to make sure externally that the type
  36.  * constraints of the Java Virtual Machine instructions are satisfied. An InstConstraintVisitor may be used for this.
  37.  * Anyway, this Visitor does not mandate it. For example, when you visitIADD(IADD o), then there are two stack slots
  38.  * popped and one stack slot containing a Type.INT is pushed (where you could also pop only one slot if you know there
  39.  * are two Type.INT on top of the stack). Monitor-specific behavior is not simulated.
  40.  * </p>
  41.  *
  42.  * <b>Conventions:</b>
  43.  *
  44.  * <p>
  45.  * Type.VOID will never be pushed onto the stack. Type.DOUBLE and Type.LONG that would normally take up two stack slots
  46.  * (like Double_HIGH and Double_LOW) are represented by a simple single Type.DOUBLE or Type.LONG object on the stack
  47.  * here.
  48.  * </p>
  49.  *
  50.  * <p>
  51.  * If a two-slot type is stored into a local variable, the next variable is given the type Type.UNKNOWN.
  52.  * </p>
  53.  *
  54.  * @see #visitDSTORE(DSTORE o)
  55.  * @see InstConstraintVisitor
  56.  */
  57. public class ExecutionVisitor extends EmptyVisitor {

  58.     /**
  59.      * The executionframe we're operating on.
  60.      */
  61.     private Frame frame;

  62.     /**
  63.      * The ConstantPoolGen we're working with.
  64.      *
  65.      * @see #setConstantPoolGen(ConstantPoolGen)
  66.      */
  67.     private ConstantPoolGen cpg;

  68.     /**
  69.      * Constructs a new instance of this class.
  70.      */
  71.     public ExecutionVisitor() {
  72.     }

  73.     /**
  74.      * The LocalVariables from the current Frame we're operating on.
  75.      *
  76.      * @see #setFrame(Frame)
  77.      */
  78.     private LocalVariables locals() {
  79.         return frame.getLocals();
  80.     }

  81.     /**
  82.      * Sets the ConstantPoolGen needed for symbolic execution.
  83.      */
  84.     public void setConstantPoolGen(final ConstantPoolGen cpg) { // TODO could be package-protected?
  85.         this.cpg = cpg;
  86.     }

  87.     /**
  88.      * The only method granting access to the single instance of the ExecutionVisitor class. Before actively using this
  89.      * instance, <B>SET THE ConstantPoolGen FIRST</B>.
  90.      *
  91.      * @see #setConstantPoolGen(ConstantPoolGen)
  92.      */
  93.     public void setFrame(final Frame f) { // TODO could be package-protected?
  94.         this.frame = f;
  95.     }

  96.     /**
  97.      * The OperandStack from the current Frame we're operating on.
  98.      *
  99.      * @see #setFrame(Frame)
  100.      */
  101.     private OperandStack stack() {
  102.         return frame.getStack();
  103.     }

  104.     /// ** Symbolically executes the corresponding Java Virtual Machine instruction. */
  105.     // public void visitWIDE(WIDE o) {
  106.     // The WIDE instruction is modeled as a flag
  107.     // of the embedded instructions in BCEL.
  108.     // Therefore BCEL checks for possible errors
  109.     // when parsing in the .class file: We don't
  110.     // have even the possibility to care for WIDE
  111.     // here.
  112.     // }

  113.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  114.     @Override
  115.     public void visitAALOAD(final AALOAD o) {
  116.         stack().pop(); // pop the index int
  117. //System.out.print(stack().peek());
  118.         final Type t = stack().pop(); // Pop Array type
  119.         if (t == Type.NULL) {
  120.             stack().push(Type.NULL);
  121.         } // Do nothing stackwise --- a NullPointerException is thrown at Run-Time
  122.         else {
  123.             final ArrayType at = (ArrayType) t;
  124.             stack().push(at.getElementType());
  125.         }
  126.     }

  127.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  128.     @Override
  129.     public void visitAASTORE(final AASTORE o) {
  130.         stack().pop(3);
  131.     }

  132.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  133.     @Override
  134.     public void visitACONST_NULL(final ACONST_NULL o) {
  135.         stack().push(Type.NULL);
  136.     }

  137.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  138.     @Override
  139.     public void visitALOAD(final ALOAD o) {
  140.         stack().push(locals().get(o.getIndex()));
  141.     }

  142.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  143.     @Override
  144.     public void visitANEWARRAY(final ANEWARRAY o) {
  145.         stack().pop(); // count
  146.         stack().push(new ArrayType(o.getType(cpg), 1));
  147.     }

  148.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  149.     @Override
  150.     public void visitARETURN(final ARETURN o) {
  151.         stack().pop();
  152.     }

  153.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  154.     @Override
  155.     public void visitARRAYLENGTH(final ARRAYLENGTH o) {
  156.         stack().pop();
  157.         stack().push(Type.INT);
  158.     }

  159.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  160.     @Override
  161.     public void visitASTORE(final ASTORE o) {
  162.         locals().set(o.getIndex(), stack().pop());
  163.         // System.err.println("TODO-DEBUG: set LV '"+o.getIndex()+"' to '"+locals().get(o.getIndex())+"'.");
  164.     }

  165.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  166.     @Override
  167.     public void visitATHROW(final ATHROW o) {
  168.         final Type t = stack().pop();
  169.         stack().clear();
  170.         if (t.equals(Type.NULL)) {
  171.             stack().push(Type.getType("Ljava/lang/NullPointerException;"));
  172.         } else {
  173.             stack().push(t);
  174.         }
  175.     }

  176.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  177.     @Override
  178.     public void visitBALOAD(final BALOAD o) {
  179.         stack().pop(2);
  180.         stack().push(Type.INT);
  181.     }

  182.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  183.     @Override
  184.     public void visitBASTORE(final BASTORE o) {
  185.         stack().pop(3);
  186.     }

  187.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  188.     @Override
  189.     public void visitBIPUSH(final BIPUSH o) {
  190.         stack().push(Type.INT);
  191.     }

  192.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  193.     @Override
  194.     public void visitCALOAD(final CALOAD o) {
  195.         stack().pop(2);
  196.         stack().push(Type.INT);
  197.     }

  198.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  199.     @Override
  200.     public void visitCASTORE(final CASTORE o) {
  201.         stack().pop(3);
  202.     }

  203.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  204.     @Override
  205.     public void visitCHECKCAST(final CHECKCAST o) {
  206.         // It's possibly wrong to do so, but SUN's
  207.         // ByteCode verifier seems to do (only) this, too.
  208.         // TODO: One could use a sophisticated analysis here to check
  209.         // if a type cannot possibly be cated to another and by
  210.         // so doing predict the ClassCastException at run-time.
  211.         stack().pop();
  212.         stack().push(o.getType(cpg));
  213.     }

  214.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  215.     @Override
  216.     public void visitD2F(final D2F o) {
  217.         stack().pop();
  218.         stack().push(Type.FLOAT);
  219.     }

  220.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  221.     @Override
  222.     public void visitD2I(final D2I o) {
  223.         stack().pop();
  224.         stack().push(Type.INT);
  225.     }

  226.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  227.     @Override
  228.     public void visitD2L(final D2L o) {
  229.         stack().pop();
  230.         stack().push(Type.LONG);
  231.     }

  232.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  233.     @Override
  234.     public void visitDADD(final DADD o) {
  235.         stack().pop(2);
  236.         stack().push(Type.DOUBLE);
  237.     }

  238.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  239.     @Override
  240.     public void visitDALOAD(final DALOAD o) {
  241.         stack().pop(2);
  242.         stack().push(Type.DOUBLE);
  243.     }

  244.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  245.     @Override
  246.     public void visitDASTORE(final DASTORE o) {
  247.         stack().pop(3);
  248.     }

  249.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  250.     @Override
  251.     public void visitDCMPG(final DCMPG o) {
  252.         stack().pop(2);
  253.         stack().push(Type.INT);
  254.     }

  255.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  256.     @Override
  257.     public void visitDCMPL(final DCMPL o) {
  258.         stack().pop(2);
  259.         stack().push(Type.INT);
  260.     }

  261.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  262.     @Override
  263.     public void visitDCONST(final DCONST o) {
  264.         stack().push(Type.DOUBLE);
  265.     }

  266.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  267.     @Override
  268.     public void visitDDIV(final DDIV o) {
  269.         stack().pop(2);
  270.         stack().push(Type.DOUBLE);
  271.     }

  272.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  273.     @Override
  274.     public void visitDLOAD(final DLOAD o) {
  275.         stack().push(Type.DOUBLE);
  276.     }

  277.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  278.     @Override
  279.     public void visitDMUL(final DMUL o) {
  280.         stack().pop(2);
  281.         stack().push(Type.DOUBLE);
  282.     }

  283.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  284.     @Override
  285.     public void visitDNEG(final DNEG o) {
  286.         stack().pop();
  287.         stack().push(Type.DOUBLE);
  288.     }

  289.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  290.     @Override
  291.     public void visitDREM(final DREM o) {
  292.         stack().pop(2);
  293.         stack().push(Type.DOUBLE);
  294.     }

  295.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  296.     @Override
  297.     public void visitDRETURN(final DRETURN o) {
  298.         stack().pop();
  299.     }

  300.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  301.     @Override
  302.     public void visitDSTORE(final DSTORE o) {
  303.         locals().set(o.getIndex(), stack().pop());
  304.         locals().set(o.getIndex() + 1, Type.UNKNOWN);
  305.     }

  306.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  307.     @Override
  308.     public void visitDSUB(final DSUB o) {
  309.         stack().pop(2);
  310.         stack().push(Type.DOUBLE);
  311.     }

  312.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  313.     @Override
  314.     public void visitDUP(final DUP o) {
  315.         final Type t = stack().pop();
  316.         stack().push(t);
  317.         stack().push(t);
  318.     }

  319.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  320.     @Override
  321.     public void visitDUP_X1(final DUP_X1 o) {
  322.         final Type w1 = stack().pop();
  323.         final Type w2 = stack().pop();
  324.         stack().push(w1);
  325.         stack().push(w2);
  326.         stack().push(w1);
  327.     }

  328.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  329.     @Override
  330.     public void visitDUP_X2(final DUP_X2 o) {
  331.         final Type w1 = stack().pop();
  332.         final Type w2 = stack().pop();
  333.         if (w2.getSize() == 2) {
  334.             stack().push(w1);
  335.         } else {
  336.             final Type w3 = stack().pop();
  337.             stack().push(w1);
  338.             stack().push(w3);
  339.         }
  340.         stack().push(w2);
  341.         stack().push(w1);
  342.     }

  343.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  344.     @Override
  345.     public void visitDUP2(final DUP2 o) {
  346.         final Type t = stack().pop();
  347.         if (t.getSize() == 2) {
  348.             stack().push(t);
  349.         } else { // t.getSize() is 1
  350.             final Type u = stack().pop();
  351.             stack().push(u);
  352.             stack().push(t);
  353.             stack().push(u);
  354.         }
  355.         stack().push(t);
  356.     }

  357.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  358.     @Override
  359.     public void visitDUP2_X1(final DUP2_X1 o) {
  360.         final Type t = stack().pop();
  361.         if (t.getSize() == 2) {
  362.             final Type u = stack().pop();
  363.             stack().push(t);
  364.             stack().push(u);
  365.         } else { // t.getSize() is1
  366.             final Type u = stack().pop();
  367.             final Type v = stack().pop();
  368.             stack().push(u);
  369.             stack().push(t);
  370.             stack().push(v);
  371.             stack().push(u);
  372.         }
  373.         stack().push(t);
  374.     }

  375.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  376.     @Override
  377.     public void visitDUP2_X2(final DUP2_X2 o) {
  378.         final Type t = stack().pop();
  379.         if (t.getSize() == 2) {
  380.             final Type u = stack().pop();
  381.             if (u.getSize() == 2) {
  382.                 stack().push(t);
  383.             } else {
  384.                 final Type v = stack().pop();
  385.                 stack().push(t);
  386.                 stack().push(v);
  387.             }
  388.             stack().push(u);
  389.             stack().push(t);
  390.         } else { // t.getSize() is 1
  391.             final Type u = stack().pop();
  392.             final Type v = stack().pop();
  393.             if (v.getSize() == 2) {
  394.                 stack().push(u);
  395.                 stack().push(t);
  396.             } else {
  397.                 final Type w = stack().pop();
  398.                 stack().push(u);
  399.                 stack().push(t);
  400.                 stack().push(w);
  401.             }
  402.             stack().push(v);
  403.             stack().push(u);
  404.             stack().push(t);
  405.         }
  406.     }

  407.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  408.     @Override
  409.     public void visitF2D(final F2D o) {
  410.         stack().pop();
  411.         stack().push(Type.DOUBLE);
  412.     }

  413.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  414.     @Override
  415.     public void visitF2I(final F2I o) {
  416.         stack().pop();
  417.         stack().push(Type.INT);
  418.     }

  419.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  420.     @Override
  421.     public void visitF2L(final F2L o) {
  422.         stack().pop();
  423.         stack().push(Type.LONG);
  424.     }

  425.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  426.     @Override
  427.     public void visitFADD(final FADD o) {
  428.         stack().pop(2);
  429.         stack().push(Type.FLOAT);
  430.     }

  431.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  432.     @Override
  433.     public void visitFALOAD(final FALOAD o) {
  434.         stack().pop(2);
  435.         stack().push(Type.FLOAT);
  436.     }

  437.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  438.     @Override
  439.     public void visitFASTORE(final FASTORE o) {
  440.         stack().pop(3);
  441.     }

  442.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  443.     @Override
  444.     public void visitFCMPG(final FCMPG o) {
  445.         stack().pop(2);
  446.         stack().push(Type.INT);
  447.     }

  448.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  449.     @Override
  450.     public void visitFCMPL(final FCMPL o) {
  451.         stack().pop(2);
  452.         stack().push(Type.INT);
  453.     }

  454.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  455.     @Override
  456.     public void visitFCONST(final FCONST o) {
  457.         stack().push(Type.FLOAT);
  458.     }

  459.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  460.     @Override
  461.     public void visitFDIV(final FDIV o) {
  462.         stack().pop(2);
  463.         stack().push(Type.FLOAT);
  464.     }

  465.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  466.     @Override
  467.     public void visitFLOAD(final FLOAD o) {
  468.         stack().push(Type.FLOAT);
  469.     }

  470.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  471.     @Override
  472.     public void visitFMUL(final FMUL o) {
  473.         stack().pop(2);
  474.         stack().push(Type.FLOAT);
  475.     }

  476.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  477.     @Override
  478.     public void visitFNEG(final FNEG o) {
  479.         stack().pop();
  480.         stack().push(Type.FLOAT);
  481.     }

  482.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  483.     @Override
  484.     public void visitFREM(final FREM o) {
  485.         stack().pop(2);
  486.         stack().push(Type.FLOAT);
  487.     }

  488.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  489.     @Override
  490.     public void visitFRETURN(final FRETURN o) {
  491.         stack().pop();
  492.     }

  493.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  494.     @Override
  495.     public void visitFSTORE(final FSTORE o) {
  496.         locals().set(o.getIndex(), stack().pop());
  497.     }

  498.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  499.     @Override
  500.     public void visitFSUB(final FSUB o) {
  501.         stack().pop(2);
  502.         stack().push(Type.FLOAT);
  503.     }

  504.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  505.     @Override
  506.     public void visitGETFIELD(final GETFIELD o) {
  507.         stack().pop();
  508.         Type t = o.getFieldType(cpg);
  509.         if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
  510.             t = Type.INT;
  511.         }
  512.         stack().push(t);
  513.     }

  514.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  515.     @Override
  516.     public void visitGETSTATIC(final GETSTATIC o) {
  517.         Type t = o.getFieldType(cpg);
  518.         if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
  519.             t = Type.INT;
  520.         }
  521.         stack().push(t);
  522.     }

  523.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  524.     @Override
  525.     public void visitGOTO(final GOTO o) {
  526.         // no stack changes.
  527.     }

  528.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  529.     @Override
  530.     public void visitGOTO_W(final GOTO_W o) {
  531.         // no stack changes.
  532.     }

  533.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  534.     @Override
  535.     public void visitI2B(final I2B o) {
  536.         stack().pop();
  537.         stack().push(Type.INT);
  538.     }

  539.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  540.     @Override
  541.     public void visitI2C(final I2C o) {
  542.         stack().pop();
  543.         stack().push(Type.INT);
  544.     }

  545.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  546.     @Override
  547.     public void visitI2D(final I2D o) {
  548.         stack().pop();
  549.         stack().push(Type.DOUBLE);
  550.     }

  551.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  552.     @Override
  553.     public void visitI2F(final I2F o) {
  554.         stack().pop();
  555.         stack().push(Type.FLOAT);
  556.     }

  557.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  558.     @Override
  559.     public void visitI2L(final I2L o) {
  560.         stack().pop();
  561.         stack().push(Type.LONG);
  562.     }

  563.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  564.     @Override
  565.     public void visitI2S(final I2S o) {
  566.         stack().pop();
  567.         stack().push(Type.INT);
  568.     }

  569.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  570.     @Override
  571.     public void visitIADD(final IADD o) {
  572.         stack().pop(2);
  573.         stack().push(Type.INT);
  574.     }

  575.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  576.     @Override
  577.     public void visitIALOAD(final IALOAD o) {
  578.         stack().pop(2);
  579.         stack().push(Type.INT);
  580.     }

  581.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  582.     @Override
  583.     public void visitIAND(final IAND o) {
  584.         stack().pop(2);
  585.         stack().push(Type.INT);
  586.     }

  587.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  588.     @Override
  589.     public void visitIASTORE(final IASTORE o) {
  590.         stack().pop(3);
  591.     }

  592.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  593.     @Override
  594.     public void visitICONST(final ICONST o) {
  595.         stack().push(Type.INT);
  596.     }

  597.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  598.     @Override
  599.     public void visitIDIV(final IDIV o) {
  600.         stack().pop(2);
  601.         stack().push(Type.INT);
  602.     }

  603.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  604.     @Override
  605.     public void visitIF_ACMPEQ(final IF_ACMPEQ o) {
  606.         stack().pop(2);
  607.     }

  608.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  609.     @Override
  610.     public void visitIF_ACMPNE(final IF_ACMPNE o) {
  611.         stack().pop(2);
  612.     }

  613.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  614.     @Override
  615.     public void visitIF_ICMPEQ(final IF_ICMPEQ o) {
  616.         stack().pop(2);
  617.     }

  618.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  619.     @Override
  620.     public void visitIF_ICMPGE(final IF_ICMPGE o) {
  621.         stack().pop(2);
  622.     }

  623.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  624.     @Override
  625.     public void visitIF_ICMPGT(final IF_ICMPGT o) {
  626.         stack().pop(2);
  627.     }

  628.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  629.     @Override
  630.     public void visitIF_ICMPLE(final IF_ICMPLE o) {
  631.         stack().pop(2);
  632.     }

  633.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  634.     @Override
  635.     public void visitIF_ICMPLT(final IF_ICMPLT o) {
  636.         stack().pop(2);
  637.     }

  638.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  639.     @Override
  640.     public void visitIF_ICMPNE(final IF_ICMPNE o) {
  641.         stack().pop(2);
  642.     }

  643.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  644.     @Override
  645.     public void visitIFEQ(final IFEQ o) {
  646.         stack().pop();
  647.     }

  648.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  649.     @Override
  650.     public void visitIFGE(final IFGE o) {
  651.         stack().pop();
  652.     }

  653.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  654.     @Override
  655.     public void visitIFGT(final IFGT o) {
  656.         stack().pop();
  657.     }

  658.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  659.     @Override
  660.     public void visitIFLE(final IFLE o) {
  661.         stack().pop();
  662.     }

  663.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  664.     @Override
  665.     public void visitIFLT(final IFLT o) {
  666.         stack().pop();
  667.     }

  668.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  669.     @Override
  670.     public void visitIFNE(final IFNE o) {
  671.         stack().pop();
  672.     }

  673.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  674.     @Override
  675.     public void visitIFNONNULL(final IFNONNULL o) {
  676.         stack().pop();
  677.     }

  678.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  679.     @Override
  680.     public void visitIFNULL(final IFNULL o) {
  681.         stack().pop();
  682.     }

  683.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  684.     @Override
  685.     public void visitIINC(final IINC o) {
  686.         // stack is not changed.
  687.     }

  688.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  689.     @Override
  690.     public void visitILOAD(final ILOAD o) {
  691.         stack().push(Type.INT);
  692.     }

  693.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  694.     @Override
  695.     public void visitIMUL(final IMUL o) {
  696.         stack().pop(2);
  697.         stack().push(Type.INT);
  698.     }

  699.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  700.     @Override
  701.     public void visitINEG(final INEG o) {
  702.         stack().pop();
  703.         stack().push(Type.INT);
  704.     }

  705.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  706.     @Override
  707.     public void visitINSTANCEOF(final INSTANCEOF o) {
  708.         stack().pop();
  709.         stack().push(Type.INT);
  710.     }

  711.     private void visitInvokedInternals(final InvokeInstruction o) {
  712.         stack().pop(o.getArgumentTypes(cpg).length);
  713.         // We are sure the invoked method will xRETURN eventually
  714.         // We simulate xRETURNs functionality here because we
  715.         // don't really "jump into" and simulate the invoked
  716.         // method.
  717.         if (o.getReturnType(cpg) != Type.VOID) {
  718.             Type t = o.getReturnType(cpg);
  719.             if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
  720.                 t = Type.INT;
  721.             }
  722.             stack().push(t);
  723.         }
  724.     }

  725.     /**
  726.      * Symbolically executes the corresponding Java Virtual Machine instruction.
  727.      *
  728.      * @since 6.0
  729.      */
  730.     @Override
  731.     public void visitINVOKEDYNAMIC(final INVOKEDYNAMIC o) {
  732.         visitInvokedInternals(o);
  733.     }

  734.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  735.     @Override
  736.     public void visitINVOKEINTERFACE(final INVOKEINTERFACE o) {
  737.         stack().pop(); // objectref
  738.         stack().pop(o.getArgumentTypes(cpg).length);
  739.         // We are sure the invoked method will xRETURN eventually
  740.         // We simulate xRETURNs functionality here because we
  741.         // don't really "jump into" and simulate the invoked
  742.         // method.
  743.         if (o.getReturnType(cpg) != Type.VOID) {
  744.             Type t = o.getReturnType(cpg);
  745.             if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
  746.                 t = Type.INT;
  747.             }
  748.             stack().push(t);
  749.         }
  750.     }

  751.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  752.     @Override
  753.     public void visitINVOKESPECIAL(final INVOKESPECIAL o) {
  754.         if (o.getMethodName(cpg).equals(Const.CONSTRUCTOR_NAME)) {
  755.             final UninitializedObjectType t = (UninitializedObjectType) stack().peek(o.getArgumentTypes(cpg).length);
  756.             if (t == Frame.getThis()) {
  757.                 Frame.setThis(null);
  758.             }
  759.             stack().initializeObject(t);
  760.             locals().initializeObject(t);
  761.         }
  762.         stack().pop(); // objectref
  763.         stack().pop(o.getArgumentTypes(cpg).length);
  764.         // We are sure the invoked method will xRETURN eventually
  765.         // We simulate xRETURNs functionality here because we
  766.         // don't really "jump into" and simulate the invoked
  767.         // method.
  768.         if (o.getReturnType(cpg) != Type.VOID) {
  769.             Type t = o.getReturnType(cpg);
  770.             if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
  771.                 t = Type.INT;
  772.             }
  773.             stack().push(t);
  774.         }
  775.     }

  776.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  777.     @Override
  778.     public void visitINVOKESTATIC(final INVOKESTATIC o) {
  779.         visitInvokedInternals(o);
  780.     }

  781.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  782.     @Override
  783.     public void visitINVOKEVIRTUAL(final INVOKEVIRTUAL o) {
  784.         stack().pop(); // objectref
  785.         stack().pop(o.getArgumentTypes(cpg).length);
  786.         // We are sure the invoked method will xRETURN eventually
  787.         // We simulate xRETURNs functionality here because we
  788.         // don't really "jump into" and simulate the invoked
  789.         // method.
  790.         if (o.getReturnType(cpg) != Type.VOID) {
  791.             Type t = o.getReturnType(cpg);
  792.             if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) {
  793.                 t = Type.INT;
  794.             }
  795.             stack().push(t);
  796.         }
  797.     }

  798.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  799.     @Override
  800.     public void visitIOR(final IOR o) {
  801.         stack().pop(2);
  802.         stack().push(Type.INT);
  803.     }

  804.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  805.     @Override
  806.     public void visitIREM(final IREM o) {
  807.         stack().pop(2);
  808.         stack().push(Type.INT);
  809.     }

  810.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  811.     @Override
  812.     public void visitIRETURN(final IRETURN o) {
  813.         stack().pop();
  814.     }

  815.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  816.     @Override
  817.     public void visitISHL(final ISHL o) {
  818.         stack().pop(2);
  819.         stack().push(Type.INT);
  820.     }

  821.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  822.     @Override
  823.     public void visitISHR(final ISHR o) {
  824.         stack().pop(2);
  825.         stack().push(Type.INT);
  826.     }

  827.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  828.     @Override
  829.     public void visitISTORE(final ISTORE o) {
  830.         locals().set(o.getIndex(), stack().pop());
  831.     }

  832.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  833.     @Override
  834.     public void visitISUB(final ISUB o) {
  835.         stack().pop(2);
  836.         stack().push(Type.INT);
  837.     }

  838.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  839.     @Override
  840.     public void visitIUSHR(final IUSHR o) {
  841.         stack().pop(2);
  842.         stack().push(Type.INT);
  843.     }

  844.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  845.     @Override
  846.     public void visitIXOR(final IXOR o) {
  847.         stack().pop(2);
  848.         stack().push(Type.INT);
  849.     }

  850.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  851.     @Override
  852.     public void visitJSR(final JSR o) {
  853.         stack().push(new ReturnaddressType(o.physicalSuccessor()));
  854. //System.err.println("TODO-----------:"+o.physicalSuccessor());
  855.     }

  856.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  857.     @Override
  858.     public void visitJSR_W(final JSR_W o) {
  859.         stack().push(new ReturnaddressType(o.physicalSuccessor()));
  860.     }

  861.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  862.     @Override
  863.     public void visitL2D(final L2D o) {
  864.         stack().pop();
  865.         stack().push(Type.DOUBLE);
  866.     }

  867.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  868.     @Override
  869.     public void visitL2F(final L2F o) {
  870.         stack().pop();
  871.         stack().push(Type.FLOAT);
  872.     }

  873.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  874.     @Override
  875.     public void visitL2I(final L2I o) {
  876.         stack().pop();
  877.         stack().push(Type.INT);
  878.     }

  879.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  880.     @Override
  881.     public void visitLADD(final LADD o) {
  882.         stack().pop(2);
  883.         stack().push(Type.LONG);
  884.     }

  885.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  886.     @Override
  887.     public void visitLALOAD(final LALOAD o) {
  888.         stack().pop(2);
  889.         stack().push(Type.LONG);
  890.     }

  891.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  892.     @Override
  893.     public void visitLAND(final LAND o) {
  894.         stack().pop(2);
  895.         stack().push(Type.LONG);
  896.     }

  897.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  898.     @Override
  899.     public void visitLASTORE(final LASTORE o) {
  900.         stack().pop(3);
  901.     }

  902.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  903.     @Override
  904.     public void visitLCMP(final LCMP o) {
  905.         stack().pop(2);
  906.         stack().push(Type.INT);
  907.     }

  908.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  909.     @Override
  910.     public void visitLCONST(final LCONST o) {
  911.         stack().push(Type.LONG);
  912.     }

  913.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  914.     @Override
  915.     public void visitLDC(final LDC o) {
  916.         final Constant c = cpg.getConstant(o.getIndex());
  917.         if (c instanceof ConstantInteger) {
  918.             stack().push(Type.INT);
  919.         }
  920.         if (c instanceof ConstantFloat) {
  921.             stack().push(Type.FLOAT);
  922.         }
  923.         if (c instanceof ConstantString) {
  924.             stack().push(Type.STRING);
  925.         }
  926.         if (c instanceof ConstantClass) {
  927.             stack().push(Type.CLASS);
  928.         }
  929.         if (c instanceof ConstantDynamic) {
  930.             stack().push(Type.OBJECT);
  931.         }
  932.     }

  933.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  934.     public void visitLDC_W(final LDC_W o) {
  935.         final Constant c = cpg.getConstant(o.getIndex());
  936.         if (c instanceof ConstantInteger) {
  937.             stack().push(Type.INT);
  938.         }
  939.         if (c instanceof ConstantFloat) {
  940.             stack().push(Type.FLOAT);
  941.         }
  942.         if (c instanceof ConstantString) {
  943.             stack().push(Type.STRING);
  944.         }
  945.         if (c instanceof ConstantClass) {
  946.             stack().push(Type.CLASS);
  947.         }
  948.     }

  949.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  950.     @Override
  951.     public void visitLDC2_W(final LDC2_W o) {
  952.         final Constant c = cpg.getConstant(o.getIndex());
  953.         if (c instanceof ConstantLong) {
  954.             stack().push(Type.LONG);
  955.         }
  956.         if (c instanceof ConstantDouble) {
  957.             stack().push(Type.DOUBLE);
  958.         }
  959.     }

  960.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  961.     @Override
  962.     public void visitLDIV(final LDIV o) {
  963.         stack().pop(2);
  964.         stack().push(Type.LONG);
  965.     }

  966.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  967.     @Override
  968.     public void visitLLOAD(final LLOAD o) {
  969.         stack().push(locals().get(o.getIndex()));
  970.     }

  971.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  972.     @Override
  973.     public void visitLMUL(final LMUL o) {
  974.         stack().pop(2);
  975.         stack().push(Type.LONG);
  976.     }

  977.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  978.     @Override
  979.     public void visitLNEG(final LNEG o) {
  980.         stack().pop();
  981.         stack().push(Type.LONG);
  982.     }

  983.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  984.     @Override
  985.     public void visitLOOKUPSWITCH(final LOOKUPSWITCH o) {
  986.         stack().pop(); // key
  987.     }

  988.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  989.     @Override
  990.     public void visitLOR(final LOR o) {
  991.         stack().pop(2);
  992.         stack().push(Type.LONG);
  993.     }

  994.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  995.     @Override
  996.     public void visitLREM(final LREM o) {
  997.         stack().pop(2);
  998.         stack().push(Type.LONG);
  999.     }

  1000.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1001.     @Override
  1002.     public void visitLRETURN(final LRETURN o) {
  1003.         stack().pop();
  1004.     }

  1005.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1006.     @Override
  1007.     public void visitLSHL(final LSHL o) {
  1008.         stack().pop(2);
  1009.         stack().push(Type.LONG);
  1010.     }

  1011.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1012.     @Override
  1013.     public void visitLSHR(final LSHR o) {
  1014.         stack().pop(2);
  1015.         stack().push(Type.LONG);
  1016.     }

  1017.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1018.     @Override
  1019.     public void visitLSTORE(final LSTORE o) {
  1020.         locals().set(o.getIndex(), stack().pop());
  1021.         locals().set(o.getIndex() + 1, Type.UNKNOWN);
  1022.     }

  1023.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1024.     @Override
  1025.     public void visitLSUB(final LSUB o) {
  1026.         stack().pop(2);
  1027.         stack().push(Type.LONG);
  1028.     }

  1029.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1030.     @Override
  1031.     public void visitLUSHR(final LUSHR o) {
  1032.         stack().pop(2);
  1033.         stack().push(Type.LONG);
  1034.     }

  1035.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1036.     @Override
  1037.     public void visitLXOR(final LXOR o) {
  1038.         stack().pop(2);
  1039.         stack().push(Type.LONG);
  1040.     }

  1041.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1042.     @Override
  1043.     public void visitMONITORENTER(final MONITORENTER o) {
  1044.         stack().pop();
  1045.     }

  1046.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1047.     @Override
  1048.     public void visitMONITOREXIT(final MONITOREXIT o) {
  1049.         stack().pop();
  1050.     }

  1051.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1052.     @Override
  1053.     public void visitMULTIANEWARRAY(final MULTIANEWARRAY o) {
  1054.         stack().pop(o.getDimensions());
  1055.         stack().push(o.getType(cpg));
  1056.     }

  1057.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1058.     @Override
  1059.     public void visitNEW(final NEW o) {
  1060.         stack().push(new UninitializedObjectType((ObjectType) o.getType(cpg)));
  1061.     }

  1062.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1063.     @Override
  1064.     public void visitNEWARRAY(final NEWARRAY o) {
  1065.         stack().pop();
  1066.         stack().push(o.getType());
  1067.     }

  1068.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1069.     @Override
  1070.     public void visitNOP(final NOP o) {
  1071.     }

  1072.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1073.     @Override
  1074.     public void visitPOP(final POP o) {
  1075.         stack().pop();
  1076.     }

  1077.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1078.     @Override
  1079.     public void visitPOP2(final POP2 o) {
  1080.         final Type t = stack().pop();
  1081.         if (t.getSize() == 1) {
  1082.             stack().pop();
  1083.         }
  1084.     }

  1085.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1086.     @Override
  1087.     public void visitPUTFIELD(final PUTFIELD o) {
  1088.         stack().pop(2);
  1089.     }

  1090.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1091.     @Override
  1092.     public void visitPUTSTATIC(final PUTSTATIC o) {
  1093.         stack().pop();
  1094.     }

  1095.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1096.     @Override
  1097.     public void visitRET(final RET o) {
  1098.         // do nothing, return address
  1099.         // is in the local variables.
  1100.     }

  1101.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1102.     @Override
  1103.     public void visitRETURN(final RETURN o) {
  1104.         // do nothing.
  1105.     }

  1106.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1107.     @Override
  1108.     public void visitSALOAD(final SALOAD o) {
  1109.         stack().pop(2);
  1110.         stack().push(Type.INT);
  1111.     }

  1112.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1113.     @Override
  1114.     public void visitSASTORE(final SASTORE o) {
  1115.         stack().pop(3);
  1116.     }

  1117.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1118.     @Override
  1119.     public void visitSIPUSH(final SIPUSH o) {
  1120.         stack().push(Type.INT);
  1121.     }

  1122.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1123.     @Override
  1124.     public void visitSWAP(final SWAP o) {
  1125.         final Type t = stack().pop();
  1126.         final Type u = stack().pop();
  1127.         stack().push(t);
  1128.         stack().push(u);
  1129.     }

  1130.     /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1131.     @Override
  1132.     public void visitTABLESWITCH(final TABLESWITCH o) {
  1133.         stack().pop();
  1134.     }
  1135. }