use of soot.ValueBox in project soot by Sable.
the class AsmMethodSource method convertMultiANewArrayInsn.
private void convertMultiANewArrayInsn(MultiANewArrayInsnNode insn) {
StackFrame frame = getFrame(insn);
Operand[] out = frame.out();
Operand opr;
if (out == null) {
ArrayType t = (ArrayType) AsmUtil.toJimpleType(insn.desc);
int dims = insn.dims;
Operand[] sizes = new Operand[dims];
Value[] sizeVals = new Value[dims];
ValueBox[] boxes = new ValueBox[dims];
while (dims-- != 0) {
sizes[dims] = popImmediate();
sizeVals[dims] = sizes[dims].stackOrValue();
}
NewMultiArrayExpr nm = Jimple.v().newNewMultiArrayExpr(t, Arrays.asList(sizeVals));
for (int i = 0; i != boxes.length; i++) {
ValueBox vb = nm.getSizeBox(i);
sizes[i].addBox(vb);
boxes[i] = vb;
}
frame.boxes(boxes);
frame.in(sizes);
opr = new Operand(insn, nm);
frame.out(opr);
} else {
opr = out[0];
int dims = insn.dims;
Operand[] sizes = new Operand[dims];
while (dims-- != 0) sizes[dims] = pop();
frame.mergeIn(sizes);
}
push(opr);
}
use of soot.ValueBox in project soot by Sable.
the class AsmMethodSource method convertInvokeDynamicInsn.
private void convertInvokeDynamicInsn(InvokeDynamicInsnNode insn) {
StackFrame frame = getFrame(insn);
Operand[] out = frame.out();
Operand opr;
Type returnType;
if (out == null) {
// convert info on bootstrap method
SootMethodRef bsmMethodRef = toSootMethodRef(insn.bsm);
List<Value> bsmMethodArgs = new ArrayList<Value>(insn.bsmArgs.length);
for (Object bsmArg : insn.bsmArgs) {
bsmMethodArgs.add(toSootValue(bsmArg));
}
// create ref to actual method
SootClass bclass = Scene.v().getSootClass(SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME);
// Generate parameters & returnType & parameterTypes
Type[] types = Util.v().jimpleTypesOfFieldOrMethodDescriptor(insn.desc);
int nrArgs = types.length - 1;
List<Type> parameterTypes = new ArrayList<Type>(nrArgs);
List<Value> methodArgs = new ArrayList<Value>(nrArgs);
Operand[] args = new Operand[nrArgs];
ValueBox[] boxes = new ValueBox[nrArgs];
while (nrArgs-- != 0) {
parameterTypes.add(types[nrArgs]);
args[nrArgs] = popImmediate(types[nrArgs]);
methodArgs.add(args[nrArgs].stackOrValue());
}
if (methodArgs.size() > 1) {
// Call stack is FIFO, Jimple is linear
Collections.reverse(methodArgs);
Collections.reverse(parameterTypes);
}
returnType = types[types.length - 1];
// we always model invokeDynamic method refs as static method references
// of methods on the type SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME
SootMethodRef methodRef = Scene.v().makeMethodRef(bclass, insn.name, parameterTypes, returnType, true);
DynamicInvokeExpr indy = Jimple.v().newDynamicInvokeExpr(bsmMethodRef, bsmMethodArgs, methodRef, insn.bsm.getTag(), methodArgs);
if (boxes != null) {
for (int i = 0; i < types.length - 1; i++) {
boxes[i] = indy.getArgBox(i);
args[i].addBox(boxes[i]);
}
frame.boxes(boxes);
frame.in(args);
}
opr = new Operand(insn, indy);
frame.out(opr);
} else {
opr = out[0];
InvokeExpr expr = (InvokeExpr) opr.value;
List<Type> types = expr.getMethodRef().parameterTypes();
Operand[] oprs;
int nrArgs = types.size();
if (expr.getMethodRef().isStatic())
oprs = nrArgs == 0 ? null : new Operand[nrArgs];
else
oprs = new Operand[nrArgs + 1];
if (oprs != null) {
while (nrArgs-- != 0) {
oprs[nrArgs] = pop(types.get(nrArgs));
}
if (!expr.getMethodRef().isStatic())
oprs[oprs.length - 1] = pop();
frame.mergeIn(oprs);
nrArgs = types.size();
}
returnType = expr.getMethodRef().returnType();
}
if (AsmUtil.isDWord(returnType))
pushDual(opr);
else if (!(returnType instanceof VoidType))
push(opr);
else if (!units.containsKey(insn))
setUnit(insn, Jimple.v().newInvokeStmt(opr.value));
/*
* assign all read ops in case the method modifies any of the fields
*/
assignReadOps(null);
}
use of soot.ValueBox in project soot by Sable.
the class AsmMethodSource method convertMethodInsn.
private void convertMethodInsn(MethodInsnNode insn) {
int op = insn.getOpcode();
boolean instance = op != INVOKESTATIC;
StackFrame frame = getFrame(insn);
Operand[] out = frame.out();
Operand opr;
Type returnType;
if (out == null) {
String clsName = AsmUtil.toQualifiedName(insn.owner);
if (clsName.charAt(0) == '[')
clsName = "java.lang.Object";
SootClass cls = Scene.v().getSootClass(clsName);
List<Type> sigTypes = AsmUtil.toJimpleDesc(insn.desc);
returnType = sigTypes.remove(sigTypes.size() - 1);
SootMethodRef ref = Scene.v().makeMethodRef(cls, insn.name, sigTypes, returnType, !instance);
int nrArgs = sigTypes.size();
final Operand[] args;
List<Value> argList = Collections.emptyList();
if (!instance) {
args = nrArgs == 0 ? null : new Operand[nrArgs];
if (args != null)
argList = new ArrayList<Value>(nrArgs);
} else {
args = new Operand[nrArgs + 1];
if (nrArgs != 0)
argList = new ArrayList<Value>(nrArgs);
}
while (nrArgs-- != 0) {
args[nrArgs] = popImmediate(sigTypes.get(nrArgs));
argList.add(args[nrArgs].stackOrValue());
}
if (argList.size() > 1)
Collections.reverse(argList);
if (instance)
args[args.length - 1] = popLocal();
ValueBox[] boxes = args == null ? null : new ValueBox[args.length];
InvokeExpr invoke;
if (!instance) {
invoke = Jimple.v().newStaticInvokeExpr(ref, argList);
} else {
Local base = (Local) args[args.length - 1].stackOrValue();
InstanceInvokeExpr iinvoke;
if (op == INVOKESPECIAL)
iinvoke = Jimple.v().newSpecialInvokeExpr(base, ref, argList);
else if (op == INVOKEVIRTUAL)
iinvoke = Jimple.v().newVirtualInvokeExpr(base, ref, argList);
else if (op == INVOKEINTERFACE)
iinvoke = Jimple.v().newInterfaceInvokeExpr(base, ref, argList);
else
throw new AssertionError("Unknown invoke op:" + op);
boxes[boxes.length - 1] = iinvoke.getBaseBox();
args[args.length - 1].addBox(boxes[boxes.length - 1]);
invoke = iinvoke;
}
if (boxes != null) {
for (int i = 0; i != sigTypes.size(); i++) {
boxes[i] = invoke.getArgBox(i);
args[i].addBox(boxes[i]);
}
frame.boxes(boxes);
frame.in(args);
}
opr = new Operand(insn, invoke);
frame.out(opr);
} else {
opr = out[0];
InvokeExpr expr = (InvokeExpr) opr.value;
List<Type> types = expr.getMethodRef().parameterTypes();
Operand[] oprs;
int nrArgs = types.size();
if (expr.getMethodRef().isStatic())
oprs = nrArgs == 0 ? null : new Operand[nrArgs];
else
oprs = new Operand[nrArgs + 1];
if (oprs != null) {
while (nrArgs-- != 0) {
oprs[nrArgs] = pop(types.get(nrArgs));
}
if (!expr.getMethodRef().isStatic())
oprs[oprs.length - 1] = pop();
frame.mergeIn(oprs);
nrArgs = types.size();
}
returnType = expr.getMethodRef().returnType();
}
if (AsmUtil.isDWord(returnType))
pushDual(opr);
else if (!(returnType instanceof VoidType))
push(opr);
else if (!units.containsKey(insn))
setUnit(insn, Jimple.v().newInvokeStmt(opr.value));
/*
* assign all read ops in case the method modifies any of the fields
*/
assignReadOps(null);
}
use of soot.ValueBox in project soot by Sable.
the class CPApplication method substituteUses.
public void substituteUses(List useBoxes, CPFlowSet beforeSet) {
Iterator useIt = useBoxes.iterator();
while (useIt.hasNext()) {
Object useObj = useIt.next();
Value use = ((ValueBox) useObj).getValue();
if (use instanceof Local) {
Local useLocal = (Local) use;
// System.out.println("local is: "+useLocal);
Object value = beforeSet.contains(className, useLocal.toString());
if (value != null) {
// System.out.println("Local "+useLocal+"is present in before set with value"+value);
// create constant value for the value and replace this
// local use with the constant value use
Value newValue = CPHelper.createConstant(value);
if (newValue != null) {
// System.out.println("Substituted the local use with the constant value"+newValue);
((ValueBox) useObj).setValue(newValue);
} else {
// System.out.println("FAILED TO Substitute the local use with the constant value");
}
}
} else if (use instanceof FieldRef) {
FieldRef useField = (FieldRef) use;
// System.out.println("FieldRef is: "+useField);
SootField usedSootField = useField.getField();
Object value = beforeSet.contains(usedSootField.getDeclaringClass().getName(), usedSootField.getName().toString());
if (value != null) {
// System.out.println("FieldRef "+usedSootField+"is present in before set with value"+value);
// create constant value for the value and replace this
// local use with the constant value use
Value newValue = CPHelper.createConstant(value);
if (newValue != null) {
// System.out.println("Substituted the constant field ref use with the constant value"+newValue);
((ValueBox) useObj).setValue(newValue);
} else {
// System.out.println("FAILED TO Substitute the constant field ref use with the constant value");
}
}
}
}
}
use of soot.ValueBox in project soot by Sable.
the class ShortcutArrayInit method secondPattern.
/*
* Maybe its a multi-D array then we need to look for a DAssignStmt followed
* by a definition Stmt
*/
public void secondPattern(ASTStatementSequenceNode node) {
boolean success = false;
ArrayList<AugmentedStmt> toRemove = new ArrayList<AugmentedStmt>();
for (AugmentedStmt as : node.getStatements()) {
success = false;
Stmt s = as.get_Stmt();
if (!(s instanceof DefinitionStmt))
continue;
DefinitionStmt ds = (DefinitionStmt) s;
ValueBox right = ds.getRightOpBox();
Value rightValue = right.getValue();
if (!(rightValue instanceof NewArrayExpr))
continue;
if (DEBUG) {
System.out.println("Found a new ArrayExpr" + rightValue);
System.out.println("Type of array is:" + rightValue.getType());
}
// get type out
Type arrayType = rightValue.getType();
// get size....need to know this statically for sure!!!
Value size = ((NewArrayExpr) rightValue).getSize();
if (!(size instanceof IntConstant))
continue;
if (((IntConstant) size).value == 0) {
debug("Found value to be 0 doing nothing");
continue;
}
if (DEBUG)
System.out.println("Size of array is: " + ((IntConstant) size).value);
Iterator<AugmentedStmt> tempIt = node.getStatements().iterator();
// get to the array creation stmt
while (tempIt.hasNext()) {
AugmentedStmt tempAs = (AugmentedStmt) tempIt.next();
Stmt tempS = tempAs.get_Stmt();
if (tempS.equals(s))
break;
}
// have the size have the type, tempIt is poised at the current def
// stmt
ValueBox[] array = new ValueBox[((IntConstant) size).value];
success = true;
for (int i = 0; i < ((IntConstant) size).value; i++) {
// a DefinitionStmt
if (!tempIt.hasNext()) {
// since its end of the stmt seq node just return
if (DEBUG)
System.out.println("returning");
return;
}
AugmentedStmt augOne = tempIt.next();
Stmt augSOne = augOne.get_Stmt();
if (!tempIt.hasNext()) {
// since its end of the stmt seq node just return
if (DEBUG)
System.out.println("returning");
return;
}
AugmentedStmt augTwo = tempIt.next();
Stmt augSTwo = augTwo.get_Stmt();
if (!isInSequenceAssignmentPatternTwo(augSOne, augSTwo, ds.getLeftOp(), i)) {
// initializations
if (DEBUG)
System.out.println("Out of order assignment aborting attempt");
success = false;
break;
} else {
if (DEBUG)
System.out.println("Assignment stmt in order adding to array");
// the RHS of augSOne is the next assignment in the sequence
// add to ValueBox array
array[i] = ((DShortcutAssignStmt) augSOne).getRightOpBox();
toRemove.add(augOne);
toRemove.add(augTwo);
}
}
if (success) {
DArrayInitExpr tempExpr = new DArrayInitExpr(array, arrayType);
DArrayInitValueBox tempValueBox = new DArrayInitValueBox(tempExpr);
DAssignStmt newStmt = new DAssignStmt(ds.getLeftOpBox(), tempValueBox);
// stmt
if (DEBUG)
System.out.println("Created new DAssignStmt and replacing it");
InitializationDeclarationShortcut shortcutChecker = new InitializationDeclarationShortcut(as);
methodNode.apply(shortcutChecker);
boolean possible = shortcutChecker.isShortcutPossible();
if (possible) {
if (DEBUG)
System.out.println("Shortcut is possible");
// create shortcut stmt
DShortcutAssignStmt newShortcutStmt = new DShortcutAssignStmt(newStmt, arrayType);
as.set_Stmt(newShortcutStmt);
// make sure to mark the local in the DVariableDeclarations
// so that its not printed
markLocal(ds.getLeftOp());
}
break;
}
}
// end going through stmt seq node
if (success) {
// means we did a transformation remove the stmts
List<AugmentedStmt> newStmtList = new ArrayList<AugmentedStmt>();
for (AugmentedStmt as : node.getStatements()) {
if (toRemove.contains(as)) {
toRemove.remove(as);
} else {
newStmtList.add(as);
}
}
node.setStatements(newStmtList);
// make sure any other possible simplifications are done
inASTStatementSequenceNode(node);
G.v().ASTTransformations_modified = true;
}
}
Aggregations