com.googlecode.dex2jar.ir.ts.EndRemover Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle Show documentation
Show all versions of gradle Show documentation
fakeradnroid gradle builder
package com.googlecode.dex2jar.ir.ts;
import com.googlecode.dex2jar.ir.IrMethod;
import com.googlecode.dex2jar.ir.LabelAndLocalMapper;
import com.googlecode.dex2jar.ir.Trap;
import com.googlecode.dex2jar.ir.expr.Local;
import com.googlecode.dex2jar.ir.stmt.*;
import com.googlecode.dex2jar.ir.stmt.Stmt.ST;
import java.util.ArrayList;
/**
* Try to clean following between a {@link Trap}
*
* - Move {@link Stmt}s outside a {@link Trap} if {@link Stmt}s are not throw
* - Remove {@link Trap} if all {@link Stmt}s are not throw
* - ...;GOTO L2; ... ; L2: ; return; => ...;return ; ... ; L2: ; return;
*
*
* @author bob
*
*/
public class EndRemover implements Transformer {
private static final LabelAndLocalMapper keepLocal = new LabelAndLocalMapper() {
@Override
public Local map(Local local) {
return local;
}
};
@Override
public void transform(IrMethod irMethod) {
for (Trap trap : new ArrayList(irMethod.traps)) {// copy the list and we can remove one from original list
LabelStmt start = null;
boolean removeTrap = true;
for (Stmt p = trap.start.getNext(); p != null && p != trap.end;) {
boolean notThrow = Cfg.notThrow(p);
if (!notThrow) {
start = null;
p = p.getNext();
removeTrap = false;
continue;
}
switch (p.st) {
case LABEL:
if (start != null) {
move4Label(irMethod.stmts, start, p.getPre(), (LabelStmt) p);
}
start = (LabelStmt) p;
p = p.getNext();
break;
case GOTO:
case RETURN:
case RETURN_VOID:
if (start != null) {
Stmt tmp = p.getNext();
move4End(irMethod.stmts, start, p);
start = null;
p = tmp;
} else {
p = p.getNext();
}
break;
default:
p = p.getNext();
}
}
if (removeTrap) {
irMethod.traps.remove(trap);
}
}
StmtList stmts = irMethod.stmts;
for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) {
if (p.st == ST.GOTO) {
LabelStmt target = ((GotoStmt) p).target;
Stmt next = target.getNext();
if (next != null && (next.st == ST.RETURN || next.st == ST.RETURN_VOID)) {
Stmt nnext = next.clone(keepLocal);
stmts.insertAfter(p, nnext);
stmts.remove(p);
p = nnext;
}
}
}
}
private void move4Label(StmtList stmts, LabelStmt start, Stmt end, LabelStmt label) {
move4End(stmts, start, end);
stmts.insertAfter(end, Stmts.nGoto(label));
}
private void move4End(StmtList stmts, LabelStmt start, Stmt end) {
Stmt g1 = Stmts.nGoto(start);
stmts.insertBefore(start, g1);
Stmt last = stmts.getLast();
while (last.st == ST.GOTO && ((GotoStmt) last).target == start) {
stmts.remove(last);
last = stmts.getLast();
}
stmts.move(start, end, last);
}
}