main.java.soot.jimple.toolkits.scalar.Evaluator Maven / Gradle / Ivy
/* Soot - a J*va Optimization Framework
* Copyright (C) 1999 Phong Co
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the Sable Research Group and others 1997-1999.
* See the 'credits' file distributed with Soot for the complete list of
* contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
*/
package soot.jimple.toolkits.scalar;
import soot.*;
import soot.jimple.*;
public class Evaluator {
public static boolean isValueConstantValued(Value op) {
if (op instanceof Constant)
return true;
else if ((op instanceof UnopExpr)) {
Value innerOp = ((UnopExpr)op).getOp();
if(innerOp==NullConstant.v())
//operations on null will throw an exception and the operation
//is therefore not considered constant-valued; see posting on Soot list
//on 18 September 2007 14:36
return false;
if (isValueConstantValued(innerOp))
return true;
}
else if (op instanceof BinopExpr)
{
/* Handle weird cases. */
if (op instanceof DivExpr || op instanceof RemExpr)
{
if (!isValueConstantValued(((BinopExpr)op).getOp1()) ||
!isValueConstantValued(((BinopExpr)op).getOp2()))
return false;
Value c1 = getConstantValueOf(((BinopExpr)op).getOp1());
Value c2 = getConstantValueOf(((BinopExpr)op).getOp2());
/* check for a 0 value. If so, punt. */
if (c2 instanceof IntConstant && ((IntConstant)c2).value == 0)
return false;
if (c2 instanceof LongConstant &&
((LongConstant)c2).value == 0)
return false;
}
if (isValueConstantValued(((BinopExpr)op).getOp1()) &&
isValueConstantValued(((BinopExpr)op).getOp2()))
return true;
}
return false;
} // isValueConstantValued
/** Returns the constant value of op
if it is easy
* to find the constant value; else returns null
. */
public static Value getConstantValueOf(Value op) {
if (!isValueConstantValued(op))
return null;
if (op instanceof Constant)
return op;
else if (op instanceof UnopExpr) {
Value c = getConstantValueOf(((UnopExpr)op).getOp());
if (op instanceof NegExpr)
return ((NumericConstant)c).negate();
}
else if (op instanceof BinopExpr) {
Value c1 = getConstantValueOf(((BinopExpr)op).getOp1());
Value c2 = getConstantValueOf(((BinopExpr)op).getOp2());
if (op instanceof AddExpr)
return ((NumericConstant)c1).add((NumericConstant)c2);
else if (op instanceof SubExpr)
return ((NumericConstant)c1).subtract((NumericConstant)c2);
else if (op instanceof MulExpr)
return ((NumericConstant)c1).multiply((NumericConstant)c2);
// punting handled by isValueConstantValued().
else if (op instanceof DivExpr)
return ((NumericConstant)c1).divide((NumericConstant)c2);
else if (op instanceof RemExpr)
return ((NumericConstant)c1).remainder((NumericConstant)c2);
else if (op instanceof EqExpr || op instanceof NeExpr)
{
if (c1 instanceof NumericConstant)
{
if (op instanceof EqExpr)
return ((NumericConstant)c1).equalEqual
((NumericConstant)c2);
else if (op instanceof NeExpr)
return ((NumericConstant)c1).notEqual
((NumericConstant)c2);
}
else if (c1 instanceof StringConstant)
{
boolean equality = ((StringConstant)c1).equals
(c2);
boolean truth = (op instanceof EqExpr) ? equality :
!equality;
// Yeah, this variable name sucks, but I couldn't resist.
IntConstant beauty = IntConstant.v(truth ? 1 : 0);
return beauty;
}
else if (c1 instanceof NullConstant)
return IntConstant.v
(((NullConstant)c1).equals(c2) ? 1 : 0);
throw new RuntimeException
("constant neither numeric nor string");
}
else if (op instanceof GtExpr)
return ((NumericConstant)c1).greaterThan((NumericConstant)c2);
else if (op instanceof GeExpr)
return ((NumericConstant)c1).greaterThanOrEqual((NumericConstant)c2);
else if (op instanceof LtExpr)
return ((NumericConstant)c1).lessThan((NumericConstant)c2);
else if (op instanceof LeExpr)
return ((NumericConstant)c1).lessThanOrEqual((NumericConstant)c2);
else if (op instanceof AndExpr)
return ((ArithmeticConstant)c1).and((ArithmeticConstant)c2);
else if (op instanceof OrExpr)
return ((ArithmeticConstant)c1).or((ArithmeticConstant)c2);
else if (op instanceof XorExpr)
return ((ArithmeticConstant)c1).xor((ArithmeticConstant)c2);
else if (op instanceof ShlExpr)
return ((ArithmeticConstant)c1).shiftLeft((ArithmeticConstant)c2);
else if (op instanceof ShrExpr)
return ((ArithmeticConstant)c1).shiftRight((ArithmeticConstant)c2);
else if (op instanceof UshrExpr)
return ((ArithmeticConstant)c1).unsignedShiftRight((ArithmeticConstant)c2);
else if (op instanceof CmpExpr) {
if ((c1 instanceof LongConstant) &&
(c2 instanceof LongConstant))
return ((LongConstant)c1).cmp((LongConstant)c2);
else throw new IllegalArgumentException(
"CmpExpr: LongConstant(s) expected");
}
else if ((op instanceof CmpgExpr) || (op instanceof CmplExpr)) {
if ((c1 instanceof RealConstant) &&
(c2 instanceof RealConstant)) {
if(op instanceof CmpgExpr)
return ((RealConstant) c1).cmpg((RealConstant) c2);
else if(op instanceof CmplExpr)
return ((RealConstant) c1).cmpl((RealConstant) c2);
}
else throw new IllegalArgumentException(
"CmpExpr: RealConstant(s) expected");
}
else
throw new RuntimeException("unknown binop: " + op);
}
throw new RuntimeException("couldn't getConstantValueOf of: " + op);
} // getConstantValueOf
} // Evaluator
© 2015 - 2025 Weber Informatics LLC | Privacy Policy