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);
}
}
}
}
}
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;
}
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);
}
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;
}
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);
}
Aggregations