Search in sources :

Example 16 with UnitBox

use of soot.UnitBox in project soot by Sable.

the class AsmMethodSource method emitTraps.

private void emitTraps() {
    Chain<Trap> traps = body.getTraps();
    SootClass throwable = Scene.v().getSootClass("java.lang.Throwable");
    Map<LabelNode, Iterator<UnitBox>> handlers = new HashMap<LabelNode, Iterator<UnitBox>>(tryCatchBlocks.size());
    for (TryCatchBlockNode tc : tryCatchBlocks) {
        UnitBox start = Jimple.v().newStmtBox(null);
        UnitBox end = Jimple.v().newStmtBox(null);
        Iterator<UnitBox> hitr = handlers.get(tc.handler);
        if (hitr == null) {
            hitr = trapHandlers.get(tc.handler).iterator();
            handlers.put(tc.handler, hitr);
        }
        UnitBox handler = hitr.next();
        SootClass cls = tc.type == null ? throwable : Scene.v().getSootClass(AsmUtil.toQualifiedName(tc.type));
        Trap trap = Jimple.v().newTrap(cls, start, end, handler);
        traps.add(trap);
        labels.put(tc.start, start);
        labels.put(tc.end, end);
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) TryCatchBlockNode(org.objectweb.asm.tree.TryCatchBlockNode) UnitBox(soot.UnitBox) HashMap(java.util.HashMap) Iterator(java.util.Iterator) Trap(soot.Trap) SootClass(soot.SootClass)

Example 17 with UnitBox

use of soot.UnitBox in project soot by Sable.

the class AsmMethodSource method convertTableSwitchInsn.

private void convertTableSwitchInsn(TableSwitchInsnNode insn) {
    StackFrame frame = getFrame(insn);
    if (units.containsKey(insn)) {
        frame.mergeIn(pop());
        return;
    }
    Operand key = popImmediate();
    UnitBox dflt = Jimple.v().newStmtBox(null);
    List<UnitBox> targets = new ArrayList<UnitBox>(insn.labels.size());
    labels.put(insn.dflt, dflt);
    for (LabelNode ln : insn.labels) {
        UnitBox box = Jimple.v().newStmtBox(null);
        targets.add(box);
        labels.put(ln, box);
    }
    TableSwitchStmt tss = Jimple.v().newTableSwitchStmt(key.stackOrValue(), insn.min, insn.max, targets, dflt);
    key.addBox(tss.getKeyBox());
    frame.in(key);
    frame.boxes(tss.getKeyBox());
    setUnit(insn, tss);
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) TableSwitchStmt(soot.jimple.TableSwitchStmt) UnitBox(soot.UnitBox) ArrayList(java.util.ArrayList)

Example 18 with UnitBox

use of soot.UnitBox in project soot by Sable.

the class CastAndReturnInliner method internalTransform.

@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
    Iterator<Unit> it = body.getUnits().snapshotIterator();
    while (it.hasNext()) {
        Unit u = it.next();
        if (u instanceof GotoStmt) {
            GotoStmt gtStmt = (GotoStmt) u;
            if (gtStmt.getTarget() instanceof AssignStmt) {
                AssignStmt assign = (AssignStmt) gtStmt.getTarget();
                if (assign.getRightOp() instanceof CastExpr) {
                    CastExpr ce = (CastExpr) assign.getRightOp();
                    // We have goto that ends up at a cast statement
                    Unit nextStmt = body.getUnits().getSuccOf(assign);
                    if (nextStmt instanceof ReturnStmt) {
                        ReturnStmt retStmt = (ReturnStmt) nextStmt;
                        if (retStmt.getOp() == assign.getLeftOp()) {
                            // We need to replace the GOTO with the return
                            ReturnStmt newStmt = (ReturnStmt) retStmt.clone();
                            newStmt.setOp(ce.getOp());
                            for (Trap t : body.getTraps()) for (UnitBox ubox : t.getUnitBoxes()) if (ubox.getUnit() == gtStmt)
                                ubox.setUnit(newStmt);
                            while (!gtStmt.getBoxesPointingToThis().isEmpty()) gtStmt.getBoxesPointingToThis().get(0).setUnit(newStmt);
                            body.getUnits().swapWith(gtStmt, newStmt);
                        }
                    }
                }
            }
        }
    }
}
Also used : UnitBox(soot.UnitBox) AssignStmt(soot.jimple.AssignStmt) GotoStmt(soot.jimple.GotoStmt) CastExpr(soot.jimple.CastExpr) Trap(soot.Trap) Unit(soot.Unit) ReturnStmt(soot.jimple.ReturnStmt)

Example 19 with UnitBox

use of soot.UnitBox in project soot by Sable.

