use of com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack in project dex2jar by pxb1988.
the class SSATransformer method prepare.
private boolean prepare(final IrMethod method) {
int index = Cfg.reIndexLocal(method);
final int[] readCounts = new int[index];
final int[] writeCounts = new int[index];
Cfg.travel(method.stmts, new TravelCallBack() {
@Override
public Value onAssign(Local v, AssignStmt as) {
writeCounts[v._ls_index]++;
return v;
}
@Override
public Value onUse(Local v) {
readCounts[v._ls_index]++;
return v;
}
}, true);
boolean needTravel = false;
boolean needSSAAnalyze = false;
index = 0;
List<Local> oldLocals = method.locals;
List<Local> locals = new ArrayList<>(oldLocals);
oldLocals.clear();
for (Local local : locals) {
int idx = local._ls_index;
int read = readCounts[idx];
int write = writeCounts[idx];
if (read > 0 && write == 0) {
// TODO if we need throw exception ?
// or the code is dead?
}
if (read == 0 && write == 0) {
// ignore the local
} else {
if (write <= 1) {
// no phi require
local._ls_index = -1;
oldLocals.add(local);
} else if (read == 0) {
local._ls_index = -2;
needTravel = true;
// we are going to duplicate each usage of the local and add to method.locals,
// so not add the original local to method.locals
} else {
needSSAAnalyze = true;
local._ls_index = index++;
oldLocals.add(local);
}
}
}
if (needSSAAnalyze || needTravel) {
Cfg.travelMod(method.stmts, new TravelCallBack() {
@Override
public Value onAssign(Local v, AssignStmt as) {
if (v._ls_index == -1) {
return v;
} else if (v._ls_index == -2) {
Local n = (Local) v.clone();
method.locals.add(n);
return n;
}
// others
return v.clone();
}
@Override
public Value onUse(Local v) {
if (v._ls_index == -1) {
return v;
}
return v.clone();
}
}, true);
}
return needSSAAnalyze;
}
use of com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack in project dex2jar by pxb1988.
the class SSATransformer method replaceLocalsWithSSA.
private void replaceLocalsWithSSA(final IrMethod method) {
final List<Local> locals = method.locals;
locals.clear();
StmtList stmts = method.stmts;
TravelCallBack tcb = new TravelCallBack() {
@Override
public Value onAssign(Local a, AssignStmt as) {
if (a._ls_index < 0) {
locals.add(a);
return a;
}
SSAValue lsv = (SSAValue) a.tag;
Local b = lsv.local;
locals.add(b);
return b;
}
@Override
public Value onUse(Local a) {
if (a._ls_index < 0) {
return a;
}
SSAValue lsv = (SSAValue) a.tag;
Local b = lsv.local;
return b;
}
};
Set<Value> froms = new HashSet<>();
List<LabelStmt> phiLabels = new ArrayList<>();
// 2. we are looking for Phis and insert Phi node to the code
for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) {
if (p.st == ST.LABEL) {
LabelStmt labelStmt = (LabelStmt) p;
List<AssignStmt> phis = null;
SSAValue[] frame = (SSAValue[]) p.frame;
if (frame != null) {
for (SSAValue v : frame) {
if (v == null || !v.used) {
continue;
}
if (v.parent != null) {
froms.add(v.parent.local);
}
if (v.otherParents != null) {
for (SSAValue parent : v.otherParents) {
froms.add(parent.local);
}
}
froms.remove(v.local);
if (phis == null) {
phis = new ArrayList<>();
}
locals.add(v.local);
phis.add(Stmts.nAssign(v.local, Exprs.nPhi(froms.toArray(new Value[froms.size()]))));
froms.clear();
}
}
labelStmt.phis = phis;
if (phis != null) {
phiLabels.add(labelStmt);
}
} else {
Cfg.travelMod(p, tcb, true);
}
p.frame = null;
}
if (phiLabels.size() > 0) {
method.phiLabels = phiLabels;
}
}
Aggregations