| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| package org.apache.commons.bcel6.verifier.structurals; |
| |
| |
| import org.apache.commons.bcel6.Constants; |
| import org.apache.commons.bcel6.classfile.Constant; |
| import org.apache.commons.bcel6.classfile.ConstantClass; |
| import org.apache.commons.bcel6.classfile.ConstantDouble; |
| import org.apache.commons.bcel6.classfile.ConstantFloat; |
| import org.apache.commons.bcel6.classfile.ConstantInteger; |
| import org.apache.commons.bcel6.classfile.ConstantLong; |
| import org.apache.commons.bcel6.classfile.ConstantString; |
| import org.apache.commons.bcel6.generic.*; |
| |
| /** |
| * This Visitor class may be used for a type-based Java Virtual Machine |
| * simulation. |
| * |
| * <p>It does not check for correct types on the OperandStack or in the |
| * LocalVariables; nor does it check their sizes are sufficiently big. |
| * Thus, to use this Visitor for bytecode verifying, you have to make sure |
| * externally that the type constraints of the Java Virtual Machine instructions |
| * are satisfied. An InstConstraintVisitor may be used for this. |
| * Anyway, this Visitor does not mandate it. For example, when you |
| * visitIADD(IADD o), then there are two stack slots popped and one |
| * stack slot containing a Type.INT is pushed (where you could also |
| * pop only one slot if you know there are two Type.INT on top of the |
| * stack). Monitor-specific behaviour is not simulated.</p> |
| * |
| * <b>Conventions:</b> |
| * |
| * <p>Type.VOID will never be pushed onto the stack. Type.DOUBLE and Type.LONG |
| * that would normally take up two stack slots (like Double_HIGH and |
| * Double_LOW) are represented by a simple single Type.DOUBLE or Type.LONG |
| * object on the stack here.</p> |
| * |
| * <p>If a two-slot type is stored into a local variable, the next variable |
| * is given the type Type.UNKNOWN.</p> |
| * |
| * @version $Id$ |
| * @author Enver Haase |
| * @see #visitDSTORE(DSTORE o) |
| * @see InstConstraintVisitor |
| */ |
| public class ExecutionVisitor extends EmptyVisitor{ |
| |
| /** |
| * The executionframe we're operating on. |
| */ |
| private Frame frame = null; |
| |
| /** |
| * The ConstantPoolGen we're working with. |
| * @see #setConstantPoolGen(ConstantPoolGen) |
| */ |
| private ConstantPoolGen cpg = null; |
| |
| /** |
| * Constructor. Constructs a new instance of this class. |
| */ |
| public ExecutionVisitor(){} |
| |
| /** |
| * The OperandStack from the current Frame we're operating on. |
| * @see #setFrame(Frame) |
| */ |
| private OperandStack stack(){ |
| return frame.getStack(); |
| } |
| |
| /** |
| * The LocalVariables from the current Frame we're operating on. |
| * @see #setFrame(Frame) |
| */ |
| private LocalVariables locals(){ |
| return frame.getLocals(); |
| } |
| |
| /** |
| * Sets the ConstantPoolGen needed for symbolic execution. |
| */ |
| public void setConstantPoolGen(ConstantPoolGen cpg){ |
| this.cpg = cpg; |
| } |
| |
| /** |
| * The only method granting access to the single instance of |
| * the ExecutionVisitor class. Before actively using this |
| * instance, <B>SET THE ConstantPoolGen FIRST</B>. |
| * @see #setConstantPoolGen(ConstantPoolGen) |
| */ |
| public void setFrame(Frame f){ |
| this.frame = f; |
| } |
| |
| ///** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| //public void visitWIDE(WIDE o){ |
| // The WIDE instruction is modelled as a flag |
| // of the embedded instructions in BCEL. |
| // Therefore BCEL checks for possible errors |
| // when parsing in the .class file: We don't |
| // have even the possibilty to care for WIDE |
| // here. |
| //} |
| |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitAALOAD(AALOAD o){ |
| stack().pop(); // pop the index int |
| //System.out.print(stack().peek()); |
| Type t = stack().pop(); // Pop Array type |
| if (t == Type.NULL){ |
| stack().push(Type.NULL); |
| } // Do nothing stackwise --- a NullPointerException is thrown at Run-Time |
| else{ |
| ArrayType at = (ArrayType) t; |
| stack().push(at.getElementType()); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitAASTORE(AASTORE o){ |
| stack().pop(); |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitACONST_NULL(ACONST_NULL o){ |
| stack().push(Type.NULL); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitALOAD(ALOAD o){ |
| stack().push(locals().get(o.getIndex())); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitANEWARRAY(ANEWARRAY o){ |
| stack().pop(); //count |
| stack().push( new ArrayType(o.getType(cpg), 1) ); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitARETURN(ARETURN o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitARRAYLENGTH(ARRAYLENGTH o){ |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitASTORE(ASTORE o){ |
| locals().set(o.getIndex(), stack().pop()); |
| //System.err.println("TODO-DEBUG: set LV '"+o.getIndex()+"' to '"+locals().get(o.getIndex())+"'."); |
| } |
| |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitATHROW(ATHROW o){ |
| Type t = stack().pop(); |
| stack().clear(); |
| if (t.equals(Type.NULL)) { |
| stack().push(Type.getType("Ljava/lang/NullPointerException;")); |
| } else { |
| stack().push(t); |
| } |
| } |
| |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitBALOAD(BALOAD o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitBASTORE(BASTORE o){ |
| stack().pop(); |
| stack().pop(); |
| stack().pop(); |
| } |
| |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitBIPUSH(BIPUSH o){ |
| stack().push(Type.INT); |
| } |
| |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitCALOAD(CALOAD o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitCASTORE(CASTORE o){ |
| stack().pop(); |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitCHECKCAST(CHECKCAST o){ |
| // It's possibly wrong to do so, but SUN's |
| // ByteCode verifier seems to do (only) this, too. |
| // TODO: One could use a sophisticated analysis here to check |
| // if a type cannot possibly be cated to another and by |
| // so doing predict the ClassCastException at run-time. |
| stack().pop(); |
| stack().push(o.getType(cpg)); |
| } |
| |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitD2F(D2F o){ |
| stack().pop(); |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitD2I(D2I o){ |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitD2L(D2L o){ |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDADD(DADD o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDALOAD(DALOAD o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDASTORE(DASTORE o){ |
| stack().pop(); |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDCMPG(DCMPG o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDCMPL(DCMPL o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDCONST(DCONST o){ |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDDIV(DDIV o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDLOAD(DLOAD o){ |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDMUL(DMUL o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDNEG(DNEG o){ |
| stack().pop(); |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDREM(DREM o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDRETURN(DRETURN o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDSTORE(DSTORE o){ |
| locals().set(o.getIndex(), stack().pop()); |
| locals().set(o.getIndex()+1, Type.UNKNOWN); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDSUB(DSUB o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDUP(DUP o){ |
| Type t = stack().pop(); |
| stack().push(t); |
| stack().push(t); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDUP_X1(DUP_X1 o){ |
| Type w1 = stack().pop(); |
| Type w2 = stack().pop(); |
| stack().push(w1); |
| stack().push(w2); |
| stack().push(w1); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDUP_X2(DUP_X2 o){ |
| Type w1 = stack().pop(); |
| Type w2 = stack().pop(); |
| if (w2.getSize() == 2){ |
| stack().push(w1); |
| stack().push(w2); |
| stack().push(w1); |
| } |
| else{ |
| Type w3 = stack().pop(); |
| stack().push(w1); |
| stack().push(w3); |
| stack().push(w2); |
| stack().push(w1); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDUP2(DUP2 o){ |
| Type t = stack().pop(); |
| if (t.getSize() == 2){ |
| stack().push(t); |
| stack().push(t); |
| } |
| else{ // t.getSize() is 1 |
| Type u = stack().pop(); |
| stack().push(u); |
| stack().push(t); |
| stack().push(u); |
| stack().push(t); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDUP2_X1(DUP2_X1 o){ |
| Type t = stack().pop(); |
| if (t.getSize() == 2){ |
| Type u = stack().pop(); |
| stack().push(t); |
| stack().push(u); |
| stack().push(t); |
| } |
| else{ //t.getSize() is1 |
| Type u = stack().pop(); |
| Type v = stack().pop(); |
| stack().push(u); |
| stack().push(t); |
| stack().push(v); |
| stack().push(u); |
| stack().push(t); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitDUP2_X2(DUP2_X2 o){ |
| Type t = stack().pop(); |
| if (t.getSize() == 2){ |
| Type u = stack().pop(); |
| if (u.getSize() == 2){ |
| stack().push(t); |
| stack().push(u); |
| stack().push(t); |
| }else{ |
| Type v = stack().pop(); |
| stack().push(t); |
| stack().push(v); |
| stack().push(u); |
| stack().push(t); |
| } |
| } |
| else{ //t.getSize() is 1 |
| Type u = stack().pop(); |
| Type v = stack().pop(); |
| if (v.getSize() == 2){ |
| stack().push(u); |
| stack().push(t); |
| stack().push(v); |
| stack().push(u); |
| stack().push(t); |
| }else{ |
| Type w = stack().pop(); |
| stack().push(u); |
| stack().push(t); |
| stack().push(w); |
| stack().push(v); |
| stack().push(u); |
| stack().push(t); |
| } |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitF2D(F2D o){ |
| stack().pop(); |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitF2I(F2I o){ |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitF2L(F2L o){ |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFADD(FADD o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFALOAD(FALOAD o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFASTORE(FASTORE o){ |
| stack().pop(); |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFCMPG(FCMPG o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFCMPL(FCMPL o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFCONST(FCONST o){ |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFDIV(FDIV o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFLOAD(FLOAD o){ |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFMUL(FMUL o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFNEG(FNEG o){ |
| stack().pop(); |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFREM(FREM o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFRETURN(FRETURN o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFSTORE(FSTORE o){ |
| locals().set(o.getIndex(), stack().pop()); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitFSUB(FSUB o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitGETFIELD(GETFIELD o){ |
| stack().pop(); |
| Type t = o.getFieldType(cpg); |
| if ( t.equals(Type.BOOLEAN) || |
| t.equals(Type.CHAR) || |
| t.equals(Type.BYTE) || |
| t.equals(Type.SHORT) ) { |
| t = Type.INT; |
| } |
| stack().push(t); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitGETSTATIC(GETSTATIC o){ |
| Type t = o.getFieldType(cpg); |
| if ( t.equals(Type.BOOLEAN) || |
| t.equals(Type.CHAR) || |
| t.equals(Type.BYTE) || |
| t.equals(Type.SHORT) ) { |
| t = Type.INT; |
| } |
| stack().push(t); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitGOTO(GOTO o){ |
| // no stack changes. |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitGOTO_W(GOTO_W o){ |
| // no stack changes. |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitI2B(I2B o){ |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitI2C(I2C o){ |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitI2D(I2D o){ |
| stack().pop(); |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitI2F(I2F o){ |
| stack().pop(); |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitI2L(I2L o){ |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitI2S(I2S o){ |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIADD(IADD o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIALOAD(IALOAD o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIAND(IAND o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIASTORE(IASTORE o){ |
| stack().pop(); |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitICONST(ICONST o){ |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIDIV(IDIV o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIF_ACMPEQ(IF_ACMPEQ o){ |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIF_ACMPNE(IF_ACMPNE o){ |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIF_ICMPEQ(IF_ICMPEQ o){ |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIF_ICMPGE(IF_ICMPGE o){ |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIF_ICMPGT(IF_ICMPGT o){ |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIF_ICMPLE(IF_ICMPLE o){ |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIF_ICMPLT(IF_ICMPLT o){ |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIF_ICMPNE(IF_ICMPNE o){ |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIFEQ(IFEQ o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIFGE(IFGE o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIFGT(IFGT o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIFLE(IFLE o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIFLT(IFLT o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIFNE(IFNE o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIFNONNULL(IFNONNULL o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIFNULL(IFNULL o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIINC(IINC o){ |
| // stack is not changed. |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitILOAD(ILOAD o){ |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIMUL(IMUL o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitINEG(INEG o){ |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitINSTANCEOF(INSTANCEOF o){ |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitINVOKEDYNAMIC(INVOKEDYNAMIC o){ |
| for (int i=0; i<o.getArgumentTypes(cpg).length; i++){ |
| stack().pop(); |
| } |
| // We are sure the invoked method will xRETURN eventually |
| // We simulate xRETURNs functionality here because we |
| // don't really "jump into" and simulate the invoked |
| // method. |
| if (o.getReturnType(cpg) != Type.VOID){ |
| Type t = o.getReturnType(cpg); |
| if ( t.equals(Type.BOOLEAN) || |
| t.equals(Type.CHAR) || |
| t.equals(Type.BYTE) || |
| t.equals(Type.SHORT) ) { |
| t = Type.INT; |
| } |
| stack().push(t); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitINVOKEINTERFACE(INVOKEINTERFACE o){ |
| stack().pop(); //objectref |
| for (int i=0; i<o.getArgumentTypes(cpg).length; i++){ |
| stack().pop(); |
| } |
| // We are sure the invoked method will xRETURN eventually |
| // We simulate xRETURNs functionality here because we |
| // don't really "jump into" and simulate the invoked |
| // method. |
| if (o.getReturnType(cpg) != Type.VOID){ |
| Type t = o.getReturnType(cpg); |
| if ( t.equals(Type.BOOLEAN) || |
| t.equals(Type.CHAR) || |
| t.equals(Type.BYTE) || |
| t.equals(Type.SHORT) ) { |
| t = Type.INT; |
| } |
| stack().push(t); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitINVOKESPECIAL(INVOKESPECIAL o){ |
| if (o.getMethodName(cpg).equals(Constants.CONSTRUCTOR_NAME)){ |
| UninitializedObjectType t = (UninitializedObjectType) stack().peek(o.getArgumentTypes(cpg).length); |
| if (t == Frame._this){ |
| Frame._this = null; |
| } |
| stack().initializeObject(t); |
| locals().initializeObject(t); |
| } |
| stack().pop(); //objectref |
| for (int i=0; i<o.getArgumentTypes(cpg).length; i++){ |
| stack().pop(); |
| } |
| // We are sure the invoked method will xRETURN eventually |
| // We simulate xRETURNs functionality here because we |
| // don't really "jump into" and simulate the invoked |
| // method. |
| if (o.getReturnType(cpg) != Type.VOID){ |
| Type t = o.getReturnType(cpg); |
| if ( t.equals(Type.BOOLEAN) || |
| t.equals(Type.CHAR) || |
| t.equals(Type.BYTE) || |
| t.equals(Type.SHORT) ) { |
| t = Type.INT; |
| } |
| stack().push(t); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitINVOKESTATIC(INVOKESTATIC o){ |
| for (int i=0; i<o.getArgumentTypes(cpg).length; i++){ |
| stack().pop(); |
| } |
| // We are sure the invoked method will xRETURN eventually |
| // We simulate xRETURNs functionality here because we |
| // don't really "jump into" and simulate the invoked |
| // method. |
| if (o.getReturnType(cpg) != Type.VOID){ |
| Type t = o.getReturnType(cpg); |
| if ( t.equals(Type.BOOLEAN) || |
| t.equals(Type.CHAR) || |
| t.equals(Type.BYTE) || |
| t.equals(Type.SHORT) ) { |
| t = Type.INT; |
| } |
| stack().push(t); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitINVOKEVIRTUAL(INVOKEVIRTUAL o){ |
| stack().pop(); //objectref |
| for (int i=0; i<o.getArgumentTypes(cpg).length; i++){ |
| stack().pop(); |
| } |
| // We are sure the invoked method will xRETURN eventually |
| // We simulate xRETURNs functionality here because we |
| // don't really "jump into" and simulate the invoked |
| // method. |
| if (o.getReturnType(cpg) != Type.VOID){ |
| Type t = o.getReturnType(cpg); |
| if ( t.equals(Type.BOOLEAN) || |
| t.equals(Type.CHAR) || |
| t.equals(Type.BYTE) || |
| t.equals(Type.SHORT) ) { |
| t = Type.INT; |
| } |
| stack().push(t); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIOR(IOR o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIREM(IREM o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIRETURN(IRETURN o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitISHL(ISHL o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitISHR(ISHR o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitISTORE(ISTORE o){ |
| locals().set(o.getIndex(), stack().pop()); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitISUB(ISUB o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIUSHR(IUSHR o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitIXOR(IXOR o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitJSR(JSR o){ |
| stack().push(new ReturnaddressType(o.physicalSuccessor())); |
| //System.err.println("TODO-----------:"+o.physicalSuccessor()); |
| } |
| |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitJSR_W(JSR_W o){ |
| stack().push(new ReturnaddressType(o.physicalSuccessor())); |
| } |
| |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitL2D(L2D o){ |
| stack().pop(); |
| stack().push(Type.DOUBLE); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitL2F(L2F o){ |
| stack().pop(); |
| stack().push(Type.FLOAT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitL2I(L2I o){ |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLADD(LADD o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLALOAD(LALOAD o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLAND(LAND o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLASTORE(LASTORE o){ |
| stack().pop(); |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLCMP(LCMP o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLCONST(LCONST o){ |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLDC(LDC o){ |
| Constant c = cpg.getConstant(o.getIndex()); |
| if (c instanceof ConstantInteger){ |
| stack().push(Type.INT); |
| } |
| if (c instanceof ConstantFloat){ |
| stack().push(Type.FLOAT); |
| } |
| if (c instanceof ConstantString){ |
| stack().push(Type.STRING); |
| } |
| if (c instanceof ConstantClass){ |
| stack().push(Type.CLASS); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| public void visitLDC_W(LDC_W o){ |
| Constant c = cpg.getConstant(o.getIndex()); |
| if (c instanceof ConstantInteger){ |
| stack().push(Type.INT); |
| } |
| if (c instanceof ConstantFloat){ |
| stack().push(Type.FLOAT); |
| } |
| if (c instanceof ConstantString){ |
| stack().push(Type.STRING); |
| } |
| if (c instanceof ConstantClass){ |
| stack().push(Type.CLASS); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLDC2_W(LDC2_W o){ |
| Constant c = cpg.getConstant(o.getIndex()); |
| if (c instanceof ConstantLong){ |
| stack().push(Type.LONG); |
| } |
| if (c instanceof ConstantDouble){ |
| stack().push(Type.DOUBLE); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLDIV(LDIV o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLLOAD(LLOAD o){ |
| stack().push(locals().get(o.getIndex())); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLMUL(LMUL o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLNEG(LNEG o){ |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLOOKUPSWITCH(LOOKUPSWITCH o){ |
| stack().pop(); //key |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLOR(LOR o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLREM(LREM o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLRETURN(LRETURN o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLSHL(LSHL o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLSHR(LSHR o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLSTORE(LSTORE o){ |
| locals().set(o.getIndex(), stack().pop()); |
| locals().set(o.getIndex()+1, Type.UNKNOWN); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLSUB(LSUB o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLUSHR(LUSHR o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitLXOR(LXOR o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.LONG); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitMONITORENTER(MONITORENTER o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitMONITOREXIT(MONITOREXIT o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitMULTIANEWARRAY(MULTIANEWARRAY o){ |
| for (int i=0; i<o.getDimensions(); i++){ |
| stack().pop(); |
| } |
| stack().push(o.getType(cpg)); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitNEW(NEW o){ |
| stack().push(new UninitializedObjectType((ObjectType) (o.getType(cpg)))); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitNEWARRAY(NEWARRAY o){ |
| stack().pop(); |
| stack().push(o.getType()); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitNOP(NOP o){ |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitPOP(POP o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitPOP2(POP2 o){ |
| Type t = stack().pop(); |
| if (t.getSize() == 1){ |
| stack().pop(); |
| } |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitPUTFIELD(PUTFIELD o){ |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitPUTSTATIC(PUTSTATIC o){ |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitRET(RET o){ |
| // do nothing, return address |
| // is in in the local variables. |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitRETURN(RETURN o){ |
| // do nothing. |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitSALOAD(SALOAD o){ |
| stack().pop(); |
| stack().pop(); |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitSASTORE(SASTORE o){ |
| stack().pop(); |
| stack().pop(); |
| stack().pop(); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitSIPUSH(SIPUSH o){ |
| stack().push(Type.INT); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitSWAP(SWAP o){ |
| Type t = stack().pop(); |
| Type u = stack().pop(); |
| stack().push(t); |
| stack().push(u); |
| } |
| /** Symbolically executes the corresponding Java Virtual Machine instruction. */ |
| @Override |
| public void visitTABLESWITCH(TABLESWITCH o){ |
| stack().pop(); |
| } |
| } |