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