Search in sources :

Example 1 with IdentityRef

use of soot.jimple.IdentityRef in project soot by Sable.

the class MethodNodeFactory method handleStmt.

/**
 * Adds the edges required for this statement to the graph.
 */
public final void handleStmt(Stmt s) {
    // We only consider reflective class creation when it is enabled
    if (s.containsInvokeExpr()) {
        if (!pag.getCGOpts().types_for_invoke())
            return;
        InvokeExpr iexpr = s.getInvokeExpr();
        if (iexpr instanceof VirtualInvokeExpr) {
            if (!isReflectionNewInstance(iexpr))
                return;
        } else if (!(iexpr instanceof StaticInvokeExpr))
            return;
    }
    s.apply(new AbstractStmtSwitch() {

        @Override
        public final void caseAssignStmt(AssignStmt as) {
            Value l = as.getLeftOp();
            Value r = as.getRightOp();
            if (!(l.getType() instanceof RefLikeType))
                return;
            assert r.getType() instanceof RefLikeType : "Type mismatch in assignment " + as + " in method " + method.getSignature();
            l.apply(MethodNodeFactory.this);
            Node dest = getNode();
            r.apply(MethodNodeFactory.this);
            Node src = getNode();
            if (l instanceof InstanceFieldRef) {
                ((InstanceFieldRef) l).getBase().apply(MethodNodeFactory.this);
                pag.addDereference((VarNode) getNode());
            }
            if (r instanceof InstanceFieldRef) {
                ((InstanceFieldRef) r).getBase().apply(MethodNodeFactory.this);
                pag.addDereference((VarNode) getNode());
            } else if (r instanceof StaticFieldRef) {
                StaticFieldRef sfr = (StaticFieldRef) r;
                SootFieldRef s = sfr.getFieldRef();
                if (pag.getOpts().empties_as_allocs()) {
                    if (s.declaringClass().getName().equals("java.util.Collections")) {
                        if (s.name().equals("EMPTY_SET")) {
                            src = pag.makeAllocNode(RefType.v("java.util.HashSet"), RefType.v("java.util.HashSet"), method);
                        } else if (s.name().equals("EMPTY_MAP")) {
                            src = pag.makeAllocNode(RefType.v("java.util.HashMap"), RefType.v("java.util.HashMap"), method);
                        } else if (s.name().equals("EMPTY_LIST")) {
                            src = pag.makeAllocNode(RefType.v("java.util.LinkedList"), RefType.v("java.util.LinkedList"), method);
                        }
                    } else if (s.declaringClass().getName().equals("java.util.Hashtable")) {
                        if (s.name().equals("emptyIterator")) {
                            src = pag.makeAllocNode(RefType.v("java.util.Hashtable$EmptyIterator"), RefType.v("java.util.Hashtable$EmptyIterator"), method);
                        } else if (s.name().equals("emptyEnumerator")) {
                            src = pag.makeAllocNode(RefType.v("java.util.Hashtable$EmptyEnumerator"), RefType.v("java.util.Hashtable$EmptyEnumerator"), method);
                        }
                    }
                }
            }
            mpag.addInternalEdge(src, dest);
        }

        @Override
        public final void caseReturnStmt(ReturnStmt rs) {
            if (!(rs.getOp().getType() instanceof RefLikeType))
                return;
            rs.getOp().apply(MethodNodeFactory.this);
            Node retNode = getNode();
            mpag.addInternalEdge(retNode, caseRet());
        }

        @Override
        public final void caseIdentityStmt(IdentityStmt is) {
            if (!(is.getLeftOp().getType() instanceof RefLikeType))
                return;
            Value leftOp = is.getLeftOp();
            Value rightOp = is.getRightOp();
            leftOp.apply(MethodNodeFactory.this);
            Node dest = getNode();
            rightOp.apply(MethodNodeFactory.this);
            Node src = getNode();
            mpag.addInternalEdge(src, dest);
            // in case library mode is activated add allocations to any
            // possible type of this local and
            // parameters of accessible methods
            int libOption = pag.getCGOpts().library();
            if (libOption != CGOptions.library_disabled && (accessibilityOracle.isAccessible(method))) {
                if (rightOp instanceof IdentityRef) {
                    Type rt = rightOp.getType();
                    rt.apply(new SparkLibraryHelper(pag, src, method));
                }
            }
        }

        @Override
        public final void caseThrowStmt(ThrowStmt ts) {
            ts.getOp().apply(MethodNodeFactory.this);
            mpag.addOutEdge(getNode(), pag.nodeFactory().caseThrow());
        }
    });
}
Also used : VarNode(soot.jimple.spark.pag.VarNode) AssignStmt(soot.jimple.AssignStmt) NewInstanceNode(soot.jimple.spark.pag.NewInstanceNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode) SootFieldRef(soot.SootFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) RefLikeType(soot.RefLikeType) RefType(soot.RefType) Type(soot.Type) RefLikeType(soot.RefLikeType) ArrayType(soot.ArrayType) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) IdentityRef(soot.jimple.IdentityRef) AbstractStmtSwitch(soot.jimple.AbstractStmtSwitch) Value(soot.Value) InstanceFieldRef(soot.jimple.InstanceFieldRef) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) ReturnStmt(soot.jimple.ReturnStmt) ThrowStmt(soot.jimple.ThrowStmt) IdentityStmt(soot.jimple.IdentityStmt) SparkLibraryHelper(soot.jimple.spark.internal.SparkLibraryHelper)