the class GroupIntPair method emitMethodBody.

@Override
protected void emitMethodBody(SootMethod method) {
    if (Options.v().time())
        Timers.v().buildJasminTimer.end();
    Body activeBody = method.getActiveBody();
    if (!(activeBody instanceof BafBody)) {
        if (activeBody instanceof JimpleBody) {
            if (Options.v().verbose()) {
                logger.debug("Was expecting Baf body for " + method + " but found a Jimple body. Will convert body to Baf on the fly.");
            }
            activeBody = PackManager.v().convertJimpleBodyToBaf(method);
        } else
            throw new RuntimeException("method: " + method.getName() + " has an invalid active body!");
    }
    BafBody body = (BafBody) activeBody;
    if (body == null)
        throw new RuntimeException("method: " + method.getName() + " has no active body!");
    if (Options.v().time())
        Timers.v().buildJasminTimer.start();
    Chain<Unit> instList = body.getUnits();
    int stackLimitIndex = -1;
    subroutineToReturnAddressSlot = new HashMap<Unit, Integer>(10, 0.7f);
    // Determine the unitToLabel map
    {
        unitToLabel = new HashMap<Unit, String>(instList.size() * 2 + 1, 0.7f);
        labelCount = 0;
        for (UnitBox uBox : body.getUnitBoxes(true)) {
            // Assign a label for each statement reference
            {
                InstBox box = (InstBox) uBox;
                if (!unitToLabel.containsKey(box.getUnit()))
                    unitToLabel.put(box.getUnit(), "label" + labelCount++);
            }
        }
    }
    // Emit the exceptions, recording the Units at the beginning
    // of handlers so that later on we can recognize blocks that
    // begin with an exception on the stack.
    Set<Unit> handlerUnits = new ArraySet<Unit>(body.getTraps().size());
    {
        for (Trap trap : body.getTraps()) {
            handlerUnits.add(trap.getHandlerUnit());
            if (trap.getBeginUnit() != trap.getEndUnit()) {
                emit(".catch " + slashify(trap.getException().getName()) + " from " + unitToLabel.get(trap.getBeginUnit()) + " to " + unitToLabel.get(trap.getEndUnit()) + " using " + unitToLabel.get(trap.getHandlerUnit()));
            }
        }
    }
    // Determine where the locals go
    {
        int localCount = 0;
        int[] paramSlots = new int[method.getParameterCount()];
        int thisSlot = 0;
        Set<Local> assignedLocals = new HashSet<Local>();
        localToSlot = new HashMap<Local, Integer>(body.getLocalCount() * 2 + 1, 0.7f);
        // assignColorsToLocals(body);
        // Determine slots for 'this' and parameters
        {
            if (!method.isStatic()) {
                thisSlot = 0;
                localCount++;
            }
            for (int i = 0; i < method.getParameterCount(); i++) {
                paramSlots[i] = localCount;
                localCount += sizeOfType(method.getParameterType(i));
            }
        }
        // Handle identity statements
        {
            for (Unit u : instList) {
                Inst s = (Inst) u;
                if (s instanceof IdentityInst && ((IdentityInst) s).getLeftOp() instanceof Local) {
                    Local l = (Local) ((IdentityInst) s).getLeftOp();
                    IdentityRef identity = (IdentityRef) ((IdentityInst) s).getRightOp();
                    int slot = 0;
                    if (identity instanceof ThisRef) {
                        if (method.isStatic())
                            throw new RuntimeException("Attempting to use 'this' in static method");
                        slot = thisSlot;
                    } else if (identity instanceof ParameterRef)
                        slot = paramSlots[((ParameterRef) identity).getIndex()];
                    else {
                        // Exception ref. Skip over this
                        continue;
                    }
                    localToSlot.put(l, new Integer(slot));
                    assignedLocals.add(l);
                }
            }
        }
        // Assign the rest of the locals
        {
            for (Local local : body.getLocals()) {
                if (assignedLocals.add(local)) {
                    localToSlot.put(local, new Integer(localCount));
                    localCount += sizeOfType(local.getType());
                }
            }
            if (!Modifier.isNative(method.getModifiers()) && !Modifier.isAbstract(method.getModifiers())) {
                emit("    .limit stack ?");
                stackLimitIndex = code.size() - 1;
                emit("    .limit locals " + localCount);
            }
        }
    }
    // Emit code in one pass
    {
        isEmittingMethodCode = true;
        maxStackHeight = 0;
        isNextGotoAJsr = false;
        for (Unit u : instList) {
            Inst s = (Inst) u;
            if (unitToLabel.containsKey(s))
                emit(unitToLabel.get(s) + ":");
            // emit this statement
            {
                emitInst(s);
            }
        }
        isEmittingMethodCode = false;
        // calculate max stack height
        {
            maxStackHeight = 0;
            if (activeBody.getUnits().size() != 0) {
                BlockGraph blockGraph = new BriefBlockGraph(activeBody);
                List<Block> blocks = blockGraph.getBlocks();
                if (blocks.size() != 0) {
                    // set the stack height of the entry points
                    List<Block> entryPoints = ((DirectedGraph<Block>) blockGraph).getHeads();
                    for (Block entryBlock : entryPoints) {
                        Integer initialHeight;
                        if (handlerUnits.contains(entryBlock.getHead())) {
                            initialHeight = new Integer(1);
                        } else {
                            initialHeight = new Integer(0);
                        }
                        if (blockToStackHeight == null) {
                            blockToStackHeight = new HashMap<Block, Integer>();
                        }
                        blockToStackHeight.put(entryBlock, initialHeight);
                        if (blockToLogicalStackHeight == null) {
                            blockToLogicalStackHeight = new HashMap<Block, Integer>();
                        }
                        blockToLogicalStackHeight.put(entryBlock, initialHeight);
                    }
                    // entryPoints list as roots
                    for (Block nextBlock : entryPoints) {
                        calculateStackHeight(nextBlock);
                        calculateLogicalStackHeightCheck(nextBlock);
                    }
                }
            }
        }
        if (!Modifier.isNative(method.getModifiers()) && !Modifier.isAbstract(method.getModifiers()))
            code.set(stackLimitIndex, "    .limit stack " + maxStackHeight);
    }
    // emit code attributes
    {
        for (Tag t : body.getTags()) {
            if (t instanceof JasminAttribute) {
                emit(".code_attribute " + t.getName() + " \"" + ((JasminAttribute) t).getJasminValue(unitToLabel) + "\"");
            }
        }
    }
}
Also used : HashSet(java.util.HashSet) ArraySet(soot.util.ArraySet) Set(java.util.Set) HashMap(java.util.HashMap) Unit(soot.Unit) BriefBlockGraph(soot.toolkits.graph.BriefBlockGraph) BlockGraph(soot.toolkits.graph.BlockGraph) BriefBlockGraph(soot.toolkits.graph.BriefBlockGraph) DirectedGraph(soot.toolkits.graph.DirectedGraph) Body(soot.Body) UnitBox(soot.UnitBox) ArraySet(soot.util.ArraySet) Local(soot.Local) Trap(soot.Trap) JasminAttribute(soot.tagkit.JasminAttribute) Block(soot.toolkits.graph.Block) Tag(soot.tagkit.Tag) LineNumberTag(soot.tagkit.LineNumberTag)

