use of com.googlecode.dex2jar.ir.Trap in project dex2jar by pxb1988.
the class DeadCodeTransformer method transform.
@Override
public void transform(IrMethod method) {
Cfg.createCFG(method);
Cfg.dfsVisit(method, null);
if (method.traps != null) {
for (Iterator<Trap> it = method.traps.iterator(); it.hasNext(); ) {
Trap t = it.next();
boolean allNotThrow = true;
for (Stmt p = t.start; p != t.end; p = p.getNext()) {
if (p.visited && Cfg.isThrow(p)) {
allNotThrow = false;
break;
}
}
if (allNotThrow) {
it.remove();
continue;
}
boolean allNotVisited = true;
boolean allVisited = true;
for (LabelStmt labelStmt : t.handlers) {
if (labelStmt.visited) {
allNotVisited = false;
} else {
allVisited = false;
}
}
if (allNotVisited) {
it.remove();
} else {
// keep start and end
t.start.visited = true;
t.end.visited = true;
if (!allVisited) {
// part visited
List<String> types = new ArrayList<>(t.handlers.length);
List<LabelStmt> labelStmts = new ArrayList<>(t.handlers.length);
for (int i = 0; i < t.handlers.length; i++) {
labelStmts.add(t.handlers[i]);
types.add(t.types[i]);
}
t.handlers = labelStmts.toArray(new LabelStmt[labelStmts.size()]);
t.types = types.toArray(new String[types.size()]);
}
}
}
}
Set<Local> definedLocals = new HashSet<>();
for (Iterator<Stmt> it = method.stmts.iterator(); it.hasNext(); ) {
Stmt p = it.next();
if (!p.visited) {
it.remove();
continue;
}
if (p.st == Stmt.ST.ASSIGN || p.st == Stmt.ST.IDENTITY) {
if (p.getOp1().vt == Value.VT.LOCAL) {
definedLocals.add((Local) p.getOp1());
}
}
}
if (method.phiLabels != null) {
for (Iterator<LabelStmt> it = method.phiLabels.iterator(); it.hasNext(); ) {
LabelStmt labelStmt = it.next();
if (!labelStmt.visited) {
it.remove();
continue;
}
if (labelStmt.phis != null) {
for (AssignStmt phi : labelStmt.phis) {
definedLocals.add((Local) phi.getOp1());
}
}
}
}
method.locals.clear();
method.locals.addAll(definedLocals);
Set<Value> tmp = new HashSet<>();
if (method.phiLabels != null) {
for (Iterator<LabelStmt> it = method.phiLabels.iterator(); it.hasNext(); ) {
LabelStmt labelStmt = it.next();
if (labelStmt.phis != null) {
for (AssignStmt phi : labelStmt.phis) {
PhiExpr phiExpr = (PhiExpr) phi.getOp2();
boolean needRebuild = false;
for (Value v : phiExpr.getOps()) {
if (!definedLocals.contains(v)) {
needRebuild = true;
break;
}
}
if (needRebuild) {
for (Value v : phiExpr.getOps()) {
if (definedLocals.contains(v)) {
tmp.add(v);
}
}
phiExpr.setOps(tmp.toArray(new Value[tmp.size()]));
tmp.clear();
}
}
}
}
}
}
use of com.googlecode.dex2jar.ir.Trap in project dex2jar by pxb1988.
the class Cfg method createCFG.
public static void createCFG(IrMethod jm) {
createCfgWithoutEx(jm);
for (Trap t : jm.traps) {
for (Stmt s = t.start; s != t.end; s = s.getNext()) {
if (isThrow(s)) {
Set<LabelStmt> hs = s.exceptionHandlers;
if (hs == null) {
hs = new TreeSet<>(jm.stmts);
s.exceptionHandlers = hs;
}
for (LabelStmt handler : t.handlers) {
link(s, handler);
hs.add(handler);
}
}
}
}
}
use of com.googlecode.dex2jar.ir.Trap in project dex2jar by pxb1988.
the class CleanLabel method addTrap.
private void addTrap(List<Trap> traps, Set<LabelStmt> labels) {
if (traps != null) {
for (Trap trap : traps) {
labels.add(trap.start);
labels.add(trap.end);
for (LabelStmt h : trap.handlers) {
labels.add(h);
}
}
}
}
use of com.googlecode.dex2jar.ir.Trap in project dex2jar by pxb1988.
the class UnSSATransformerTransformerTest method test07PhiInHandler.
@Test
public void test07PhiInHandler() {
initMethod(true, "I");
Local a1 = addLocal("a1");
Local a2 = addLocal("a2");
Local a = addLocal("a");
Local ex = addLocal("ex");
addStmt(Stmts.nAssign(a1, nInt(1)));
LabelStmt L0 = newLabel();
LabelStmt L2 = newLabel();
LabelStmt L3 = newLabel();
addStmt(L0);
addStmt(Stmts.nVoidInvoke(Exprs.nInvokeStatic(new Value[0], "La;", "m", new String[0], "V")));
addStmt(Stmts.nAssign(a2, nInt(2)));
addStmt(Stmts.nVoidInvoke(Exprs.nInvokeStatic(new Value[0], "La;", "m", new String[0], "V")));
addStmt(L2);
addStmt(Stmts.nReturn(a2));
addStmt(L3);
Stmt ref = addStmt(Stmts.nIdentity(ex, Exprs.nExceptionRef("Ljava/lang/Exception;")));
attachPhi(L3, Stmts.nAssign(a, nPhi(a1, a2)));
addStmt(Stmts.nVoidInvoke(Exprs.nInvokeStatic(new Value[] { a1 }, "La;", "m", new String[] { "I" }, "V")));
addStmt(Stmts.nReturn(a));
method.traps.add(new Trap(L0, L2, new LabelStmt[] { L3 }, new String[] { "Ljava/lang/Exception" }));
transform();
Assert.assertTrue("the fix assign should insert after x=@ExceptionRef", L3.getNext() == ref);
}
use of com.googlecode.dex2jar.ir.Trap in project dex2jar by pxb1988.
the class IR2JConverter method reBuildTryCatchBlocks.
/**
* an empty try-catch block will cause other crash, we check this by finding non-label stmts between
* {@link Trap#start} and {@link Trap#end}. if find we add the try-catch or we drop the try-catch.
*
* @param ir
* @param asm
*/
private void reBuildTryCatchBlocks(IrMethod ir, MethodVisitor asm) {
for (Trap trap : ir.traps) {
boolean needAdd = false;
for (Stmt p = trap.start.getNext(); p != null && p != trap.end; p = p.getNext()) {
if (p.st != ST.LABEL) {
needAdd = true;
break;
}
}
if (needAdd) {
for (int i = 0; i < trap.handlers.length; i++) {
String type = trap.types[i];
asm.visitTryCatchBlock((Label) trap.start.tag, (Label) trap.end.tag, (Label) trap.handlers[i].tag, type == null ? null : toInternal(type));
}
}
}
}
Aggregations