Example 2 with IdentityRef

use of soot.jimple.IdentityRef in project soot by Sable.

the class Validate method validateArrays.

public static void validateArrays(Body b) {
    Set<DefinitionStmt> definitions = new HashSet<DefinitionStmt>();
    Set<Unit> unitWithArrayRef = new HashSet<Unit>();
    for (Unit u : b.getUnits()) {
        if (u instanceof DefinitionStmt) {
            DefinitionStmt s = (DefinitionStmt) u;
            definitions.add(s);
        }
        List<ValueBox> uses = u.getUseBoxes();
        for (ValueBox vb : uses) {
            Value v = vb.getValue();
            if (v instanceof ArrayRef) {
                unitWithArrayRef.add(u);
            }
        }
    }
    final LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(b, true);
    Set<Unit> toReplace = new HashSet<Unit>();
    for (Unit u : unitWithArrayRef) {
        boolean ok = false;
        List<ValueBox> uses = u.getUseBoxes();
        for (ValueBox vb : uses) {
            Value v = vb.getValue();
            if (v instanceof ArrayRef) {
                ArrayRef ar = (ArrayRef) v;
                Local base = (Local) ar.getBase();
                List<Unit> defs = localDefs.getDefsOfAt(base, u);
                // add aliases
                Set<Unit> alreadyHandled = new HashSet<Unit>();
                while (true) {
                    boolean isMore = false;
                    for (Unit d : defs) {
                        if (alreadyHandled.contains(d))
                            continue;
                        if (d instanceof AssignStmt) {
                            AssignStmt ass = (AssignStmt) d;
                            Value r = ass.getRightOp();
                            if (r instanceof Local) {
                                defs.addAll(localDefs.getDefsOfAt((Local) r, d));
                                alreadyHandled.add(d);
                                isMore = true;
                                break;
                            } else if (r instanceof ArrayRef) {
                                ArrayRef arrayRef = (ArrayRef) r;
                                Local l = (Local) arrayRef.getBase();
                                defs.addAll(localDefs.getDefsOfAt(l, d));
                                alreadyHandled.add(d);
                                isMore = true;
                                break;
                            }
                        }
                    }
                    if (!isMore)
                        break;
                }
                // System.out.println("def size "+ defs.size());
                for (Unit def : defs) {
                    // System.out.println("def u "+ def);
                    Value r = null;
                    if (def instanceof IdentityStmt) {
                        IdentityStmt idstmt = (IdentityStmt) def;
                        r = idstmt.getRightOp();
                    } else if (def instanceof AssignStmt) {
                        AssignStmt assStmt = (AssignStmt) def;
                        r = assStmt.getRightOp();
                    } else {
                        throw new RuntimeException("error: definition statement not an IdentityStmt nor an AssignStmt! " + def);
                    }
                    Type t = null;
                    if (r instanceof InvokeExpr) {
                        InvokeExpr ie = (InvokeExpr) r;
                        t = ie.getType();
                        // System.out.println("ie type: "+ t +" "+ t.getClass());
                        if (t instanceof ArrayType)
                            ok = true;
                    } else if (r instanceof FieldRef) {
                        FieldRef ref = (FieldRef) r;
                        t = ref.getType();
                        // System.out.println("fr type: "+ t +" "+ t.getClass());
                        if (t instanceof ArrayType)
                            ok = true;
                    } else if (r instanceof IdentityRef) {
                        IdentityRef ir = (IdentityRef) r;
                        t = ir.getType();
                        if (t instanceof ArrayType)
                            ok = true;
                    } else if (r instanceof CastExpr) {
                        CastExpr c = (CastExpr) r;
                        t = c.getType();
                        if (t instanceof ArrayType)
                            ok = true;
                    } else if (r instanceof ArrayRef) {
                    // we also check that this arrayref is correctly defined
                    } else if (r instanceof NewArrayExpr) {
                        ok = true;
                    } else if (r instanceof Local) {
                    } else if (r instanceof Constant) {
                    } else {
                        throw new RuntimeException("error: unknown right hand side of definition stmt " + def);
                    }
                    if (ok)
                        break;
                }
                if (ok)
                    break;
            }
        }
        if (!ok) {
            toReplace.add(u);
        }
    }
    int i = 0;
    for (Unit u : toReplace) {
        System.out.println("warning: incorrect array def, replacing unit " + u);
        // new object
        RefType throwableType = RefType.v("java.lang.Throwable");
        Local ttt = Jimple.v().newLocal("ttt_" + ++i, throwableType);
        b.getLocals().add(ttt);
        Value r = Jimple.v().newNewExpr(throwableType);
        Unit initLocalUnit = Jimple.v().newAssignStmt(ttt, r);
        // call <init> method with a string parameter for message
        List<String> pTypes = new ArrayList<String>();
        pTypes.add("java.lang.String");
        boolean isStatic = false;
        SootMethodRef mRef = Validate.makeMethodRef("java.lang.Throwable", "<init>", "", pTypes, isStatic);
        List<Value> parameters = new ArrayList<Value>();
        parameters.add(StringConstant.v("Soot updated this instruction"));
        InvokeExpr ie = Jimple.v().newSpecialInvokeExpr(ttt, mRef, parameters);
        Unit initMethod = Jimple.v().newInvokeStmt(ie);
        // throw exception
        Unit newUnit = Jimple.v().newThrowStmt(ttt);
        // change instruction in body
        b.getUnits().swapWith(u, newUnit);
        b.getUnits().insertBefore(initMethod, newUnit);
        b.getUnits().insertBefore(initLocalUnit, initMethod);
    // Exception a = throw new Exception();
    }
    DeadAssignmentEliminator.v().transform(b);
    UnusedLocalEliminator.v().transform(b);
    NopEliminator.v().transform(b);
    UnreachableCodeEliminator.v().transform(b);
}
Also used : AssignStmt(soot.jimple.AssignStmt) Constant(soot.jimple.Constant) StringConstant(soot.jimple.StringConstant) ArrayList(java.util.ArrayList) Unit(soot.Unit) ArrayRef(soot.jimple.ArrayRef) ArrayType(soot.ArrayType) RefType(soot.RefType) InvokeExpr(soot.jimple.InvokeExpr) IdentityRef(soot.jimple.IdentityRef) CastExpr(soot.jimple.CastExpr) IdentityStmt(soot.jimple.IdentityStmt) HashSet(java.util.HashSet) FieldRef(soot.jimple.FieldRef) SootMethodRef(soot.SootMethodRef) Local(soot.Local) LocalDefs(soot.toolkits.scalar.LocalDefs) RefType(soot.RefType) ArrayType(soot.ArrayType) Type(soot.Type) VoidType(soot.VoidType) NewArrayExpr(soot.jimple.NewArrayExpr) ValueBox(soot.ValueBox) Value(soot.Value) DefinitionStmt(soot.jimple.DefinitionStmt)

