Search in sources :

Example 21 with AssignStmt

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);
        }
          */
}
Also used : AssignStmt(soot.jimple.AssignStmt) Value(soot.Value) Local(soot.Local) Instruction23x(org.jf.dexlib2.iface.instruction.formats.Instruction23x)

Example 22 with AssignStmt

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);
    }
}
Also used : OneRegisterInstruction(org.jf.dexlib2.iface.instruction.OneRegisterInstruction) Instruction31c(org.jf.dexlib2.iface.instruction.formats.Instruction31c) Instruction21c(org.jf.dexlib2.iface.instruction.formats.Instruction21c) AssignStmt(soot.jimple.AssignStmt) StringConstant(soot.jimple.StringConstant) StringReference(org.jf.dexlib2.iface.reference.StringReference)

Example 23 with AssignStmt

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);
}
Also used : ArrayRef(soot.jimple.ArrayRef) AssignStmt(soot.jimple.AssignStmt) ValueBox(soot.ValueBox) Constant(soot.jimple.Constant) Value(soot.Value) Local(soot.Local) Unit(soot.Unit)

Example 24 with AssignStmt

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;
                    }
                }
            }
        }
    }
}
Also used : InvokeStmt(soot.jimple.InvokeStmt) AssignStmt(soot.jimple.AssignStmt) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) Local(soot.Local) Unit(soot.Unit) LocalDefs(soot.toolkits.scalar.LocalDefs) InvokeStmt(soot.jimple.InvokeStmt) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt) DefinitionStmt(soot.jimple.DefinitionStmt) NewExpr(soot.jimple.NewExpr) Jimple(soot.jimple.Jimple) DefinitionStmt(soot.jimple.DefinitionStmt)

Example 25 with AssignStmt

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);
}
Also used : AssignStmt(soot.jimple.AssignStmt) ValueBox(soot.ValueBox) Local(soot.Local) Unit(soot.Unit) DefinitionStmt(soot.jimple.DefinitionStmt)

Aggregations

AssignStmt (soot.jimple.AssignStmt)83 Local (soot.Local)50 Value (soot.Value)44 Unit (soot.Unit)40 Type (soot.Type)28 Stmt (soot.jimple.Stmt)24 InvokeExpr (soot.jimple.InvokeExpr)20 RefType (soot.RefType)19 ArrayRef (soot.jimple.ArrayRef)19 ArrayType (soot.ArrayType)17 CastExpr (soot.jimple.CastExpr)17 InvokeStmt (soot.jimple.InvokeStmt)17 ArrayList (java.util.ArrayList)15 IdentityStmt (soot.jimple.IdentityStmt)15 DefinitionStmt (soot.jimple.DefinitionStmt)13 FieldRef (soot.jimple.FieldRef)13 InstanceFieldRef (soot.jimple.InstanceFieldRef)13 IntConstant (soot.jimple.IntConstant)13 ReturnStmt (soot.jimple.ReturnStmt)13 HashSet (java.util.HashSet)12