use of com.googlecode.dex2jar.ir.expr.Local 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;
}
}
use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.
the class AggTransformer method transformReportChanged.
@Override
public boolean transformReportChanged(IrMethod method) {
boolean changed = false;
Set<Stmt> locationSensitiveStmts = new HashSet<>();
// 1. merge location Insensitive stmts
changed = simpleMergeLocals(method, changed, locationSensitiveStmts);
if (locationSensitiveStmts.size() == 0) {
return changed;
}
ReplaceX replaceX = new ReplaceX();
Queue<Stmt> q = new UniqueQueue<>();
q.addAll(locationSensitiveStmts);
// 2. merge location sensitive stmts
while (!q.isEmpty()) {
Stmt stmt = q.poll();
Local local = (Local) stmt.getOp1();
Stmt next = stmt.getNext();
switch(next.st) {
case LABEL:
case GOTO:
case IDENTITY:
case FILL_ARRAY_DATA:
case NOP:
case RETURN_VOID:
continue;
default:
}
try {
localCanExecFirst(local, next);
// impossible here
throw new RuntimeException();
} catch (MergeResult e) {
if (e == SUCCESS) {
replaceX.local = local;
replaceX.replaceWith = stmt.getOp2();
method.locals.remove(local);
method.stmts.remove(stmt);
Cfg.travelMod(next, replaceX, false);
Stmt pre = next.getPre();
if (pre != null && locationSensitiveStmts.contains(pre)) {
q.add(pre);
}
}
}
}
return changed;
}
use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.
the class AggTransformer method modReplace.
private void modReplace(Map<Local, Value> toReplace, Cfg.TravelCallBack tcb) {
for (Map.Entry<Local, Value> e : toReplace.entrySet()) {
Value v = e.getValue();
if (v.vt == Value.VT.LOCAL) {
while (true) {
Value v2 = toReplace.get(v);
if (v2 == null) {
break;
}
v = v2;
if (v.vt != Value.VT.LOCAL) {
break;
}
}
e.setValue(v);
} else {
Cfg.travelMod(v, tcb);
}
}
}
use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.
the class ArrayNullPointerTransformer method replaceNPE.
private void replaceNPE(StmtList stmts, List<Local> locals, Stmt p) {
List<Value> values = new ArrayList<Value>();
switch(p.et) {
case E1:
tryAdd(((E1Stmt) p).op.trim(), values);
break;
case E2:
E2Stmt e2 = (E2Stmt) p;
switch(e2.op1.trim().vt) {
case LOCAL:
tryAdd(e2.op2.trim(), values);
break;
case ARRAY:
ArrayExpr ae = (ArrayExpr) e2.op1.trim();
if (tryAdd(ae.op1.trim(), values)) {
if (tryAdd(ae.op2.trim(), values)) {
tryAdd(e2.op2.trim(), values);
}
}
break;
case // putfield
FIELD:
FieldExpr fe = (FieldExpr) e2.op1.trim();
if (fe.op == null || fe.op.trim() == null || tryAdd(fe.op.trim(), values)) {
tryAdd(e2.op2.trim(), values);
}
break;
default:
if (tryAdd(e2.op2.trim(), values)) {
tryAdd(e2.op1.trim(), values);
}
}
default:
}
for (Value value : values) {
switch(value.vt) {
case CONSTANT:
case LOCAL:
break;
default:
Local n = Exprs.nLocal("xxx");
locals.add(n);
stmts.insertBefore(p, Stmts.nAssign(n, value));
}
}
stmts.insertBefore(p, Stmts.nThrow(Exprs.nInvokeNew(new Value[0], new String[0], "Ljava/lang/NullPointerException;")));
stmts.remove(p);
}
use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.
the class AggTransformerTest method test04.
@Test
public void test04() {
Local array = addLocal("array");
Local index = addLocal("index");
Local value = addLocal("value");
addStmt(nAssign(array, nNewIntArray(nInt(5))));
addStmt(nAssign(index, niAdd(nInt(1999), nInt(3))));
addStmt(nAssign(value, niAdd(index, nInt(4))));
addStmt(nAssign(nArray(array, index, "I"), value));
addStmt(nReturnVoid());
transform();
Assert.assertTrue(method.locals.size() >= 2);
}
Aggregations