Example 3 with IdentityRef

use of soot.jimple.IdentityRef in project soot by Sable.

the class BafASMBackend method generateMethodBody.

/*
	 * (non-Javadoc)
	 * 
	 * @see soot.AbstractASMBackend#generateMethodBody(org.objectweb.asm.
	 * MethodVisitor, soot.SootMethod)
	 */
@Override
protected void generateMethodBody(MethodVisitor mv, SootMethod method) {
    BafBody body = getBafBody(method);
    Chain<Unit> instructions = body.getUnits();
    /*
		 * Create a label for each instruction that is the target of some branch
		 */
    for (UnitBox box : body.getUnitBoxes(true)) {
        Unit u = box.getUnit();
        if (!branchTargetLabels.containsKey(u)) {
            branchTargetLabels.put(u, new Label());
        }
    }
    Label startLabel = null;
    if (Options.v().write_local_annotations()) {
        startLabel = new Label();
        mv.visitLabel(startLabel);
    }
    /*
		 * Handle all TRY-CATCH-blocks
		 */
    for (Trap trap : body.getTraps()) {
        // Check if the try-block contains any statement
        if (trap.getBeginUnit() != trap.getEndUnit()) {
            Label start = branchTargetLabels.get(trap.getBeginUnit());
            Label end = branchTargetLabels.get(trap.getEndUnit());
            Label handler = branchTargetLabels.get(trap.getHandlerUnit());
            String type = slashify(trap.getException().getName());
            mv.visitTryCatchBlock(start, end, handler, type);
        }
    }
    /*
		 * Handle local variable slots for the "this"-local and the parameters
		 */
    int localCount = 0;
    int[] paramSlots = new int[method.getParameterCount()];
    Set<Local> assignedLocals = new HashSet<Local>();
    /*
		 * For non-static methods the first parameters and zero-slot is the
		 * "this"-local
		 */
    if (!method.isStatic()) {
        ++localCount;
    }
    for (int i = 0; i < method.getParameterCount(); ++i) {
        paramSlots[i] = localCount;
        localCount += sizeOfType(method.getParameterType(i));
    }
    for (Unit u : instructions) {
        if (u instanceof IdentityInst && ((IdentityInst) u).getLeftOp() instanceof Local) {
            Local l = (Local) ((IdentityInst) u).getLeftOp();
            IdentityRef identity = (IdentityRef) ((IdentityInst) u).getRightOp();
            int slot = 0;
            if (identity instanceof ThisRef) {
                if (method.isStatic())
                    throw new RuntimeException("Attempting to use 'this' in static method");
            } else if (identity instanceof ParameterRef)
                slot = paramSlots[((ParameterRef) identity).getIndex()];
            else {
                // Exception ref. Skip over this
                continue;
            }
            localToSlot.put(l, slot);
            assignedLocals.add(l);
        }
    }
    for (Local local : body.getLocals()) {
        if (assignedLocals.add(local)) {
            localToSlot.put(local, localCount);
            localCount += sizeOfType(local.getType());
        }
    }
    // Generate the code
    for (Unit u : instructions) {
        if (branchTargetLabels.containsKey(u)) {
            mv.visitLabel(branchTargetLabels.get(u));
        }
        if (u.hasTag("LineNumberTag")) {
            LineNumberTag lnt = (LineNumberTag) u.getTag("LineNumberTag");
            Label l;
            if (branchTargetLabels.containsKey(u)) {
                l = branchTargetLabels.get(u);
            } else {
                l = new Label();
                mv.visitLabel(l);
            }
            mv.visitLineNumber(lnt.getLineNumber(), l);
        }
        generateInstruction(mv, (Inst) u);
    }
    // Generate the local annotations
    if (Options.v().write_local_annotations()) {
        Label endLabel = new Label();
        mv.visitLabel(endLabel);
        for (Local local : body.getLocals()) {
            Integer slot = localToSlot.get(local);
            if (slot != null) {
                BafLocal l = (BafLocal) local;
                if (l.getOriginalLocal() != null) {
                    Local jimpleLocal = l.getOriginalLocal();
                    if (jimpleLocal != null)
                        mv.visitLocalVariable(jimpleLocal.getName(), toTypeDesc(jimpleLocal.getType()), null, startLabel, endLabel, slot);
                }
            }
        }
    }
}
Also used : UnitBox(soot.UnitBox) Label(org.objectweb.asm.Label) BafLocal(soot.baf.internal.BafLocal) Local(soot.Local) Trap(soot.Trap) Unit(soot.Unit) ParameterRef(soot.jimple.ParameterRef) ThisRef(soot.jimple.ThisRef) LineNumberTag(soot.tagkit.LineNumberTag) IdentityRef(soot.jimple.IdentityRef) HashSet(java.util.HashSet) BafLocal(soot.baf.internal.BafLocal)