Example 20 with UnitBox

use of soot.UnitBox in project soot by Sable.

the class Walker method outACaseStmt.

/*
	 * case_label = {constant} case minus? integer_constant | {default} default;
	 */
/*
	 * case_stmt = case_label colon goto_stmt;
	 */
public void outACaseStmt(ACaseStmt node) {
    String labelName = (String) mProductions.removeLast();
    UnitBox box = Jimple.v().newStmtBox(null);
    addBoxToPatch(labelName, box);
    Value labelValue = null;
    if (node.getCaseLabel() instanceof AConstantCaseLabel)
        labelValue = (Value) mProductions.removeLast();
    // if labelValue == null, this is the default label.
    if (labelValue == null)
        mProductions.addLast(box);
    else {
        Object[] valueTargetPair = new Object[2];
        valueTargetPair[0] = labelValue;
        valueTargetPair[1] = box;
        mProductions.addLast(valueTargetPair);
    }
}
Also used : UnitBox(soot.UnitBox) Value(soot.Value)

Aggregations

UnitBox (soot.UnitBox)23 Unit (soot.Unit)16 ArrayList (java.util.ArrayList)9 Trap (soot.Trap)9 Value (soot.Value)8 HashMap (java.util.HashMap)5 Local (soot.Local)5 Iterator (java.util.Iterator)4 LabelNode (org.objectweb.asm.tree.LabelNode)4 GotoStmt (soot.jimple.GotoStmt)4 IntConstant (soot.jimple.IntConstant)4 ReturnStmt (soot.jimple.ReturnStmt)4 HashSet (java.util.HashSet)3 List (java.util.List)3 CaughtExceptionRef (soot.jimple.CaughtExceptionRef)3 IdentityStmt (soot.jimple.IdentityStmt)3 IfStmt (soot.jimple.IfStmt)3 ParameterRef (soot.jimple.ParameterRef)3 Stmt (soot.jimple.Stmt)3 ThisRef (soot.jimple.ThisRef)3