Search in sources :

Example 81 with Unit

use of soot.Unit 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 82 with Unit

use of soot.Unit in project soot by Sable.

the class BafASMBackend method getMinJavaVersion.

/*
	 * (non-Javadoc)
	 * 
	 * @see soot.AbstractASMBackend#getMinJavaVersion(soot.SootMethod)
	 */
@Override
protected int getMinJavaVersion(SootMethod method) {
    final BafBody body = getBafBody(method);
    int minVersion = Options.java_version_1_1;
    // http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/classfile/classFileParser.cpp
    if (method.getDeclaringClass().isInterface()) {
        if (method.isStatic() && !method.isStaticInitializer()) {
            return Options.java_version_1_8;
        }
    }
    for (Unit u : body.getUnits()) {
        if (u instanceof DynamicInvokeInst) {
            return Options.java_version_1_7;
        }
        if (u instanceof PushInst) {
            if (((PushInst) u).getConstant() instanceof ClassConstant) {
                minVersion = Options.java_version_1_5;
            }
        }
    }
    return minVersion;
}
Also used : Unit(soot.Unit) ClassConstant(soot.jimple.ClassConstant)

Example 83 with Unit

use of soot.Unit 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)

Example 84 with Unit

use of soot.Unit in project soot by Sable.

the class LoopFinder method getLoopBodyFor.

private List<Stmt> getLoopBodyFor(Stmt header, Stmt node) {
    ArrayList<Stmt> loopBody = new ArrayList<Stmt>();
    Stack<Unit> stack = new Stack<Unit>();
    loopBody.add(header);
    stack.push(node);
    while (!stack.isEmpty()) {
        Stmt next = (Stmt) stack.pop();
        if (!loopBody.contains(next)) {
            // add next to loop body
            loopBody.add(0, next);
            // put all preds of next on stack
            Iterator<Unit> it = g.getPredsOf(next).iterator();
            while (it.hasNext()) {
                stack.push(it.next());
            }
        }
    }
    assert (node == header && loopBody.size() == 1) || loopBody.get(loopBody.size() - 2) == node;
    assert loopBody.get(loopBody.size() - 1) == header;
    return loopBody;
}
Also used : ArrayList(java.util.ArrayList) Unit(soot.Unit) Stmt(soot.jimple.Stmt) Stack(java.util.Stack)

Example 85 with Unit

use of soot.Unit in project soot by Sable.

the class Main method main.

/**
 * @param args
 */
public static void main(String[] args) {
    PackManager.v().getPack("wjtp").add(new Transform("wjtp.ifds", new SceneTransformer() {

        protected void internalTransform(String phaseName, @SuppressWarnings("rawtypes") Map options) {
            IFDSTabulationProblem<Unit, ?, SootMethod, InterproceduralCFG<Unit, SootMethod>> problem = new IFDSPossibleTypes(new JimpleBasedInterproceduralCFG());
            @SuppressWarnings({ "rawtypes", "unchecked" }) JimpleIFDSSolver<?, InterproceduralCFG<Unit, SootMethod>> solver = new JimpleIFDSSolver(problem);
            solver.solve();
        }
    }));
    soot.Main.main(args);
}
Also used : JimpleBasedInterproceduralCFG(soot.jimple.toolkits.ide.icfg.JimpleBasedInterproceduralCFG) InterproceduralCFG(heros.InterproceduralCFG) JimpleBasedInterproceduralCFG(soot.jimple.toolkits.ide.icfg.JimpleBasedInterproceduralCFG) Unit(soot.Unit) SceneTransformer(soot.SceneTransformer) IFDSPossibleTypes(soot.jimple.toolkits.ide.exampleproblems.IFDSPossibleTypes) SootMethod(soot.SootMethod) Transform(soot.Transform) Map(java.util.Map)

Aggregations

Unit (soot.Unit)240 Local (soot.Local)77 Stmt (soot.jimple.Stmt)77 Value (soot.Value)74 ArrayList (java.util.ArrayList)65 AssignStmt (soot.jimple.AssignStmt)58 SootMethod (soot.SootMethod)47 Body (soot.Body)37 InvokeStmt (soot.jimple.InvokeStmt)35 Type (soot.Type)34 HashSet (java.util.HashSet)33 ValueBox (soot.ValueBox)33 InvokeExpr (soot.jimple.InvokeExpr)33 Trap (soot.Trap)32 RefType (soot.RefType)30 IdentityStmt (soot.jimple.IdentityStmt)28 HashMap (java.util.HashMap)27 IfStmt (soot.jimple.IfStmt)27 DefinitionStmt (soot.jimple.DefinitionStmt)25 List (java.util.List)23