use of soot.jimple.AssignStmt in project soot by Sable.
the class BinopInstruction method jimplify.
@Override
public void jimplify(DexBody body) {
if (!(instruction instanceof Instruction23x))
throw new IllegalArgumentException("Expected Instruction23x but got: " + instruction.getClass());
Instruction23x binOpInstr = (Instruction23x) instruction;
int dest = binOpInstr.getRegisterA();
Local source1 = body.getRegisterLocal(binOpInstr.getRegisterB());
Local source2 = body.getRegisterLocal(binOpInstr.getRegisterC());
Value expr = getExpression(source1, source2);
AssignStmt assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), expr);
assign.addTag(getTag());
setUnit(assign);
addTags(assign);
body.add(assign);
/*
if (IDalvikTyper.ENABLE_DVKTYPER) {
int op = (int)instruction.getOpcode().value;
BinopExpr bexpr = (BinopExpr)expr;
JAssignStmt jassign = (JAssignStmt)assign;
DalvikTyper.v().setType(bexpr.getOp1Box(), op1BinType[op-0x90], true);
DalvikTyper.v().setType(bexpr.getOp2Box(), op2BinType[op-0x90], true);
DalvikTyper.v().setType(jassign.leftBox, resBinType[op-0x90], false);
}
*/
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class ConstStringInstruction method jimplify.
@Override
public void jimplify(DexBody body) {
int dest = ((OneRegisterInstruction) instruction).getRegisterA();
String s;
if (instruction instanceof Instruction21c) {
Instruction21c i = (Instruction21c) instruction;
s = ((StringReference) (i.getReference())).getString();
} else if (instruction instanceof Instruction31c) {
Instruction31c i = (Instruction31c) instruction;
s = ((StringReference) (i.getReference())).getString();
} else
throw new IllegalArgumentException("Expected Instruction21c or Instruction31c but got neither.");
StringConstant sc = StringConstant.v(s);
AssignStmt assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), sc);
setUnit(assign);
addTags(assign);
body.add(assign);
if (IDalvikTyper.ENABLE_DVKTYPER) {
DalvikTyper.v().setType(assign.getLeftOpBox(), sc.getType(), false);
}
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class DexArrayInitReducer method internalTransform.
@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
// Make sure that we only have linear control flow
if (!b.getTraps().isEmpty())
return;
// Look for a chain of two constant assignments followed by an array put
Unit u1 = null, u2 = null;
for (Iterator<Unit> uIt = b.getUnits().snapshotIterator(); uIt.hasNext(); ) {
Unit u = uIt.next();
// If this is not an assignment, it does not matter.
if (!(u instanceof AssignStmt) || !((Stmt) u).getBoxesPointingToThis().isEmpty()) {
u1 = null;
u2 = null;
continue;
}
// If this is an assignment to an array, we must already have two
// preceding constant assignments
AssignStmt assignStmt = (AssignStmt) u;
if (assignStmt.getLeftOp() instanceof ArrayRef) {
if (u1 != null && u2 != null && u2.getBoxesPointingToThis().isEmpty() && assignStmt.getBoxesPointingToThis().isEmpty()) {
ArrayRef arrayRef = (ArrayRef) assignStmt.getLeftOp();
Value u1val = u1.getDefBoxes().get(0).getValue();
Value u2val = u2.getDefBoxes().get(0).getValue();
// index
if (arrayRef.getIndex() == u1val)
arrayRef.setIndex(((AssignStmt) u1).getRightOp());
else if (arrayRef.getIndex() == u2val)
arrayRef.setIndex(((AssignStmt) u2).getRightOp());
// value
if (assignStmt.getRightOp() == u1val)
assignStmt.setRightOp(((AssignStmt) u1).getRightOp());
else if (assignStmt.getRightOp() == u2val)
assignStmt.setRightOp(((AssignStmt) u2).getRightOp());
// Remove the unnecessary assignments
Unit checkU = u;
boolean foundU1 = false, foundU2 = false, doneU1 = false, doneU2 = false;
while (!(doneU1 && doneU2) && !(foundU1 && foundU2) && checkU != null) {
// Does the current statement use the value?
for (ValueBox vb : checkU.getUseBoxes()) {
if (!doneU1 && vb.getValue() == u1val)
foundU1 = true;
if (!doneU2 && vb.getValue() == u2val)
foundU2 = true;
}
// Does the current statement overwrite the value?
for (ValueBox vb : checkU.getDefBoxes()) {
if (vb.getValue() == u1val)
doneU1 = true;
else if (vb.getValue() == u2val)
doneU2 = true;
}
// If this statement branches, we abort
if (checkU.branches()) {
foundU1 = true;
foundU2 = true;
break;
}
// Get the next statement
checkU = b.getUnits().getSuccOf(checkU);
}
if (!foundU1) {
// only remove constant assignment if the left value is Local
if (u1val instanceof Local) {
b.getUnits().remove(u1);
if (Options.v().verbose()) {
logger.debug("[" + b.getMethod().getName() + "] remove 1 " + u1);
}
}
}
if (!foundU2) {
// only remove constant assignment if the left value is Local
if (u2val instanceof Local) {
b.getUnits().remove(u2);
if (Options.v().verbose()) {
logger.debug("[" + b.getMethod().getName() + "] remove 2 " + u2);
}
}
}
u1 = null;
u2 = null;
} else {
// No proper initialization before
u1 = null;
u2 = null;
continue;
}
}
// value.
if (!(assignStmt.getRightOp() instanceof Constant)) {
u1 = null;
u2 = null;
continue;
}
if (u1 == null) {
u1 = assignStmt;
} else if (u2 == null) {
u2 = assignStmt;
// If the last value is overwritten again, we start again at the beginning
if (u1 != null) {
Value op1 = ((AssignStmt) u1).getLeftOp();
if (op1 == ((AssignStmt) u2).getLeftOp()) {
u1 = u2;
u2 = null;
}
}
} else {
u1 = u2;
u2 = assignStmt;
}
}
// Remove all locals that are no longer necessary
UnusedLocalEliminator.v().transform(b);
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class TypeResolver method split_new.
/* Taken from the soot.jimple.toolkits.typing.TypeResolver class of Soot
version 2.2.5. */
private void split_new() {
LocalDefs defs = LocalDefs.Factory.newLocalDefs(jb);
PatchingChain<Unit> units = this.jb.getUnits();
Stmt[] stmts = new Stmt[units.size()];
units.toArray(stmts);
final Jimple jimple = Jimple.v();
for (Stmt stmt : stmts) {
if (stmt instanceof InvokeStmt) {
InvokeStmt invoke = (InvokeStmt) stmt;
if (invoke.getInvokeExpr() instanceof SpecialInvokeExpr) {
SpecialInvokeExpr special = (SpecialInvokeExpr) invoke.getInvokeExpr();
if (special.getMethodRef().name().equals("<init>")) {
List<Unit> deflist = defs.getDefsOfAt((Local) special.getBase(), invoke);
while (deflist.size() == 1) {
Stmt stmt2 = (Stmt) deflist.get(0);
if (stmt2 instanceof AssignStmt) {
AssignStmt assign = (AssignStmt) stmt2;
if (assign.getRightOp() instanceof Local) {
deflist = defs.getDefsOfAt((Local) assign.getRightOp(), assign);
continue;
} else if (assign.getRightOp() instanceof NewExpr) {
Local newlocal = jimple.newLocal("tmp", null);
newlocal.setName("tmp$" + System.identityHashCode(newlocal));
this.jb.getLocals().add(newlocal);
special.setBase(newlocal);
DefinitionStmt assignStmt = jimple.newAssignStmt(assign.getLeftOp(), newlocal);
Unit u = Util.findLastIdentityUnit(jb, assign);
units.insertAfter(assignStmt, u);
assign.setLeftOp(newlocal);
this.addLocal(newlocal);
this.initAssignment(assignStmt);
}
}
break;
}
}
}
}
}
}
use of soot.jimple.AssignStmt in project soot by Sable.
the class StackFrame method mergeIn.
/**
* Merges the specified operands with the operands used by this frame.
* @param oprs the new operands.
* @throws IllegalArgumentException if the number of new operands is not equal
* to the number of old operands.
*/
void mergeIn(Operand... oprs) {
ArrayList<Operand[]> in = this.in;
if (in.get(0).length != oprs.length)
throw new IllegalArgumentException("Invalid in operands length!");
int nrIn = in.size();
boolean diff = false;
for (int i = 0; i != oprs.length; i++) {
Operand newOp = oprs[i];
diff = true;
/* merge, since prevOp != newOp */
Local stack = inStackLocals[i];
if (stack != null) {
if (newOp.stack == null) {
newOp.stack = stack;
AssignStmt as = Jimple.v().newAssignStmt(stack, newOp.value);
src.setUnit(newOp.insn, as);
newOp.updateBoxes();
} else {
AssignStmt as = Jimple.v().newAssignStmt(stack, newOp.stackOrValue());
src.mergeUnits(newOp.insn, as);
newOp.addBox(as.getRightOpBox());
}
} else {
for (int j = 0; j != nrIn; j++) {
stack = in.get(j)[i].stack;
if (stack != null)
break;
}
if (stack == null) {
stack = newOp.stack;
if (stack == null)
stack = src.newStackLocal();
}
/* add assign statement for prevOp */
ValueBox box = boxes == null ? null : boxes[i];
for (int j = 0; j != nrIn; j++) {
Operand prevOp = in.get(j)[i];
if (prevOp.stack == stack)
continue;
prevOp.removeBox(box);
if (prevOp.stack == null) {
prevOp.stack = stack;
AssignStmt as = Jimple.v().newAssignStmt(stack, prevOp.value);
src.setUnit(prevOp.insn, as);
} else {
Unit u = src.getUnit(prevOp.insn);
DefinitionStmt as = (DefinitionStmt) (u instanceof UnitContainer ? ((UnitContainer) u).getFirstUnit() : u);
ValueBox lvb = as.getLeftOpBox();
assert lvb.getValue() == prevOp.stack : "Invalid stack local!";
lvb.setValue(stack);
prevOp.stack = stack;
}
prevOp.updateBoxes();
}
if (newOp.stack != stack) {
if (newOp.stack == null) {
newOp.stack = stack;
AssignStmt as = Jimple.v().newAssignStmt(stack, newOp.value);
src.setUnit(newOp.insn, as);
} else {
Unit u = src.getUnit(newOp.insn);
DefinitionStmt as = (DefinitionStmt) (u instanceof UnitContainer ? ((UnitContainer) u).getFirstUnit() : u);
ValueBox lvb = as.getLeftOpBox();
assert lvb.getValue() == newOp.stack : "Invalid stack local!";
lvb.setValue(stack);
newOp.stack = stack;
}
newOp.updateBoxes();
}
if (box != null)
box.setValue(stack);
inStackLocals[i] = stack;
}
/*
* this version uses allocates local if it
* finds both operands have stack locals allocated already
*/
/*if (stack == null) {
if (in.size() != 1)
throw new AssertionError("Local h " + in.size());
stack = src.newStackLocal();
inStackLocals[i] = stack;
ValueBox box = boxes == null ? null : boxes[i];
/* add assign statement for prevOp *
for (int j = 0; j != nrIn; j++) {
Operand prevOp = in.get(j)[i];
prevOp.removeBox(box);
if (prevOp.stack == null) {
prevOp.stack = stack;
as = Jimple.v().newAssignStmt(stack, prevOp.value);
src.setUnit(prevOp.insn, as);
prevOp.updateBoxes();
} else {
as = Jimple.v().newAssignStmt(stack, prevOp.stackOrValue());
src.mergeUnits(prevOp.insn, as);
}
prevOp.addBox(as.getRightOpBox());
}
if (box != null)
box.setValue(stack);
}
if (newOp.stack == null) {
newOp.stack = stack;
as = Jimple.v().newAssignStmt(stack, newOp.value);
src.setUnit(newOp.insn, as);
newOp.updateBoxes();
} else {
as = Jimple.v().newAssignStmt(stack, newOp.stackOrValue());
src.mergeUnits(newOp.insn, as);
}
newOp.addBox(as.getRightOpBox());*/
}
if (diff)
in.add(oprs);
}
Aggregations