ExecutionVisitor.java
- /*
- * 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.bcel.verifier.structurals;
- import org.apache.bcel.Const;
- import org.apache.bcel.classfile.Constant;
- import org.apache.bcel.classfile.ConstantClass;
- import org.apache.bcel.classfile.ConstantDouble;
- import org.apache.bcel.classfile.ConstantDynamic;
- import org.apache.bcel.classfile.ConstantFloat;
- import org.apache.bcel.classfile.ConstantInteger;
- import org.apache.bcel.classfile.ConstantLong;
- import org.apache.bcel.classfile.ConstantString;
- // CHECKSTYLE:OFF (there are lots of references!)
- import org.apache.bcel.generic.*;
- //CHECKSTYLE:ON
- /**
- * 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 behavior 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>
- *
- * @see #visitDSTORE(DSTORE o)
- * @see InstConstraintVisitor
- */
- public class ExecutionVisitor extends EmptyVisitor {
- /**
- * The executionframe we're operating on.
- */
- private Frame frame;
- /**
- * The ConstantPoolGen we're working with.
- *
- * @see #setConstantPoolGen(ConstantPoolGen)
- */
- private ConstantPoolGen cpg;
- /**
- * Constructs a new instance of this class.
- */
- public ExecutionVisitor() {
- }
- /**
- * 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(final ConstantPoolGen cpg) { // TODO could be package-protected?
- 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(final Frame f) { // TODO could be package-protected?
- this.frame = f;
- }
- /**
- * The OperandStack from the current Frame we're operating on.
- *
- * @see #setFrame(Frame)
- */
- private OperandStack stack() {
- return frame.getStack();
- }
- /// ** Symbolically executes the corresponding Java Virtual Machine instruction. */
- // public void visitWIDE(WIDE o) {
- // The WIDE instruction is modeled 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 possibility to care for WIDE
- // here.
- // }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitAALOAD(final AALOAD o) {
- stack().pop(); // pop the index int
- //System.out.print(stack().peek());
- final 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 {
- final ArrayType at = (ArrayType) t;
- stack().push(at.getElementType());
- }
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitAASTORE(final AASTORE o) {
- stack().pop(3);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitACONST_NULL(final ACONST_NULL o) {
- stack().push(Type.NULL);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitALOAD(final ALOAD o) {
- stack().push(locals().get(o.getIndex()));
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitANEWARRAY(final 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(final ARETURN o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitARRAYLENGTH(final ARRAYLENGTH o) {
- stack().pop();
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitASTORE(final 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(final ATHROW o) {
- final 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(final BALOAD o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitBASTORE(final BASTORE o) {
- stack().pop(3);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitBIPUSH(final BIPUSH o) {
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitCALOAD(final CALOAD o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitCASTORE(final CASTORE o) {
- stack().pop(3);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitCHECKCAST(final 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(final D2F o) {
- stack().pop();
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitD2I(final D2I o) {
- stack().pop();
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitD2L(final D2L o) {
- stack().pop();
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDADD(final DADD o) {
- stack().pop(2);
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDALOAD(final DALOAD o) {
- stack().pop(2);
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDASTORE(final DASTORE o) {
- stack().pop(3);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDCMPG(final DCMPG o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDCMPL(final DCMPL o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDCONST(final DCONST o) {
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDDIV(final DDIV o) {
- stack().pop(2);
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDLOAD(final DLOAD o) {
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDMUL(final DMUL o) {
- stack().pop(2);
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDNEG(final DNEG o) {
- stack().pop();
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDREM(final DREM o) {
- stack().pop(2);
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDRETURN(final DRETURN o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDSTORE(final 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(final DSUB o) {
- stack().pop(2);
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDUP(final DUP o) {
- final Type t = stack().pop();
- stack().push(t);
- stack().push(t);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitDUP_X1(final DUP_X1 o) {
- final Type w1 = stack().pop();
- final 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(final DUP_X2 o) {
- final Type w1 = stack().pop();
- final Type w2 = stack().pop();
- if (w2.getSize() == 2) {
- stack().push(w1);
- } else {
- final 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(final DUP2 o) {
- final Type t = stack().pop();
- if (t.getSize() == 2) {
- stack().push(t);
- } else { // t.getSize() is 1
- final 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(final DUP2_X1 o) {
- final Type t = stack().pop();
- if (t.getSize() == 2) {
- final Type u = stack().pop();
- stack().push(t);
- stack().push(u);
- } else { // t.getSize() is1
- final Type u = stack().pop();
- final 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(final DUP2_X2 o) {
- final Type t = stack().pop();
- if (t.getSize() == 2) {
- final Type u = stack().pop();
- if (u.getSize() == 2) {
- stack().push(t);
- } else {
- final Type v = stack().pop();
- stack().push(t);
- stack().push(v);
- }
- stack().push(u);
- stack().push(t);
- } else { // t.getSize() is 1
- final Type u = stack().pop();
- final Type v = stack().pop();
- if (v.getSize() == 2) {
- stack().push(u);
- stack().push(t);
- } else {
- final 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(final F2D o) {
- stack().pop();
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitF2I(final F2I o) {
- stack().pop();
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitF2L(final F2L o) {
- stack().pop();
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFADD(final FADD o) {
- stack().pop(2);
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFALOAD(final FALOAD o) {
- stack().pop(2);
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFASTORE(final FASTORE o) {
- stack().pop(3);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFCMPG(final FCMPG o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFCMPL(final FCMPL o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFCONST(final FCONST o) {
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFDIV(final FDIV o) {
- stack().pop(2);
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFLOAD(final FLOAD o) {
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFMUL(final FMUL o) {
- stack().pop(2);
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFNEG(final FNEG o) {
- stack().pop();
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFREM(final FREM o) {
- stack().pop(2);
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFRETURN(final FRETURN o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFSTORE(final FSTORE o) {
- locals().set(o.getIndex(), stack().pop());
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitFSUB(final FSUB o) {
- stack().pop(2);
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitGETFIELD(final 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(final 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(final GOTO o) {
- // no stack changes.
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitGOTO_W(final GOTO_W o) {
- // no stack changes.
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitI2B(final I2B o) {
- stack().pop();
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitI2C(final I2C o) {
- stack().pop();
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitI2D(final I2D o) {
- stack().pop();
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitI2F(final I2F o) {
- stack().pop();
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitI2L(final I2L o) {
- stack().pop();
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitI2S(final I2S o) {
- stack().pop();
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIADD(final IADD o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIALOAD(final IALOAD o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIAND(final IAND o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIASTORE(final IASTORE o) {
- stack().pop(3);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitICONST(final ICONST o) {
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIDIV(final IDIV o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIF_ACMPEQ(final IF_ACMPEQ o) {
- stack().pop(2);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIF_ACMPNE(final IF_ACMPNE o) {
- stack().pop(2);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIF_ICMPEQ(final IF_ICMPEQ o) {
- stack().pop(2);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIF_ICMPGE(final IF_ICMPGE o) {
- stack().pop(2);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIF_ICMPGT(final IF_ICMPGT o) {
- stack().pop(2);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIF_ICMPLE(final IF_ICMPLE o) {
- stack().pop(2);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIF_ICMPLT(final IF_ICMPLT o) {
- stack().pop(2);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIF_ICMPNE(final IF_ICMPNE o) {
- stack().pop(2);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIFEQ(final IFEQ o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIFGE(final IFGE o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIFGT(final IFGT o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIFLE(final IFLE o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIFLT(final IFLT o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIFNE(final IFNE o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIFNONNULL(final IFNONNULL o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIFNULL(final IFNULL o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIINC(final IINC o) {
- // stack is not changed.
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitILOAD(final ILOAD o) {
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIMUL(final IMUL o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitINEG(final INEG o) {
- stack().pop();
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitINSTANCEOF(final INSTANCEOF o) {
- stack().pop();
- stack().push(Type.INT);
- }
- private void visitInvokedInternals(final InvokeInstruction o) {
- stack().pop(o.getArgumentTypes(cpg).length);
- // 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.
- *
- * @since 6.0
- */
- @Override
- public void visitINVOKEDYNAMIC(final INVOKEDYNAMIC o) {
- visitInvokedInternals(o);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitINVOKEINTERFACE(final INVOKEINTERFACE o) {
- stack().pop(); // objectref
- stack().pop(o.getArgumentTypes(cpg).length);
- // 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(final INVOKESPECIAL o) {
- if (o.getMethodName(cpg).equals(Const.CONSTRUCTOR_NAME)) {
- final UninitializedObjectType t = (UninitializedObjectType) stack().peek(o.getArgumentTypes(cpg).length);
- if (t == Frame.getThis()) {
- Frame.setThis(null);
- }
- stack().initializeObject(t);
- locals().initializeObject(t);
- }
- stack().pop(); // objectref
- stack().pop(o.getArgumentTypes(cpg).length);
- // 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(final INVOKESTATIC o) {
- visitInvokedInternals(o);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitINVOKEVIRTUAL(final INVOKEVIRTUAL o) {
- stack().pop(); // objectref
- stack().pop(o.getArgumentTypes(cpg).length);
- // 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(final IOR o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIREM(final IREM o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIRETURN(final IRETURN o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitISHL(final ISHL o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitISHR(final ISHR o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitISTORE(final ISTORE o) {
- locals().set(o.getIndex(), stack().pop());
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitISUB(final ISUB o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIUSHR(final IUSHR o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitIXOR(final IXOR o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitJSR(final 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(final JSR_W o) {
- stack().push(new ReturnaddressType(o.physicalSuccessor()));
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitL2D(final L2D o) {
- stack().pop();
- stack().push(Type.DOUBLE);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitL2F(final L2F o) {
- stack().pop();
- stack().push(Type.FLOAT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitL2I(final L2I o) {
- stack().pop();
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLADD(final LADD o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLALOAD(final LALOAD o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLAND(final LAND o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLASTORE(final LASTORE o) {
- stack().pop(3);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLCMP(final LCMP o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLCONST(final LCONST o) {
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLDC(final LDC o) {
- final 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);
- }
- if (c instanceof ConstantDynamic) {
- stack().push(Type.OBJECT);
- }
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- public void visitLDC_W(final LDC_W o) {
- final 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(final LDC2_W o) {
- final 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(final LDIV o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLLOAD(final LLOAD o) {
- stack().push(locals().get(o.getIndex()));
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLMUL(final LMUL o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLNEG(final LNEG o) {
- stack().pop();
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLOOKUPSWITCH(final LOOKUPSWITCH o) {
- stack().pop(); // key
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLOR(final LOR o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLREM(final LREM o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLRETURN(final LRETURN o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLSHL(final LSHL o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLSHR(final LSHR o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLSTORE(final 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(final LSUB o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLUSHR(final LUSHR o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitLXOR(final LXOR o) {
- stack().pop(2);
- stack().push(Type.LONG);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitMONITORENTER(final MONITORENTER o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitMONITOREXIT(final MONITOREXIT o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitMULTIANEWARRAY(final MULTIANEWARRAY o) {
- stack().pop(o.getDimensions());
- stack().push(o.getType(cpg));
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitNEW(final NEW o) {
- stack().push(new UninitializedObjectType((ObjectType) o.getType(cpg)));
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitNEWARRAY(final NEWARRAY o) {
- stack().pop();
- stack().push(o.getType());
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitNOP(final NOP o) {
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitPOP(final POP o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitPOP2(final POP2 o) {
- final Type t = stack().pop();
- if (t.getSize() == 1) {
- stack().pop();
- }
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitPUTFIELD(final PUTFIELD o) {
- stack().pop(2);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitPUTSTATIC(final PUTSTATIC o) {
- stack().pop();
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitRET(final RET o) {
- // do nothing, return address
- // is in the local variables.
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitRETURN(final RETURN o) {
- // do nothing.
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitSALOAD(final SALOAD o) {
- stack().pop(2);
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitSASTORE(final SASTORE o) {
- stack().pop(3);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitSIPUSH(final SIPUSH o) {
- stack().push(Type.INT);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitSWAP(final SWAP o) {
- final Type t = stack().pop();
- final Type u = stack().pop();
- stack().push(t);
- stack().push(u);
- }
- /** Symbolically executes the corresponding Java Virtual Machine instruction. */
- @Override
- public void visitTABLESWITCH(final TABLESWITCH o) {
- stack().pop();
- }
- }