use of com.googlecode.dex2jar.ir.stmt.Stmt in project dex2jar by pxb1988.
the class VoidInvokeTransformer method transformReportChanged.
@Override
public boolean transformReportChanged(IrMethod method) {
if (method.locals.size() == 0) {
return false;
}
int[] reads = Cfg.countLocalReads(method);
boolean changed = false;
for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) {
if (p.st == Stmt.ST.ASSIGN && p.getOp1().vt == Value.VT.LOCAL) {
Local left = (Local) p.getOp1();
if (reads[left._ls_index] == 0) {
switch(p.getOp2().vt) {
case INVOKE_INTERFACE:
case INVOKE_NEW:
case INVOKE_SPECIAL:
case INVOKE_STATIC:
case INVOKE_VIRTUAL:
method.locals.remove(left);
Stmt nVoidInvoke = Stmts.nVoidInvoke(p.getOp2());
method.stmts.replace(p, nVoidInvoke);
p = nVoidInvoke;
changed = true;
break;
default:
break;
}
}
}
}
return changed;
}
use of com.googlecode.dex2jar.ir.stmt.Stmt in project dex2jar by pxb1988.
the class BaseAnalyze method init.
protected void init() {
if (reindexLocal) {
int index = 0;
for (Local local : method.locals) {
local._ls_index = index;
index++;
}
}
if (DEBUG) {
int idx = 0;
for (Stmt s : method.stmts) {
if (s.st == Stmt.ST.LABEL) {
LabelStmt label = (LabelStmt) s;
label.displayName = "L" + idx++;
}
}
}
initCFG();
}
use of com.googlecode.dex2jar.ir.stmt.Stmt in project dex2jar by pxb1988.
the class ArrayElementTransformer method transformReportChanged.
@Override
public boolean transformReportChanged(IrMethod method) {
Set<Local> arrays = searchForArrayObject(method);
if (arrays.size() == 0) {
return false;
}
for (Local local : method.locals) {
local._ls_index = -1;
}
int i = 0;
for (Local local : arrays) {
local._ls_index = i++;
}
final int size = i;
Cfg.createCFG(method);
final List<ArrayValue> values = new ArrayList<>();
final List<Stmt> used = new ArrayList<>();
Cfg.dfs(method.stmts, new Cfg.FrameVisitor<ArrayValue[]>() {
Set<Integer> phis = new HashSet<>();
@Override
public ArrayValue[] merge(ArrayValue[] srcFrame, ArrayValue[] distFrame, Stmt src, Stmt dist) {
if (dist.st == Stmt.ST.LABEL) {
LabelStmt labelStmt = (LabelStmt) dist;
if (labelStmt.phis != null) {
for (AssignStmt phi : labelStmt.phis) {
int idx = ((Local) phi.getOp1())._ls_index;
if (idx >= 0) {
phis.add(idx);
}
}
}
}
if (distFrame == null) {
distFrame = new ArrayValue[size];
for (int i = 0; i < size; i++) {
if (phis.contains(i)) {
ArrayValue aov = new ArrayValue();
values.add(aov);
aov.s = ArrayValue.S.UNKNOWN;
aov.indexType = ArrayValue.IndexType.NONE;
aov.stmt = dist;
distFrame[i] = aov;
} else {
ArrayValue arc = srcFrame[i];
if (arc != null) {
ArrayValue aov = new ArrayValue();
values.add(aov);
aov.s = ArrayValue.S.INHERIT;
aov.indexType = ArrayValue.IndexType.NONE;
aov.stmt = dist;
aov.parent = arc;
distFrame[i] = aov;
}
}
}
} else {
for (int i = 0; i < size; i++) {
if (phis.contains(i)) {
continue;
}
ArrayValue arc = srcFrame[i];
ArrayValue aov = distFrame[i];
if (arc != null && aov != null) {
if (aov.parent == null) {
aov.parent = arc;
} else if (!aov.parent.equals(arc)) {
if (aov.otherParents == null) {
aov.otherParents = new HashSet<>();
}
aov.otherParents.add(arc);
}
}
}
}
phis.clear();
return distFrame;
}
@Override
public ArrayValue[] initFirstFrame(Stmt first) {
return new ArrayValue[size];
}
ArrayValue[] tmp = new ArrayValue[size];
Stmt currentStmt;
@Override
public ArrayValue[] exec(ArrayValue[] frame, Stmt stmt) {
currentStmt = stmt;
System.arraycopy(frame, 0, tmp, 0, size);
if (stmt.st == Stmt.ST.ASSIGN) {
// create an array
if (stmt.getOp1().vt == Value.VT.LOCAL) {
Local local = (Local) stmt.getOp1();
use(stmt.getOp2());
if (local._ls_index >= 0) {
Value op2 = stmt.getOp2();
if (op2.vt == Value.VT.NEW_ARRAY) {
ArrayValue av = new ArrayValue();
av.s = ArrayValue.S.DEFAULT;
av.size = op2.getOp();
values.add(av);
tmp[local._ls_index] = av;
} else if (op2.vt == Value.VT.FILLED_ARRAY) {
ArrayValue av = new ArrayValue();
av.s = ArrayValue.S.DEFAULT;
av.indexType = ArrayValue.IndexType.CONST;
av.stmt = stmt;
FilledArrayExpr fae = (FilledArrayExpr) stmt.getOp2();
av.size = Exprs.nInt(fae.getOps().length);
Value[] ops = fae.getOps();
for (int i = 0; i < ops.length; i++) {
av.elements1.put(i, ops[i]);
}
values.add(av);
tmp[local._ls_index] = av;
} else if (op2.vt == Value.VT.CONSTANT) {
Object cst = ((Constant) op2).value;
if (cst != null && !cst.equals(Constant.Null) && cst.getClass().isArray()) {
ArrayValue av = new ArrayValue();
av.s = ArrayValue.S.DEFAULT;
av.indexType = ArrayValue.IndexType.CONST;
av.stmt = stmt;
int size = Array.getLength(cst);
av.size = Exprs.nInt(size);
for (int i = 0; i < size; i++) {
av.elements1.put(i, Exprs.nConstant(Array.get(cst, size)));
}
values.add(av);
tmp[local._ls_index] = av;
} else {
ArrayValue av = new ArrayValue();
values.add(av);
av.s = ArrayValue.S.UNKNOWN;
av.indexType = ArrayValue.IndexType.NONE;
av.stmt = stmt;
tmp[local._ls_index] = av;
}
} else {
ArrayValue av = new ArrayValue();
values.add(av);
av.s = ArrayValue.S.UNKNOWN;
av.indexType = ArrayValue.IndexType.NONE;
av.stmt = stmt;
tmp[local._ls_index] = av;
}
}
// assign index1
} else if (stmt.getOp1().vt == Value.VT.ARRAY) {
use(stmt.getOp2());
ArrayExpr ae = (ArrayExpr) stmt.getOp1();
if (ae.getOp1().vt == Value.VT.LOCAL) {
Local local = (Local) ae.getOp1();
Value index = ae.getOp2();
if (local._ls_index >= 0) {
if (index.vt == Value.VT.CONSTANT) {
ArrayValue parent = tmp[local._ls_index];
ArrayValue av = new ArrayValue();
values.add(av);
av.parent = parent;
av.elements1.put(((Number) (((Constant) index).value)).intValue(), stmt.getOp2());
av.indexType = ArrayValue.IndexType.CONST;
av.s = ArrayValue.S.INHERIT;
av.stmt = stmt;
tmp[local._ls_index] = av;
} else if (index.vt == Value.VT.LOCAL) {
ArrayValue parent = tmp[local._ls_index];
ArrayValue av = new ArrayValue();
values.add(av);
av.parent = parent;
av.elements1.put(index, stmt.getOp2());
av.indexType = ArrayValue.IndexType.LOCAL;
av.s = ArrayValue.S.INHERIT;
av.stmt = stmt;
tmp[local._ls_index] = av;
} else {
ArrayValue av = new ArrayValue();
values.add(av);
av.s = ArrayValue.S.UNKNOWN;
av.indexType = ArrayValue.IndexType.NONE;
av.stmt = stmt;
tmp[local._ls_index] = av;
}
} else {
use(stmt.getOp1());
}
} else {
use(stmt.getOp1());
}
} else {
use(stmt.getOp1());
use(stmt.getOp2());
}
// assign index2
} else if (stmt.st == Stmt.ST.FILL_ARRAY_DATA) {
if (stmt.getOp1().vt == Value.VT.LOCAL) {
Local local = (Local) stmt.getOp1();
if (local._ls_index >= 0) {
Object array = ((Constant) stmt.getOp2()).value;
ArrayValue parent = tmp[local._ls_index];
ArrayValue av = new ArrayValue();
values.add(av);
av.parent = parent;
int size = Array.getLength(array);
av.size = Exprs.nInt(size);
for (int i = 0; i < size; i++) {
av.elements1.put(i, Exprs.nConstant(Array.get(array, i)));
}
av.indexType = ArrayValue.IndexType.CONST;
av.s = ArrayValue.S.INHERIT;
av.stmt = stmt;
tmp[local._ls_index] = av;
}
} else {
use(stmt.getOp1());
}
} else {
switch(stmt.et) {
case E0:
break;
case E1:
use(stmt.getOp());
break;
case E2:
use(stmt.getOp1());
use(stmt.getOp2());
break;
case En:
throw new RuntimeException();
}
}
return tmp;
}
private void use(Value v) {
switch(v.et) {
case E0:
break;
case E1:
use(v.getOp());
break;
case E2:
Value op1 = v.getOp1();
Value op2 = v.getOp2();
use(op1);
use(op2);
if (v.vt == Value.VT.ARRAY) {
if (op1.vt == Value.VT.LOCAL && (op2.vt == Value.VT.LOCAL || op2.vt == Value.VT.CONSTANT)) {
Local local = (Local) op1;
if (local._ls_index > 0) {
used.add(currentStmt);
}
}
}
break;
case En:
for (Value op : v.getOps()) {
use(op);
}
break;
}
}
});
for (Stmt p : method.stmts) {
}
new StmtTraveler() {
@Override
public Value travel(Value op) {
op = super.travel(op);
if (op.vt == Value.VT.ARRAY) {
}
return op;
}
}.travel(method.stmts);
return false;
}
use of com.googlecode.dex2jar.ir.stmt.Stmt in project dex2jar by pxb1988.
the class UnSSATransformerTransformerTest method test01SSAProblem.
@Test
public void test01SSAProblem() {
initMethod(true, "I");
Local a = addLocal("a");
Local b = addLocal("b");
Local phi = addLocal("p");
LabelStmt L0 = newLabel();
addStmt(nAssign(a, nInt(2)));
addStmt(L0);
attachPhi(L0, nAssign(phi, nPhi(a, b)));
Stmt stmt = addStmt(nAssign(b, niAdd(phi, nInt(0))));
addStmt(nIf(niGt(nInt(100), nInt(0)), L0));
addStmt(nReturn(phi));
transform();
Assert.assertTrue("a new local should introduced to solve the problem", stmt.getPre() != L0);
}
use of com.googlecode.dex2jar.ir.stmt.Stmt in project dex2jar by pxb1988.
the class UnSSATransformerTransformerTest method test05OneInPhiLoop.
@Test
public void test05OneInPhiLoop() {
initMethod(true, "V");
Local a = addLocal("a");
Local b = addLocal("b");
Local phi = addLocal("p");
Stmt s1 = addStmt(nAssign(a, nString("123")));
LabelStmt L1 = newLabel();
addStmt(L1);
attachPhi(L1, nAssign(phi, nPhi(a)));
addStmt(nVoidInvoke(nInvokeStatic(new Value[] { phi }, "LAAA;", "bMethod", new String[] { "Ljava/lang/String;" }, "V")));
addStmt(nAssign(b, nString("456")));
// phi is still live here
Stmt s2 = addStmt(nVoidInvoke(nInvokeStatic(new Value[] { b }, "LBBB;", "cMethod", new String[] { "Ljava/lang/String;" }, "V")));
addStmt(nIf(niGt(nInt(100), nInt(0)), L1));
addStmt(nReturnVoid());
transform();
Assert.assertTrue("p=a should inserted", s1.getPre() != L1);
}
Aggregations