/* Soot - a J*va Optimization Framework
* Copyright (C) 1999 Patrick Lam
* Copyright (C) 2004 Ondrej Lhotak
*
* 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.grimp;
import soot.*;
import soot.jimple.*;
import soot.grimp.internal.*;
import java.util.*;
/**
The Grimp class contains all the constructors for the components of the Grimp
grammar for the Grimp body. <br><br>
Immediate -> Local | Constant <br>
RValue -> Local | Constant | ConcreteRef | Expr<br>
Variable -> Local | ArrayRef | InstanceFieldRef | StaticFieldRef <br>
*/
public class Grimp
{
public Grimp( Singletons.Global g ) {}
public static Grimp v() { return G.v().soot_grimp_Grimp(); }
/**
Constructs a XorExpr(Expr, Expr) grammar chunk.
*/
public XorExpr newXorExpr(Value op1, Value op2)
{
return new GXorExpr(op1, op2);
}
/**
Constructs a UshrExpr(Expr, Expr) grammar chunk.
*/
public UshrExpr newUshrExpr(Value op1, Value op2)
{
return new GUshrExpr(op1, op2);
}
/**
Constructs a SubExpr(Expr, Expr) grammar chunk.
*/
public SubExpr newSubExpr(Value op1, Value op2)
{
return new GSubExpr(op1, op2);
}
/**
Constructs a ShrExpr(Expr, Expr) grammar chunk.
*/
public ShrExpr newShrExpr(Value op1, Value op2)
{
return new GShrExpr(op1, op2);
}
/**
Constructs a ShlExpr(Expr, Expr) grammar chunk.
*/
public ShlExpr newShlExpr(Value op1, Value op2)
{
return new GShlExpr(op1, op2);
}
/**
Constructs a RemExpr(Expr, Expr) grammar chunk.
*/
public RemExpr newRemExpr(Value op1, Value op2)
{
return new GRemExpr(op1, op2);
}
/**
Constructs a OrExpr(Expr, Expr) grammar chunk.
*/
public OrExpr newOrExpr(Value op1, Value op2)
{
return new GOrExpr(op1, op2);
}
/**
Constructs a NeExpr(Expr, Expr) grammar chunk.
*/
public NeExpr newNeExpr(Value op1, Value op2)
{
return new GNeExpr(op1, op2);
}
/**
Constructs a MulExpr(Expr, Expr) grammar chunk.
*/
public MulExpr newMulExpr(Value op1, Value op2)
{
return new GMulExpr(op1, op2);
}
/**
Constructs a LeExpr(Expr, Expr) grammar chunk.
*/
public LeExpr newLeExpr(Value op1, Value op2)
{
return new GLeExpr(op1, op2);
}
/**
Constructs a GeExpr(Expr, Expr) grammar chunk.
*/
public GeExpr newGeExpr(Value op1, Value op2)
{
return new GGeExpr(op1, op2);
}
/**
Constructs a EqExpr(Expr, Expr) grammar chunk.
*/
public EqExpr newEqExpr(Value op1, Value op2)
{
return new GEqExpr(op1, op2);
}
/**
Constructs a DivExpr(Expr, Expr) grammar chunk.
*/
public DivExpr newDivExpr(Value op1, Value op2)
{
return new GDivExpr(op1, op2);
}
/**
Constructs a CmplExpr(Expr, Expr) grammar chunk.
*/
public CmplExpr newCmplExpr(Value op1, Value op2)
{
return new GCmplExpr(op1, op2);
}
/**
Constructs a CmpgExpr(Expr, Expr) grammar chunk.
*/
public CmpgExpr newCmpgExpr(Value op1, Value op2)
{
return new GCmpgExpr(op1, op2);
}
/**
Constructs a CmpExpr(Expr, Expr) grammar chunk.
*/
public CmpExpr newCmpExpr(Value op1, Value op2)
{
return new GCmpExpr(op1, op2);
}
/**
Constructs a GtExpr(Expr, Expr) grammar chunk.
*/
public GtExpr newGtExpr(Value op1, Value op2)
{
return new GGtExpr(op1, op2);
}
/**
Constructs a LtExpr(Expr, Expr) grammar chunk.
*/
public LtExpr newLtExpr(Value op1, Value op2)
{
return new GLtExpr(op1, op2);
}
/**
Constructs a AddExpr(Expr, Expr) grammar chunk.
*/
public AddExpr newAddExpr(Value op1, Value op2)
{
return new GAddExpr(op1, op2);
}
/**
Constructs a AndExpr(Expr, Expr) grammar chunk.
*/
public AndExpr newAndExpr(Value op1, Value op2)
{
return new GAndExpr(op1, op2);
}
/**
Constructs a NegExpr(Expr, Expr) grammar chunk.
*/
public NegExpr newNegExpr(Value op)
{
return new GNegExpr(op);
}
/**
Constructs a LengthExpr(Expr) grammar chunk.
*/
public LengthExpr newLengthExpr(Value op)
{
return new GLengthExpr(op);
}
/**
Constructs a CastExpr(Expr, Type) grammar chunk.
*/
public CastExpr newCastExpr(Value op1, Type t)
{
return new GCastExpr(op1, t);
}
/**
Constructs a InstanceOfExpr(Expr, Type)
grammar chunk.
*/
public InstanceOfExpr newInstanceOfExpr(Value op1, Type t)
{
return new GInstanceOfExpr(op1, t);
}
/**
Constructs a NewExpr(RefType) grammar chunk.
*/
NewExpr newNewExpr(RefType type)
{
return Jimple.v().newNewExpr(type);
}
/**
Constructs a NewArrayExpr(Type, Expr) grammar chunk.
*/
public NewArrayExpr newNewArrayExpr(Type type, Value size)
{
return new GNewArrayExpr(type, size);
}
/**
Constructs a NewMultiArrayExpr(ArrayType, List of Expr) grammar chunk.
*/
public NewMultiArrayExpr newNewMultiArrayExpr(ArrayType type, List sizes)
{
return new GNewMultiArrayExpr(type, sizes);
}
/**
Constructs a NewInvokeExpr(Local base, List of Expr) grammar chunk.
*/
public NewInvokeExpr newNewInvokeExpr(RefType base, SootMethodRef method, List args)
{
return new GNewInvokeExpr(base, method, args);
}
/**
Constructs a StaticInvokeExpr(ArrayType, List of Expr) grammar chunk.
*/
public StaticInvokeExpr newStaticInvokeExpr(SootMethodRef method, List args)
{
return new GStaticInvokeExpr(method, args);
}
/**
Constructs a SpecialInvokeExpr(Local base, SootMethodRef method, List of Expr) grammar chunk.
*/
public SpecialInvokeExpr newSpecialInvokeExpr(Local base, SootMethodRef method, List args)
{
return new GSpecialInvokeExpr(base, method, args);
}
/**
Constructs a VirtualInvokeExpr(Local base, SootMethodRef method, List of Expr) grammar chunk.
*/
public VirtualInvokeExpr newVirtualInvokeExpr(Local base, SootMethodRef method, List args)
{
return new GVirtualInvokeExpr(base, method, args);
}
/**
* Constructs a new DynamicInvokeExpr grammar chunk.
*/
public DynamicInvokeExpr newDynamicInvokeExpr(SootMethodRef bootstrapMethodRef, List<Value> bootstrapArgs, SootMethodRef methodRef, List args){
return new GDynamicInvokeExpr(bootstrapMethodRef, bootstrapArgs, methodRef, args);
}
/**
Constructs a InterfaceInvokeExpr(Local base, SootMethodRef method, List of Expr) grammar chunk.
*/
public InterfaceInvokeExpr newInterfaceInvokeExpr(Local base, SootMethodRef method, List args)
{
return new GInterfaceInvokeExpr(base, method, args);
}
/**
Constructs a ThrowStmt(Expr) grammar chunk.
*/
public ThrowStmt newThrowStmt(Value op)
{
return new GThrowStmt(op);
}
public ThrowStmt newThrowStmt(ThrowStmt s)
{
return new GThrowStmt(s.getOp());
}
/**
Constructs a ExitMonitorStmt(Expr) grammar chunk
*/
public ExitMonitorStmt newExitMonitorStmt(Value op)
{
return new GExitMonitorStmt(op);
}
public ExitMonitorStmt newExitMonitorStmt(ExitMonitorStmt s)
{
return new GExitMonitorStmt(s.getOp());
}
/**
Constructs a EnterMonitorStmt(Expr) grammar chunk.
*/
public EnterMonitorStmt newEnterMonitorStmt(Value op)
{
return new GEnterMonitorStmt(op);
}
public EnterMonitorStmt newEnterMonitorStmt(EnterMonitorStmt s)
{
return new GEnterMonitorStmt(s.getOp());
}
/**
Constructs a BreakpointStmt() grammar chunk.
*/
public BreakpointStmt newBreakpointStmt()
{
return Jimple.v().newBreakpointStmt();
}
public BreakpointStmt newBreakpointStmt(BreakpointStmt s)
{
return Jimple.v().newBreakpointStmt();
}
/**
Constructs a GotoStmt(Stmt) grammar chunk.
*/
public GotoStmt newGotoStmt(Unit target)
{
return Jimple.v().newGotoStmt(target);
}
public GotoStmt newGotoStmt(GotoStmt s)
{
return Jimple.v().newGotoStmt(s.getTarget());
}
/**
Constructs a NopStmt() grammar chunk.
*/
public NopStmt newNopStmt()
{
return Jimple.v().newNopStmt();
}
public NopStmt newNopStmt(NopStmt s)
{
return Jimple.v().newNopStmt();
}
/**
Constructs a ReturnVoidStmt() grammar chunk.
*/
public ReturnVoidStmt newReturnVoidStmt()
{
return Jimple.v().newReturnVoidStmt();
}
public ReturnVoidStmt newReturnVoidStmt(ReturnVoidStmt s)
{
return Jimple.v().newReturnVoidStmt();
}
/**
Constructs a ReturnStmt(Expr) grammar chunk.
*/
public ReturnStmt newReturnStmt(Value op)
{
return new GReturnStmt(op);
}
public ReturnStmt newReturnStmt(ReturnStmt s)
{
return new GReturnStmt(s.getOp());
}
/**
Constructs a IfStmt(Condition, Stmt) grammar chunk.
*/
public IfStmt newIfStmt(Value condition, Unit target)
{
return new GIfStmt(condition, target);
}
public IfStmt newIfStmt(IfStmt s)
{
return new GIfStmt(s.getCondition(), s.getTarget());
}
/**
Constructs a IdentityStmt(Local, IdentityRef) grammar chunk.
*/
public IdentityStmt newIdentityStmt(Value local, Value identityRef)
{
return new GIdentityStmt(local, identityRef);
}
public IdentityStmt newIdentityStmt(IdentityStmt s)
{
return new GIdentityStmt(s.getLeftOp(), s.getRightOp());
}
/**
Constructs a AssignStmt(Variable, RValue) grammar chunk.
*/
public AssignStmt newAssignStmt(Value variable, Value rvalue)
{
return new GAssignStmt(variable, rvalue);
}
public AssignStmt newAssignStmt(AssignStmt s)
{
return new GAssignStmt(s.getLeftOp(), s.getRightOp());
}
/**
Constructs a InvokeStmt(InvokeExpr) grammar chunk.
*/
public InvokeStmt newInvokeStmt(Value op)
{
return new GInvokeStmt(op);
}
public InvokeStmt newInvokeStmt(InvokeStmt s)
{
return new GInvokeStmt(s.getInvokeExpr());
}
/**
Constructs a TableSwitchStmt(Expr, int, int, List of Unit, Stmt) grammar chunk.
*/
public TableSwitchStmt newTableSwitchStmt(Value key, int lowIndex, int highIndex, List targets, Unit defaultTarget)
{
return new GTableSwitchStmt(key, lowIndex, highIndex, targets, defaultTarget);
}
public TableSwitchStmt newTableSwitchStmt(TableSwitchStmt s)
{
return new GTableSwitchStmt(s.getKey(), s.getLowIndex(),
s.getHighIndex(), s.getTargets(),
s.getDefaultTarget());
}
/**
Constructs a LookupSwitchStmt(Expr, List of Expr, List of Unit, Stmt) grammar chunk.
*/
public LookupSwitchStmt newLookupSwitchStmt(Value key, List lookupValues, List targets, Unit defaultTarget)
{
return new GLookupSwitchStmt(key, lookupValues, targets, defaultTarget);
}
public LookupSwitchStmt newLookupSwitchStmt(LookupSwitchStmt s)
{
return new GLookupSwitchStmt(s.getKey(), s.getLookupValues(),
s.getTargets(), s.getDefaultTarget());
}
/**
Constructs a Local with the given name and type.
*/
public Local newLocal(String name, Type t)
{
return Jimple.v().newLocal(name, t);
}
/**
Constructs a new Trap for the given exception on the given Stmt range with the given Stmt handler.
*/
public Trap newTrap(SootClass exception, Unit beginStmt, Unit endStmt, Unit handlerStmt)
{
return new GTrap(exception, beginStmt, endStmt, handlerStmt);
}
public Trap newTrap(Trap trap)
{
return new GTrap(trap.getException(), trap.getBeginUnit(),
trap.getEndUnit(), trap.getHandlerUnit());
}
/**
Constructs a StaticFieldRef(SootFieldRef) grammar chunk.
*/
public StaticFieldRef newStaticFieldRef(SootFieldRef f)
{
return Jimple.v().newStaticFieldRef(f);
}
/**
Constructs a ThisRef(RefType) grammar chunk.
*/
public ThisRef newThisRef(RefType t)
{
return Jimple.v().newThisRef(t);
}
/**
Constructs a ParameterRef(SootMethod, int) grammar chunk.
*/
public ParameterRef newParameterRef(Type paramType, int number)
{
return Jimple.v().newParameterRef(paramType, number);
}
/**
Constructs a InstanceFieldRef(Value, SootFieldRef) grammar chunk.
*/
public InstanceFieldRef newInstanceFieldRef(Value base, SootFieldRef f)
{
return new GInstanceFieldRef(base, f);
}
/**
Constructs a CaughtExceptionRef() grammar chunk.
*/
public CaughtExceptionRef newCaughtExceptionRef()
{
return Jimple.v().newCaughtExceptionRef();
}
/**
Constructs a ArrayRef(Local, Expr) grammar chunk.
*/
public ArrayRef newArrayRef(Value base, Value index)
{
return new GArrayRef(base, index);
}
public ValueBox newVariableBox(Value value)
{
return Jimple.v().newVariableBox(value);
}
public ValueBox newLocalBox(Value value)
{
return Jimple.v().newLocalBox(value);
}
public ValueBox newRValueBox(Value value)
{
return new GRValueBox(value);
}
public ValueBox newImmediateBox(Value value)
{
return Jimple.v().newImmediateBox(value);
}
public ValueBox newExprBox(Value value)
{
return new ExprBox(value);
}
public ValueBox newArgBox(Value value)
{
return new ExprBox(value);
}
public ValueBox newObjExprBox(Value value)
{
return new ObjExprBox(value);
}
public ValueBox newIdentityRefBox(Value value)
{
return Jimple.v().newIdentityRefBox(value);
}
public ValueBox newConditionExprBox(Value value)
{
return Jimple.v().newConditionExprBox(value);
}
public ValueBox newInvokeExprBox(Value value)
{
return Jimple.v().newInvokeExprBox(value);
}
public UnitBox newStmtBox(Unit unit)
{
return Jimple.v().newStmtBox(unit);
}
/** Carries out the mapping from other Value's to Grimp Value's */
public Value newExpr(Value value)
{
if (value instanceof Expr)
{
final ExprBox returnedExpr = new ExprBox(IntConstant.v(0));
((Expr)value).apply(new AbstractExprSwitch()
{
public void caseAddExpr(AddExpr v)
{
returnedExpr.setValue
(newAddExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseAndExpr(AndExpr v)
{
returnedExpr.setValue
(newAndExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseCmpExpr(CmpExpr v)
{
returnedExpr.setValue
(newCmpExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseCmpgExpr(CmpgExpr v)
{
returnedExpr.setValue
(newCmpgExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseCmplExpr(CmplExpr v)
{
returnedExpr.setValue
(newCmplExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseDivExpr(DivExpr v)
{
returnedExpr.setValue
(newDivExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseEqExpr(EqExpr v)
{
returnedExpr.setValue
(newEqExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseNeExpr(NeExpr v)
{
returnedExpr.setValue
(newNeExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseGeExpr(GeExpr v)
{
returnedExpr.setValue
(newGeExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseGtExpr(GtExpr v)
{
returnedExpr.setValue
(newGtExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseLeExpr(LeExpr v)
{
returnedExpr.setValue
(newLeExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseLtExpr(LtExpr v)
{
returnedExpr.setValue
(newLtExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseMulExpr(MulExpr v)
{
returnedExpr.setValue
(newMulExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseOrExpr(OrExpr v)
{
returnedExpr.setValue
(newOrExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseRemExpr(RemExpr v)
{
returnedExpr.setValue
(newRemExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseShlExpr(ShlExpr v)
{
returnedExpr.setValue
(newShlExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseShrExpr(ShrExpr v)
{
returnedExpr.setValue
(newShrExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseUshrExpr(UshrExpr v)
{
returnedExpr.setValue
(newUshrExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseSubExpr(SubExpr v)
{
returnedExpr.setValue
(newSubExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseXorExpr(XorExpr v)
{
returnedExpr.setValue
(newXorExpr(newExpr(v.getOp1()),
newExpr(v.getOp2())));
}
public void caseInterfaceInvokeExpr(InterfaceInvokeExpr v)
{
ArrayList newArgList = new ArrayList();
for (int i = 0; i < v.getArgCount(); i++)
newArgList.add(newExpr(v.getArg(i)));
returnedExpr.setValue
(newInterfaceInvokeExpr((Local)(v.getBase()),
v.getMethodRef(),
newArgList));
}
public void caseSpecialInvokeExpr(SpecialInvokeExpr v)
{
ArrayList newArgList = new ArrayList();
for (int i = 0; i < v.getArgCount(); i++)
newArgList.add(newExpr(v.getArg(i)));
returnedExpr.setValue
(newSpecialInvokeExpr((Local)(v.getBase()),
v.getMethodRef(),
newArgList));
}
public void caseStaticInvokeExpr(StaticInvokeExpr v)
{
ArrayList newArgList = new ArrayList();
for (int i = 0; i < v.getArgCount(); i++)
newArgList.add(newExpr(v.getArg(i)));
returnedExpr.setValue
(newStaticInvokeExpr(v.getMethodRef(),
newArgList));
}
public void caseVirtualInvokeExpr(VirtualInvokeExpr v)
{
ArrayList newArgList = new ArrayList();
for (int i = 0; i < v.getArgCount(); i++)
newArgList.add(newExpr(v.getArg(i)));
returnedExpr.setValue
(newVirtualInvokeExpr((Local)(v.getBase()),
v.getMethodRef(),
newArgList));
}
public void caseDynamicInvokeExpr(DynamicInvokeExpr v){
ArrayList newArgList = new ArrayList();
for (int i = 0; i < v.getArgCount(); i++)
newArgList.add(newExpr(v.getArg(i)));
returnedExpr.setValue
(newDynamicInvokeExpr(v.getBootstrapMethodRef(),v.getBootstrapArgs(),v.getMethodRef(),
newArgList));
}
public void caseCastExpr(CastExpr v)
{
returnedExpr.setValue(newCastExpr(newExpr(v.getOp()),
v.getType()));
}
public void caseInstanceOfExpr(InstanceOfExpr v)
{
returnedExpr.setValue(newInstanceOfExpr
(newExpr(v.getOp()),
v.getCheckType()));
}
public void caseNewArrayExpr(NewArrayExpr v)
{
returnedExpr.setValue(newNewArrayExpr(v.getBaseType(),
v.getSize()));
}
public void caseNewMultiArrayExpr(NewMultiArrayExpr v)
{
returnedExpr.setValue(newNewMultiArrayExpr
(v.getBaseType(),
v.getSizes()));
}
public void caseNewExpr(NewExpr v)
{
returnedExpr.setValue(newNewExpr(v.getBaseType()));
}
public void caseLengthExpr(LengthExpr v)
{
returnedExpr.setValue(newLengthExpr
(newExpr(v.getOp())));
}
public void caseNegExpr(NegExpr v)
{
returnedExpr.setValue(newNegExpr(newExpr(v.getOp())));
}
public void defaultCase(Object v)
{
returnedExpr.setValue((Expr)v);
}
});
return returnedExpr.getValue();
}
else
{
if (value instanceof ArrayRef)
return newArrayRef(((ArrayRef)value).getBase(),
newExpr(((ArrayRef)value).getIndex()));
if (value instanceof InstanceFieldRef)
return newInstanceFieldRef
(newExpr((((InstanceFieldRef)value).getBase())),
((InstanceFieldRef)value).getFieldRef());
/* have Ref/Value, which is fine -- not Jimple-specific. */
return value;
}
}
/** Returns an empty GrimpBody associated with method m. */
public GrimpBody newBody(SootMethod m)
{
return new GrimpBody(m);
}
/** Returns a GrimpBody constructed from b. */
public GrimpBody newBody(Body b, String phase)
{
return new GrimpBody(b);
}
public static Value cloneIfNecessary(Value val)
{
if( val instanceof Local || val instanceof Constant )
return val;
else
return (Value) val.clone();
}
}