use of com.googlecode.dex2jar.ir.stmt.AssignStmt in project dex2jar by pxb1988.
the class RemoveLocalFromSSA method simplePhi.
private boolean simplePhi(List<LabelStmt> phiLabels, Map<Local, Local> toReplace, Set<Value> set) {
boolean changed = false;
if (phiLabels != null) {
for (Iterator<LabelStmt> itLabel = phiLabels.iterator(); itLabel.hasNext(); ) {
LabelStmt labelStmt = itLabel.next();
for (Iterator<AssignStmt> it = labelStmt.phis.iterator(); it.hasNext(); ) {
AssignStmt phi = it.next();
set.addAll(Arrays.asList(phi.getOp2().getOps()));
set.remove(phi.getOp1());
if (set.size() == 1) {
it.remove();
changed = true;
toReplace.put((Local) phi.getOp1(), (Local) set.iterator().next());
}
set.clear();
}
if (labelStmt.phis.size() == 0) {
labelStmt.phis = null;
itLabel.remove();
}
}
}
return changed;
}
use of com.googlecode.dex2jar.ir.stmt.AssignStmt in project dex2jar by pxb1988.
the class RemoveLocalFromSSA method simpleAssign.
private boolean simpleAssign(List<LabelStmt> phiLabels, List<AssignStmt> assignStmtList, Map<Local, Local> toReplace, StmtList stmts) {
Set<Value> usedInPhi = new HashSet<>();
if (phiLabels != null) {
for (LabelStmt labelStmt : phiLabels) {
for (AssignStmt phi : labelStmt.phis) {
usedInPhi.addAll(Arrays.asList(phi.getOp2().getOps()));
}
}
}
boolean changed = false;
for (Iterator<AssignStmt> it = assignStmtList.iterator(); it.hasNext(); ) {
AssignStmt as = it.next();
if (!usedInPhi.contains(as.getOp1())) {
it.remove();
stmts.remove(as);
toReplace.put((Local) as.getOp1(), (Local) as.getOp2());
changed = true;
}
}
return changed;
}
use of com.googlecode.dex2jar.ir.stmt.AssignStmt in project dex2jar by pxb1988.
the class UnSSATransformer method insertAssignPath.
private void insertAssignPath(IrMethod method, Collection<LabelStmt> phiLabels) {
// FIXME the phi in Exception handler is buggy
List<AssignStmt> buff = new ArrayList<>();
for (LabelStmt labelStmt : phiLabels) {
List<AssignStmt> phis = (List<AssignStmt>) labelStmt.phis;
LiveV[] frame = (LiveV[]) labelStmt.frame;
for (Stmt from : labelStmt._cfg_froms) {
if (from.visited) {
// at lease it is reached by cfg
for (AssignStmt phi : phis) {
Local a = (Local) phi.getOp1();
LiveV v = frame[a._ls_index];
Local local = v.stmt2regMap.get(from);
if (local != a) {
buff.add(Stmts.nAssign(a, local));
}
}
insertAssignPath(method.stmts, from, labelStmt, buff);
buff.clear();
}
}
}
}
use of com.googlecode.dex2jar.ir.stmt.AssignStmt in project dex2jar by pxb1988.
the class ZeroTransformer method transformReportChanged.
@Override
public boolean transformReportChanged(IrMethod method) {
boolean changed = false;
List<AssignStmt> assignStmtList = new ArrayList<>();
for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {
if (p.st == Stmt.ST.ASSIGN) {
AssignStmt as = (AssignStmt) p;
if (as.getOp1().vt == Value.VT.LOCAL && as.getOp2().vt == Value.VT.CONSTANT) {
Constant cst = (Constant) as.getOp2();
Object value = cst.value;
if (value instanceof Number && !((value instanceof Long) || (value instanceof Double))) {
int v = ((Number) value).intValue();
if (v == 0 || v == 1) {
assignStmtList.add(as);
}
}
}
}
}
if (assignStmtList.size() == 0) {
return false;
}
List<LabelStmt> phiLabels = method.phiLabels;
if (phiLabels != null) {
for (AssignStmt as : assignStmtList) {
Local local = (Local) as.getOp1();
boolean first = true;
for (LabelStmt labelStmt : phiLabels) {
for (AssignStmt phi : labelStmt.phis) {
Value[] vs = phi.getOp2().getOps();
for (int i = 0; i < vs.length; i++) {
Value v = vs[i];
if (v == local) {
if (first) {
first = false;
} else {
Local nLocal = Exprs.nLocal(-1);
method.locals.add(nLocal);
changed = true;
method.stmts.insertBefore(as, Stmts.nAssign(nLocal, as.getOp2().clone()));
vs[i] = nLocal;
}
}
}
}
}
}
}
return changed;
}
use of com.googlecode.dex2jar.ir.stmt.AssignStmt in project dex2jar by pxb1988.
the class FillArrayTransformer method replace.
private void replace(IrMethod method, Map<Local, ArrayObject> arraySizes) {
final List<FilledArrayExpr> filledArrayExprs = new ArrayList<>();
for (Map.Entry<Local, ArrayObject> e : arraySizes.entrySet()) {
final Local local0 = e.getKey();
final ArrayObject ao = e.getValue();
final Value[] t = new Value[ao.size];
for (Iterator<Stmt> it = ao.putItem.iterator(); it.hasNext(); ) {
Stmt p = it.next();
if (p.st == Stmt.ST.FILL_ARRAY_DATA) {
Local local = (Local) p.getOp1();
if (local == local0) {
Object vs = ((Constant) p.getOp2()).value;
int endPos = Array.getLength(vs);
for (int j = 0; j < endPos; j++) {
t[j] = Exprs.nConstant(Array.get(vs, j));
}
}
} else {
// ASSIGN
ArrayExpr ae = (ArrayExpr) p.getOp1();
Local local = (Local) ae.getOp1();
if (local == local0) {
int idx = ((Number) ((Constant) ae.getOp2()).value).intValue();
Value op2 = p.getOp2();
if (op2.vt != Value.VT.LOCAL && op2.vt != Value.VT.CONSTANT) {
Local n = new Local(-1);
method.locals.add(n);
method.stmts.insertBefore(p, Stmts.nAssign(n, op2));
op2 = n;
}
t[idx] = op2;
}
}
}
// for code
// b=new Object[1]
// b[0]=null
// a =new Object[1]
// a =b;
// use(a)
// if a is replace before b, the code
// b=new Object[1]
// b[0]=null
// use(new Object[]{b})
// the used stmt of b is outdated, so we have to search pre replaced arrays
method.locals.remove(local0);
method.stmts.remove(ao.init);
for (Stmt p : ao.putItem) {
method.stmts.remove(p);
}
Cfg.TravelCallBack tcb = new Cfg.TravelCallBack() {
@Override
public Value onAssign(Local v, AssignStmt as) {
return v;
}
@Override
public Value onUse(Local v) {
if (local0 == v) {
FilledArrayExpr fae = Exprs.nFilledArray(ao.type, t);
filledArrayExprs.add(fae);
return fae;
}
return v;
}
};
if (ao.used.size() == 1) {
Stmt stmt = ao.used.get(0);
if (method.stmts.contains(stmt)) {
// the stmt is not removed by pre array replacement
Cfg.travelMod(stmt, tcb, false);
} else {
int size = filledArrayExprs.size();
for (int i = 0; i < size; i++) {
Cfg.travelMod(filledArrayExprs.get(i), tcb);
}
}
} else if (ao.used.size() == 0) {
// the array is never used, ignore
} else {
throw new RuntimeException("array is used multiple times");
}
}
}
Aggregations