--HG--
branch : 0.0.9.x
This commit is contained in:
Panxiaobo 2011-08-03 23:35:18 +08:00
parent cbe7056c4a
commit 125c65b47c
6 changed files with 170 additions and 34 deletions

View File

@ -8,4 +8,8 @@ target/*
.*
*.bak
*.orig
*/nb-configuration.xml
*/nb-configuration.xml
*.iml
*.ipr
*.iws

View File

@ -44,17 +44,19 @@ public class IrMethod {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("// ").append(this.owner.getClassName()).append("\n");
sb.append(ToStringUtil.getAccDes(access)).append(ToStringUtil.toShortClassName(ret)).append(' ')
.append(this.name).append('(');
boolean first = true;
for (Type arg : args) {
if (first) {
first = false;
} else {
sb.append(',');
sb.append("// ").append(this.owner == null ? null : this.owner.getClassName()).append("\n");
sb.append(ToStringUtil.getAccDes(access)).append(ret == null ? null : ToStringUtil.toShortClassName(ret))
.append(' ').append(this.name).append('(');
if (args != null) {
boolean first = true;
for (Type arg : args) {
if (first) {
first = false;
} else {
sb.append(',');
}
sb.append(ToStringUtil.toShortClassName(arg));
}
sb.append(ToStringUtil.toShortClassName(arg));
}
sb.append(") {\n\n").append(stmts).append("\n");
if (traps.size() > 0) {

View File

@ -119,7 +119,7 @@ public abstract class Stmt {
/**
* Used in Local Split, backward frame of the {@link Stmt}
*/
public ValueBox[] _ls_backward_frame;
public Object _ls_backward_frame;
/**
* Used in Local Split, forward frame of the {@link Stmt}
*/

View File

@ -15,11 +15,11 @@
*/
package com.googlecode.dex2jar.ir.ts;
import static com.googlecode.dex2jar.ir.Constant.nInt;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.googlecode.dex2jar.ir.IrMethod;
import com.googlecode.dex2jar.ir.Local;
@ -79,6 +79,32 @@ public class LocalSplit implements Transformer {
return vb;
}
static class BackwardMarker extends Value {
Set<BackwardMarker> parent;
boolean used = false;
BackwardMarker(boolean use) {
this();
this.used = use;
}
public void use() {
if (!used) {
used = true;
if (parent != null) {
for (BackwardMarker p : parent) {
p.use();
}
}
}
}
protected BackwardMarker() {
super(null, null);
}
}
public void transform(final IrMethod jm) {
final int orgLocalSize = jm.locals.size();
final StmtList list = jm.stmts;
@ -89,20 +115,18 @@ public class LocalSplit implements Transformer {
jm.locals.clear();
final List<Local> locals = jm.locals;
final Value NEED = nInt(1);
final Value NotNEED = nInt(0);
Cfg.createCFG(jm);
Cfg.Backward(jm, new FrameVisitor<ValueBox[]>() {
Cfg.Backward(jm, new FrameVisitor<BackwardMarker[]>() {
private void doLocalRef(ValueBox vb, ValueBox[] frame) {
private void doLocalRef(ValueBox vb, BackwardMarker[] frame) {
if (vb == null)
return;
Value v = vb.value;
switch (v.et) {
case E0:
if (v.vt == VT.LOCAL) {
frame[((Local) v)._ls_index] = new ValueBox(NEED);
frame[((Local) v)._ls_index] = new BackwardMarker(true);
}
break;
case E1:
@ -124,13 +148,13 @@ public class LocalSplit implements Transformer {
}
@Override
public ValueBox[] exec(Stmt stmt) {
ValueBox[] tmp = new ValueBox[orgLocalSize];
public BackwardMarker[] exec(Stmt stmt) {
BackwardMarker[] tmp = new BackwardMarker[orgLocalSize];
if (stmt._ls_backward_frame != null) {
System.arraycopy(stmt._ls_backward_frame, 0, tmp, 0, tmp.length);
} else {
for (int i = 0; i < tmp.length; i++) {
tmp[i] = new ValueBox(NotNEED);
tmp[i] = new BackwardMarker(false);
}
}
@ -144,7 +168,7 @@ public class LocalSplit implements Transformer {
case E2:
E2Stmt e2 = (E2Stmt) stmt;
if (e2.op1.value.vt == VT.LOCAL) {
tmp[((Local) e2.op1.value)._ls_index] = new ValueBox(NotNEED);
tmp[((Local) e2.op1.value)._ls_index] = new BackwardMarker(false);
doLocalRef(e2.op2, tmp);
} else {
doLocalRef(e2.op1, tmp);
@ -162,23 +186,57 @@ public class LocalSplit implements Transformer {
}
@Override
public void merge(ValueBox[] currnetFrame, Stmt dist) {
public void merge(BackwardMarker[] currnetFrame, Stmt dist) {
if (dist._ls_backward_frame == null) {
dist._ls_backward_frame = new ValueBox[orgLocalSize];
for (int i = 0; i < currnetFrame.length; i++) {
dist._ls_backward_frame[i] = new ValueBox(currnetFrame[i].value);
BackwardMarker[] distFrame = new BackwardMarker[orgLocalSize];
dist._ls_backward_frame = distFrame;
if (dist._cfg_tos.size() > 1) {
for (int i = 0; i < orgLocalSize; i++) {
if (currnetFrame[i].used) {
distFrame[i] = currnetFrame[i];
} else {
BackwardMarker bm = new BackwardMarker();
Set<BackwardMarker> parent = currnetFrame[i].parent;
if (parent == null) {
parent = new HashSet<BackwardMarker>();
currnetFrame[i].parent = parent;
}
parent.add(bm);
distFrame[i] = bm;
}
}
} else {
// for (int i = 0; i < currnetFrame.length; i++) {
// dist._ls_backward_frame[i] = currnetFrame[i];
// }
System.arraycopy(currnetFrame, 0, dist._ls_backward_frame, 0, orgLocalSize);
}
} else {
ValueBox[] distFrame = (ValueBox[]) dist._ls_backward_frame;
for (int i = 0; i < currnetFrame.length; i++) {
if (currnetFrame[i].value == NEED) {
distFrame[i].value = NEED;
BackwardMarker[] distFrame = (BackwardMarker[]) dist._ls_backward_frame;
for (int i = 0; i < orgLocalSize; i++) {
if (!distFrame[i].used) {
if (currnetFrame[i].used) {
distFrame[i].use();
} else {
Set<BackwardMarker> parent = currnetFrame[i].parent;
if (parent == null) {
parent = new HashSet<BackwardMarker>();
currnetFrame[i].parent = parent;
}
parent.add(distFrame[i]);
}
}
}
}
}
});
// for (Stmt stmt : jm.stmts) {
// System.out.printf("%30s |%s\n",
// stmt._ls_backward_frame == null ? "" : Arrays.asList(stmt._ls_backward_frame), stmt);
// }
final ArrayList<Stmt> _ls_visit_order = new ArrayList<Stmt>(list.getSize());
Cfg.Forward(jm, new FrameVisitor<ValueBox[]>() {
@ -226,9 +284,9 @@ public class LocalSplit implements Transformer {
System.arraycopy(currentFrame, 0, distStmt._ls_forward_frame, 0, currentFrame.length);
} else {
ValueBox[] b = (ValueBox[]) distStmt._ls_forward_frame;
ValueBox[] backwardFrame = distStmt._ls_backward_frame;
BackwardMarker[] backwardFrame = (BackwardMarker[]) distStmt._ls_backward_frame;
for (int i = 0; i < currentFrame.length; i++) {
if (backwardFrame[i].value == NotNEED) {
if (!backwardFrame[i].used) {
continue;
}
ValueBox ai = trimLocalVB(currentFrame[i]);

View File

@ -31,6 +31,7 @@ import com.googlecode.dex2jar.ir.expr.Exprs;
import com.googlecode.dex2jar.ir.stmt.AssignStmt;
import com.googlecode.dex2jar.ir.stmt.LabelStmt;
import com.googlecode.dex2jar.ir.stmt.StmtList;
import com.googlecode.dex2jar.ir.stmt.Stmts;
import com.googlecode.dex2jar.ir.stmt.UnopStmt;
import com.googlecode.dex2jar.ir.ts.LocalSplit;
@ -262,4 +263,76 @@ public class LocalSplitTest {
Assert.assertTrue(jm.locals.size() == 14);
}
@Test
public void test7() {
IrMethod jm = new IrMethod();
LabelStmt L2 = nLabel();
LabelStmt L3 = nLabel();
LabelStmt L4 = nLabel();
LabelStmt L5 = nLabel();
StmtList list = jm.stmts;
Local b = nLocal("b", null);
Local c = nLocal("c", null);
jm.locals.add(b);
jm.locals.add(c);
list.add(Stmts.nIf(Exprs.nEq(nInt(1), nInt(2)), L2));
list.add(nAssign(b, nInt(3)));
list.add(nGoto(L3));
list.add(L2);
list.add(nAssign(b, nInt(4)));
list.add(L3);
list.add(Stmts.nIf(Exprs.nEq(nInt(1), nInt(2)), L4));
list.add(Stmts.nReturnVoid());
list.add(L4);
list.add(Stmts.nIf(Exprs.nEq(nInt(1), nInt(2)), L5));
list.add(Stmts.nAssign(c, Exprs.nInvokeStatic(new Value[] { b }, Type.getType(String.class), "someMethod",
new Type[] { Type.INT_TYPE }, Type.VOID_TYPE)));
list.add(Stmts.nReturnVoid());
list.add(L5);
list.add(Stmts.nReturnVoid());
new LocalSplit().transform(jm);
Assert.assertTrue(jm.locals.size() == 2);
}
@Test
public void test8() {
IrMethod jm = new IrMethod();
LabelStmt L2 = nLabel();
LabelStmt L3 = nLabel();
LabelStmt L4 = nLabel();
LabelStmt L5 = nLabel();
StmtList list = jm.stmts;
Local b = nLocal("b", null);
Local c = nLocal("c", null);
jm.locals.add(b);
jm.locals.add(c);
list.add(Stmts.nIf(Exprs.nEq(nInt(1), nInt(2)), L2));
list.add(nAssign(b, nInt(3)));
list.add(nGoto(L3));
list.add(L2);
list.add(nAssign(b, nInt(4)));
list.add(L3);
list.add(Stmts.nIf(Exprs.nEq(nInt(1), nInt(2)), L4));
list.add(Stmts.nReturnVoid());
list.add(L4);
list.add(Stmts.nIf(Exprs.nEq(nInt(1), nInt(2)), L5));
list.add(Stmts.nReturnVoid());
list.add(L5);
list.add(Stmts.nAssign(c, Exprs.nInvokeStatic(new Value[] { b }, Type.getType(String.class), "someMethod",
new Type[] { Type.INT_TYPE }, Type.VOID_TYPE)));
list.add(Stmts.nReturnVoid());
new LocalSplit().transform(jm);
Assert.assertTrue(jm.locals.size() == 2);
}
}

View File

@ -17,7 +17,6 @@ package com.googlecode.dex2jar.test;
import java.io.File;
import java.io.IOException;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;