Example 4 with IdentityRef

use of soot.jimple.IdentityRef in project soot by Sable.

the class SiteInliner method inlineSite.

/**
 *        Inlines the given site.  Note that this method does
 *        not actually check if it's safe (with respect to access modifiers and special invokes)
 *        for it to be inlined.  That functionality is handled by the InlinerSafetyManager.
 */
public static List inlineSite(SootMethod inlinee, Stmt toInline, SootMethod container, Map options) {
    boolean enableNullPointerCheckInsertion = PhaseOptions.getBoolean(options, "insert-null-checks");
    boolean enableRedundantCastInsertion = PhaseOptions.getBoolean(options, "insert-redundant-casts");
    Hierarchy hierarchy = Scene.v().getActiveHierarchy();
    JimpleBody containerB = (JimpleBody) container.getActiveBody();
    Chain<Unit> containerUnits = containerB.getUnits();
    if (!(inlinee.getDeclaringClass().isApplicationClass() || inlinee.getDeclaringClass().isLibraryClass()))
        return null;
    Body inlineeB = inlinee.getActiveBody();
    Chain<Unit> inlineeUnits = inlineeB.getUnits();
    InvokeExpr ie = toInline.getInvokeExpr();
    Value thisToAdd = null;
    if (ie instanceof InstanceInvokeExpr)
        thisToAdd = ((InstanceInvokeExpr) ie).getBase();
    // Insert casts to please the verifier.
    {
        boolean targetUsesThis = true;
        if (enableRedundantCastInsertion && ie instanceof InstanceInvokeExpr && targetUsesThis) {
            // The verifier will complain if targetUsesThis, and:
            // the argument passed to the method is not the same type.
            // For instance, Bottle.price_static takes a cost.
            // Cost is an interface implemented by Bottle.
            SootClass localType, parameterType;
            localType = ((RefType) ((InstanceInvokeExpr) ie).getBase().getType()).getSootClass();
            parameterType = inlinee.getDeclaringClass();
            if (localType.isInterface() || hierarchy.isClassSuperclassOf(localType, parameterType)) {
                Local castee = Jimple.v().newLocal("__castee", parameterType.getType());
                containerB.getLocals().add(castee);
                containerB.getUnits().insertBefore(Jimple.v().newAssignStmt(castee, Jimple.v().newCastExpr(((InstanceInvokeExpr) ie).getBase(), parameterType.getType())), toInline);
                thisToAdd = castee;
            }
        }
    }
    // (If enabled), add a null pointer check.
    {
        if (enableNullPointerCheckInsertion && ie instanceof InstanceInvokeExpr) {
            boolean caught = TrapManager.isExceptionCaughtAt(Scene.v().getSootClass("java.lang.NullPointerException"), toInline, containerB);
            /* Ah ha.  Caught again! */
            if (caught) {
                /* In this case, we don't use throwPoint;
                     * instead, put the code right there. */
                Stmt insertee = Jimple.v().newIfStmt(Jimple.v().newNeExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), toInline);
                containerB.getUnits().insertBefore(insertee, toInline);
                // This sucks (but less than before).
                ((IfStmt) insertee).setTarget(toInline);
                ThrowManager.addThrowAfter(containerB, insertee);
            } else {
                Stmt throwPoint = ThrowManager.getNullPointerExceptionThrower(containerB);
                containerB.getUnits().insertBefore(Jimple.v().newIfStmt(Jimple.v().newEqExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), throwPoint), toInline);
            }
        }
    }
    // Add synchronizing stuff.
    {
        if (inlinee.isSynchronized()) {
            // Need to get the class object if ie is a static invoke.
            if (ie instanceof InstanceInvokeExpr)
                SynchronizerManager.v().synchronizeStmtOn(toInline, containerB, (Local) ((InstanceInvokeExpr) ie).getBase());
            else {
                // synchronization.
                if (!container.getDeclaringClass().isInterface()) {
                    // Whew!
                    Local l = SynchronizerManager.v().addStmtsToFetchClassBefore(containerB, toInline);
                    SynchronizerManager.v().synchronizeStmtOn(toInline, containerB, l);
                }
            }
        }
    }
    Stmt exitPoint = (Stmt) containerUnits.getSuccOf(toInline);
    // First, clone all of the inlinee's units & locals.
    HashMap<Local, Local> oldLocalsToNew = new HashMap<Local, Local>();
    HashMap<Stmt, Stmt> oldUnitsToNew = new HashMap<Stmt, Stmt>();
    {
        Stmt cursor = toInline;
        for (Iterator<Unit> currIt = inlineeUnits.iterator(); currIt.hasNext(); ) {
            final Stmt curr = (Stmt) currIt.next();
            Stmt currPrime = (Stmt) curr.clone();
            if (currPrime == null)
                throw new RuntimeException("getting null from clone!");
            currPrime.addAllTagsOf(curr);
            containerUnits.insertAfter(currPrime, cursor);
            cursor = currPrime;
            oldUnitsToNew.put(curr, currPrime);
        }
        for (Iterator<Local> lIt = inlineeB.getLocals().iterator(); lIt.hasNext(); ) {
            final Local l = lIt.next();
            Local lPrime = (Local) l.clone();
            if (lPrime == null)
                throw new RuntimeException("getting null from local clone!");
            containerB.getLocals().add(lPrime);
            oldLocalsToNew.put(l, lPrime);
        }
    }
    // Backpatch the newly-inserted units using newly-constructed maps.
    {
        Iterator<Unit> it = containerUnits.iterator(containerUnits.getSuccOf(toInline), containerUnits.getPredOf(exitPoint));
        while (it.hasNext()) {
            Stmt patchee = (Stmt) it.next();
            for (ValueBox box : patchee.getUseAndDefBoxes()) {
                if (!(box.getValue() instanceof Local))
                    continue;
                Local lPrime = oldLocalsToNew.get(box.getValue());
                if (lPrime != null)
                    box.setValue(lPrime);
                else
                    throw new RuntimeException("local has no clone!");
            }
            for (UnitBox box : patchee.getUnitBoxes()) {
                Unit uPrime = (oldUnitsToNew.get(box.getUnit()));
                if (uPrime != null)
                    box.setUnit(uPrime);
                else
                    throw new RuntimeException("inlined stmt has no clone!");
            }
        }
    }
    // Copy & backpatch the traps; preserve their same order.
    {
        Trap prevTrap = null;
        for (Trap t : inlineeB.getTraps()) {
            Stmt newBegin = oldUnitsToNew.get(t.getBeginUnit()), newEnd = oldUnitsToNew.get(t.getEndUnit()), newHandler = oldUnitsToNew.get(t.getHandlerUnit());
            if (newBegin == null || newEnd == null || newHandler == null)
                throw new RuntimeException("couldn't map trap!");
            Trap trap = Jimple.v().newTrap(t.getException(), newBegin, newEnd, newHandler);
            if (prevTrap == null)
                containerB.getTraps().addFirst(trap);
            else
                containerB.getTraps().insertAfter(trap, prevTrap);
            prevTrap = trap;
        }
    }
    // Handle identity stmt's and returns.
    {
        Iterator<Unit> it = containerUnits.iterator(containerUnits.getSuccOf(toInline), containerUnits.getPredOf(exitPoint));
        ArrayList<Unit> cuCopy = new ArrayList<Unit>();
        while (it.hasNext()) {
            cuCopy.add(it.next());
        }
        for (Unit u : cuCopy) {
            Stmt s = (Stmt) u;
            if (s instanceof IdentityStmt) {
                IdentityRef rhs = (IdentityRef) ((IdentityStmt) s).getRightOp();
                if (rhs instanceof CaughtExceptionRef)
                    continue;
                else if (rhs instanceof ThisRef) {
                    if (!(ie instanceof InstanceInvokeExpr))
                        throw new RuntimeException("thisref with no receiver!");
                    containerUnits.swapWith(s, Jimple.v().newAssignStmt(((IdentityStmt) s).getLeftOp(), thisToAdd));
                } else if (rhs instanceof ParameterRef) {
                    ParameterRef pref = (ParameterRef) rhs;
                    containerUnits.swapWith(s, Jimple.v().newAssignStmt(((IdentityStmt) s).getLeftOp(), ie.getArg(pref.getIndex())));
                }
            } else if (s instanceof ReturnStmt) {
                if (toInline instanceof InvokeStmt) {
                    // munch, munch.
                    containerUnits.swapWith(s, Jimple.v().newGotoStmt(exitPoint));
                    continue;
                }
                if (!(toInline instanceof AssignStmt))
                    throw new RuntimeException("invoking stmt neither InvokeStmt nor AssignStmt!??!?!");
                Value ro = ((ReturnStmt) s).getOp();
                Value lhs = ((AssignStmt) toInline).getLeftOp();
                AssignStmt as = Jimple.v().newAssignStmt(lhs, ro);
                containerUnits.insertBefore(as, s);
                containerUnits.swapWith(s, Jimple.v().newGotoStmt(exitPoint));
            } else if (s instanceof ReturnVoidStmt)
                containerUnits.swapWith(s, Jimple.v().newGotoStmt(exitPoint));
        }
    }
    List<Unit> newStmts = new ArrayList<Unit>();
    for (Iterator<Unit> i = containerUnits.iterator(containerUnits.getSuccOf(toInline), containerUnits.getPredOf(exitPoint)); i.hasNext(); ) {
        newStmts.add(i.next());
    }
    // Remove the original statement toInline.
    containerUnits.remove(toInline);
    // Resolve name collisions.
    LocalNameStandardizer.v().transform(containerB, "ji.lns");
    return newStmts;
}
Also used : CaughtExceptionRef(soot.jimple.CaughtExceptionRef) InvokeStmt(soot.jimple.InvokeStmt) HashMap(java.util.HashMap) AssignStmt(soot.jimple.AssignStmt) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) ArrayList(java.util.ArrayList) Unit(soot.Unit) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) InvokeStmt(soot.jimple.InvokeStmt) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt) RefType(soot.RefType) Hierarchy(soot.Hierarchy) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) IdentityRef(soot.jimple.IdentityRef) Iterator(java.util.Iterator) JimpleBody(soot.jimple.JimpleBody) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody) IdentityStmt(soot.jimple.IdentityStmt) UnitBox(soot.UnitBox) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) Local(soot.Local) Trap(soot.Trap) SootClass(soot.SootClass) ParameterRef(soot.jimple.ParameterRef) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) Value(soot.Value) ReturnStmt(soot.jimple.ReturnStmt)

Aggregations

IdentityRef (soot.jimple.IdentityRef)4 Local (soot.Local)3 RefType (soot.RefType)3 Unit (soot.Unit)3 Value (soot.Value)3 AssignStmt (soot.jimple.AssignStmt)3 IdentityStmt (soot.jimple.IdentityStmt)3 InvokeExpr (soot.jimple.InvokeExpr)3 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 ArrayType (soot.ArrayType)2 Trap (soot.Trap)2 Type (soot.Type)2 UnitBox (soot.UnitBox)2 ValueBox (soot.ValueBox)2 ParameterRef (soot.jimple.ParameterRef)2 ReturnStmt (soot.jimple.ReturnStmt)2 ThisRef (soot.jimple.ThisRef)2 HashMap (java.util.HashMap)1 Iterator (java.util.Iterator)1