修改IR结构

--HG--
branch : 0.0.9.x
This commit is contained in:
Panxiaobo 2011-07-03 17:57:54 +08:00
parent 627987347a
commit 346e1254b0
31 changed files with 297 additions and 384 deletions

View File

@ -2,7 +2,9 @@ package com.googlecode.dex2jar.ir;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
public class Constant extends Value { import com.googlecode.dex2jar.ir.Value.E0Expr;
public class Constant extends E0Expr {
public static Object Null = new Object(); public static Object Null = new Object();
public static Type STRING = Type.getType(String.class); public static Type STRING = Type.getType(String.class);

View File

@ -0,0 +1,5 @@
package com.googlecode.dex2jar.ir;
public enum ET {
E0, E1, E2, En
}

View File

@ -2,7 +2,9 @@ package com.googlecode.dex2jar.ir;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
public class Local extends Value { import com.googlecode.dex2jar.ir.Value.E0Expr;
public class Local extends E0Expr {
public Type type; public Type type;
public String name; public String name;

View File

@ -2,18 +2,58 @@ package com.googlecode.dex2jar.ir;
public abstract class Value { public abstract class Value {
public static enum VT { public static enum VT {
ADD, AND, ARRAY, CAST, CMP, CMPG, CMPL, DIV, EQ, FIELD, GE, GT, INSTANCEOF, INVOKE_INTERFACE, LE, LENGTH, LT, MUL, NE, NEG, NEW_ARRAY, NEW_MUTI_ARRAY, OR, REM, SHL, SHR, INVOKE_SPECIAL, // ADD, AND, ARRAY, CAST, CMP, CMPG, CMPL, DIV, EQ, FIELD, GE, GT, INSTANCEOF, INVOKE_INTERFACE, LE, LENGTH, LT, MUL, NE, NEG, NEW_ARRAY, NEW_MUTI_ARRAY, OR, REM, SHL, SHR, INVOKE_SPECIAL, //
INVOKE_STATIC, SUB, USHR, INVOKE_VIRTUAL, INVOKE_NEW, XOR, LOCAL, CONSTANT, THIS_REF, PARAMETER_REF, EXCEPTION_REF, NOT INVOKE_STATIC, SUB, USHR, INVOKE_VIRTUAL, INVOKE_NEW, XOR, LOCAL, CONSTANT, THIS_REF, PARAMETER_REF, EXCEPTION_REF, NOT
} }
final public VT vt; final public VT vt;
final public ET et;
/** /**
* @param vt * @param vt
*/ */
public Value(VT vt) { public Value(VT vt, ET et) {
super(); super();
this.vt = vt; this.vt = vt;
this.et = et;
} }
public static abstract class E0Expr extends Value {
public E0Expr(VT vt) {
super(vt, ET.E0);
}
}
public static abstract class E1Expr extends Value {
public ValueBox op;
public E1Expr(VT vt, ValueBox op) {
super(vt, ET.E1);
this.op = op;
}
}
public static abstract class E2Expr extends Value {
public ValueBox op1;
public ValueBox op2;
public E2Expr(VT vt, ValueBox op1, ValueBox op2) {
super(vt, ET.E2);
this.op1 = op1;
this.op2 = op2;
}
}
public static abstract class EnExpr extends Value {
public ValueBox[] ops;
public EnExpr(VT vt, ValueBox[] ops) {
super(vt, ET.En);
this.ops = ops;
}
}
} }

View File

@ -1,24 +1,20 @@
package com.googlecode.dex2jar.ir.expr; package com.googlecode.dex2jar.ir.expr;
import com.googlecode.dex2jar.ir.Value; import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.Value.E2Expr;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
public class ArrayExpr extends Value { public class ArrayExpr extends E2Expr {
public ValueBox base;
public ValueBox index;
public ArrayExpr() { public ArrayExpr() {
super(VT.ARRAY); super(VT.ARRAY, null, null);
} }
public ArrayExpr(Value base, Value index) { public ArrayExpr(Value base, Value index) {
super(VT.ARRAY); super(VT.ARRAY, new ValueBox(base), new ValueBox(index));
this.base = new ValueBox(base);
this.index = new ValueBox(index);
} }
public String toString() { public String toString() {
return base + "[" + index + "]"; return op1 + "[" + op2 + "]";
} }
} }

View File

@ -1,17 +1,13 @@
package com.googlecode.dex2jar.ir.expr; package com.googlecode.dex2jar.ir.expr;
import com.googlecode.dex2jar.ir.Value; import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.Value.E2Expr;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
public class BinopExpr extends Value { public class BinopExpr extends E2Expr {
public ValueBox op1;
public ValueBox op2;
public BinopExpr(VT type, Value op1, Value op2) { public BinopExpr(VT type, Value op1, Value op2) {
super(type); super(type, new ValueBox(op1), new ValueBox(op2));
this.op1 = new ValueBox(op1);
this.op2 = new ValueBox(op2);
} }
public String toString() { public String toString() {

View File

@ -1,24 +0,0 @@
package com.googlecode.dex2jar.ir.expr;
import org.objectweb.asm.Type;
import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.ValueBox;
public class CastExpr extends Value {
public Type castType;
public ValueBox op;
public CastExpr(Value value, Type type) {
super(VT.CAST);
this.castType = type;
this.op = new ValueBox(value);
}
public String toString() {
return "((" + castType.getClassName() + ")" + op + ")";
}
}

View File

@ -9,7 +9,11 @@ import com.googlecode.dex2jar.ir.ValueBox;
public final class Exprs { public final class Exprs {
private static ValueBox[] box(Value[] v) { public static ValueBox box(Value value) {
return new ValueBox(value);
}
public static ValueBox[] box(Value[] v) {
if (v == null) { if (v == null) {
return new ValueBox[0]; return new ValueBox[0];
} }
@ -32,8 +36,8 @@ public final class Exprs {
return new ArrayExpr(base, index); return new ArrayExpr(base, index);
} }
public static CastExpr nCast(Value obj, Type type) { public static TypeExpr nCast(Value obj, Type type) {
return new CastExpr(obj, type); return new TypeExpr(obj, type);
} }
public static BinopExpr nCmp(Value a, Value b) { public static BinopExpr nCmp(Value a, Value b) {
@ -56,8 +60,8 @@ public final class Exprs {
return new BinopExpr(VT.EQ, a, b); return new BinopExpr(VT.EQ, a, b);
} }
public static TypeRefExpr nExceptionRef(Type type) { public static RefExpr nExceptionRef(Type type) {
return new TypeRefExpr(VT.EXCEPTION_REF, type, -1); return new RefExpr(VT.EXCEPTION_REF, type, -1);
} }
public static FieldExpr nField(Value object, Type ownerType, String fieldName, Type fieldType) { public static FieldExpr nField(Value object, Type ownerType, String fieldName, Type fieldType) {
@ -72,8 +76,8 @@ public final class Exprs {
return new BinopExpr(VT.GT, a, b); return new BinopExpr(VT.GT, a, b);
} }
public static InstanceOfExpr nInstanceOf(Value value, Type type) { public static TypeExpr nInstanceOf(Value value, Type type) {
return new InstanceOfExpr(value, type); return new TypeExpr(value, type);
} }
public static InvokeExpr nInvokeInterface(Value[] regs, Type owner, String name, Type[] argmentTypes, public static InvokeExpr nInvokeInterface(Value[] regs, Type owner, String name, Type[] argmentTypes,
@ -137,20 +141,20 @@ public final class Exprs {
// return new NewExpr(type); // return new NewExpr(type);
// } // }
public static NewArrayExpr nNewArray(Type elementType, Value size) { public static TypeExpr nNewArray(Type elementType, Value size) {
return new NewArrayExpr(elementType, size); return new TypeExpr(size, elementType);
} }
public static NewMutiArrayExpr nNewMutiArray(Type base, int dim, Value[] sizes) { public static NewMutiArrayExpr nNewMutiArray(Type base, int dim, Value[] sizes) {
return new NewMutiArrayExpr(base, dim, sizes); return new NewMutiArrayExpr(base, dim, box(sizes));
} }
public static BinopExpr nOr(Value a, Value b) { public static BinopExpr nOr(Value a, Value b) {
return new BinopExpr(VT.OR, a, b); return new BinopExpr(VT.OR, a, b);
} }
public static TypeRefExpr nParameterRef(Type type, int index) { public static RefExpr nParameterRef(Type type, int index) {
return new TypeRefExpr(VT.PARAMETER_REF, type, index); return new RefExpr(VT.PARAMETER_REF, type, index);
} }
public static BinopExpr nRem(Value a, Value b) { public static BinopExpr nRem(Value a, Value b) {
@ -173,8 +177,8 @@ public final class Exprs {
return new BinopExpr(VT.SUB, a, b); return new BinopExpr(VT.SUB, a, b);
} }
public static TypeRefExpr nThisRef(Type type) { public static RefExpr nThisRef(Type type) {
return new TypeRefExpr(VT.THIS_REF, type, -1); return new RefExpr(VT.THIS_REF, type, -1);
} }
public static BinopExpr nUshr(Value a, Value b) { public static BinopExpr nUshr(Value a, Value b) {

View File

@ -2,26 +2,25 @@ package com.googlecode.dex2jar.ir.expr;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import com.googlecode.dex2jar.ir.Value; import com.googlecode.dex2jar.ir.Value.E1Expr;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
public class FieldExpr extends Value { public class FieldExpr extends E1Expr {
public String fieldName; public String fieldName;
public Type fieldType; public Type fieldType;
public Type fieldOwnerType; public Type fieldOwnerType;
public ValueBox object; public ValueBox op;
public FieldExpr(ValueBox object, Type ownerType, String fieldName, Type fieldType) { public FieldExpr(ValueBox object, Type ownerType, String fieldName, Type fieldType) {
super(VT.FIELD); super(VT.FIELD,object);
this.object = object;
this.fieldType = fieldType; this.fieldType = fieldType;
this.fieldName = fieldName; this.fieldName = fieldName;
this.fieldOwnerType = ownerType; this.fieldOwnerType = ownerType;
} }
public String toString() { public String toString() {
return (object == null ? fieldOwnerType.getClassName() : object) + "." + fieldName; return (op == null ? fieldOwnerType.getClassName() : op) + "." + fieldName;
} }
} }

View File

@ -1,23 +0,0 @@
package com.googlecode.dex2jar.ir.expr;
import org.objectweb.asm.Type;
import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.ValueBox;
public class InstanceOfExpr extends Value {
public ValueBox op;
public Type instanceType;
public InstanceOfExpr(Value op, Type type2) {
super(VT.INSTANCEOF);
this.op = new ValueBox(op);
instanceType = type2;
}
public String toString() {
return "(" + op + " instanceof " + instanceType.getClassName() + ")";
}
}

View File

@ -2,25 +2,22 @@ package com.googlecode.dex2jar.ir.expr;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import com.googlecode.dex2jar.ir.Value; import com.googlecode.dex2jar.ir.Value.EnExpr;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
public class InvokeExpr extends Value { public class InvokeExpr extends EnExpr {
public Type[] argmentTypes; public Type[] argmentTypes;
public ValueBox args[];
public String methodName; public String methodName;
public Type methodOwnerType; public Type methodOwnerType;
public Type methodReturnType; public Type methodReturnType;
public InvokeExpr(VT type, ValueBox[] args, Type ownerType, String methodName, Type[] argmentTypes, Type returnType) { public InvokeExpr(VT type, ValueBox[] args, Type ownerType, String methodName, Type[] argmentTypes, Type returnType) {
super(type); super(type, args);
this.methodReturnType = returnType; this.methodReturnType = returnType;
this.methodName = methodName; this.methodName = methodName;
this.methodOwnerType = ownerType; this.methodOwnerType = ownerType;
this.argmentTypes = argmentTypes; this.argmentTypes = argmentTypes;
this.args = args;
} }
public String toString() { public String toString() {
@ -29,18 +26,18 @@ public class InvokeExpr extends Value {
if (super.vt == VT.INVOKE_NEW) { if (super.vt == VT.INVOKE_NEW) {
sb.append("new ").append(methodOwnerType.getClassName()).append('('); sb.append("new ").append(methodOwnerType.getClassName()).append('(');
} else { } else {
sb.append(super.vt == VT.INVOKE_STATIC ? methodOwnerType.getClassName() : args[i]).append('.') sb.append(super.vt == VT.INVOKE_STATIC ? methodOwnerType.getClassName() : ops[i]).append('.')
.append(this.methodName).append('('); .append(this.methodName).append('(');
i++; i++;
} }
boolean first = true; boolean first = true;
for (; i < args.length; i++) { for (; i < ops.length; i++) {
if (first) { if (first) {
first = false; first = false;
} else { } else {
sb.append(','); sb.append(',');
} }
sb.append(args[i]); sb.append(ops[i]);
} }
sb.append(')'); sb.append(')');
return sb.toString(); return sb.toString();

View File

@ -1,23 +0,0 @@
package com.googlecode.dex2jar.ir.expr;
import org.objectweb.asm.Type;
import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.ValueBox;
public class NewArrayExpr extends Value {
public ValueBox size;
public Type baseType;
public NewArrayExpr(Type type, Value size) {
super(VT.NEW_ARRAY);
this.size = new ValueBox(size);
this.baseType = type;
}
public String toString() {
return "new " + baseType.getClassName() + "[" + size + "]";
}
}

View File

@ -2,31 +2,26 @@ package com.googlecode.dex2jar.ir.expr;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import com.googlecode.dex2jar.ir.Value; import com.googlecode.dex2jar.ir.Value.EnExpr;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
public class NewMutiArrayExpr extends EnExpr {
public class NewMutiArrayExpr extends Value {
public Type baseType; public Type baseType;
public int dimension; public int dimension;
public ValueBox[] sizes;
public NewMutiArrayExpr(Type base, int dimension, Value[] sizes) { public NewMutiArrayExpr(Type base, int dimension, ValueBox[] sizes) {
super(VT.NEW_MUTI_ARRAY); super(VT.NEW_MUTI_ARRAY, sizes);
this.baseType = base; this.baseType = base;
this.dimension = dimension; this.dimension = dimension;
this.sizes = new ValueBox[sizes.length]; this.ops = new ValueBox[sizes.length];
for (int i = 0; i < sizes.length; i++) {
this.sizes[i] = new ValueBox(sizes[i]);
}
} }
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("new ").append(baseType); sb.append("new ").append(baseType);
for (int i = 0; i < dimension; i++) { for (int i = 0; i < dimension; i++) {
sb.append('[').append(sizes[i]).append(']'); sb.append('[').append(ops[i]).append(']');
} }
return sb.toString(); return sb.toString();
} }

View File

@ -2,12 +2,12 @@ package com.googlecode.dex2jar.ir.expr;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import com.googlecode.dex2jar.ir.Value; import com.googlecode.dex2jar.ir.Value.E0Expr;
public class TypeRefExpr extends Value { public class RefExpr extends E0Expr {
public TypeRefExpr(VT vt, Type refType, int index) { public RefExpr(VT vt, Type refType, int index) {
super(vt); super(vt);
this.parameterIndex = index; this.parameterIndex = index;
} }

View File

@ -0,0 +1,31 @@
package com.googlecode.dex2jar.ir.expr;
import org.objectweb.asm.Type;
import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.Value.E1Expr;
import com.googlecode.dex2jar.ir.ValueBox;
public class TypeExpr extends E1Expr {
public Type type;
public TypeExpr(Value value, Type type) {
super(VT.CAST, new ValueBox(value));
this.type = type;
}
public String toString() {
switch (super.vt) {
case CAST:
return "((" + type.getClassName() + ")" + op + ")";
case INSTANCEOF:
return "(" + op + " instanceof " + type.getClassName() + ")";
case NEW_ARRAY:
return "new " + type.getClassName() + "[" + op + "]";
}
return "UNKNOW";
}
}

View File

@ -1,19 +1,17 @@
package com.googlecode.dex2jar.ir.expr; package com.googlecode.dex2jar.ir.expr;
import com.googlecode.dex2jar.ir.Value; import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.Value.E1Expr;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
public class UnopExpr extends Value { public class UnopExpr extends E1Expr {
public ValueBox op;
/** /**
* @param type * @param type
* @param value * @param value
*/ */
public UnopExpr(VT type, Value value) { public UnopExpr(VT type, Value value) {
super(type); super(type, new ValueBox(value));
this.op = new ValueBox(value);
} }
public String toString() { public String toString() {

View File

@ -1,38 +1,20 @@
package com.googlecode.dex2jar.ir.stmt; package com.googlecode.dex2jar.ir.stmt;
import java.util.Map;
import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
import com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt;
public class AssignStmt extends Stmt { public class AssignStmt extends E2Stmt {
public ValueBox left;
public ValueBox right;
public AssignStmt(ST type, ValueBox left, ValueBox right) { public AssignStmt(ST type, ValueBox left, ValueBox right) {
super(type); super(type, left, right);
this.left = left;
this.right = right;
}
public AssignStmt(ST type, Value left, Value right) {
super(type);
this.left = new ValueBox(left);
this.right = new ValueBox(right);
}
@Override
public Stmt clone(Map<LabelStmt, LabelStmt> map) {
return new AssignStmt(st, left.value, right.value);
} }
public String toString() { public String toString() {
switch (st) { switch (st) {
case ASSIGN: case ASSIGN:
return left + " = " + right; return op1 + " = " + op2;
case IDENTITY: case IDENTITY:
return left + " := " + right; return op1 + " := " + op2;
} }
return super.toString(); return super.toString();
} }

View File

@ -1,20 +1,12 @@
package com.googlecode.dex2jar.ir.stmt; package com.googlecode.dex2jar.ir.stmt;
import java.util.Map;
import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
import com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt;
public class JumpStmt extends E1Stmt {
public class JumpStmt extends Stmt {
public ValueBox condition;
public LabelStmt target; public LabelStmt target;
private JumpStmt(ST type) {
super(type);
}
/** /**
* GOTO * GOTO
* *
@ -22,8 +14,7 @@ public class JumpStmt extends Stmt {
* @param target * @param target
*/ */
public JumpStmt(ST type, LabelStmt target) { public JumpStmt(ST type, LabelStmt target) {
this(type); this(type, null, target);
this.target = target;
} }
/** /**
@ -33,14 +24,9 @@ public class JumpStmt extends Stmt {
* @param condition * @param condition
* @param target * @param target
*/ */
public JumpStmt(ST type, Value condition, LabelStmt target) { public JumpStmt(ST type, ValueBox condition, LabelStmt target) {
this(type, target); super(type, condition);
this.condition = new ValueBox(condition); this.target = target;
}
@Override
public Stmt clone(Map<LabelStmt, LabelStmt> map) {
return new JumpStmt(st, condition.value, (LabelStmt) target.clone(map));
} }
public String toString() { public String toString() {
@ -48,7 +34,7 @@ public class JumpStmt extends Stmt {
case GOTO: case GOTO:
return "GOTO " + target; return "GOTO " + target;
case IF: case IF:
return "if " + condition + " GOTO " + target; return "if " + op + " GOTO " + target;
} }
return super.toString(); return super.toString();
} }

View File

@ -1,10 +1,10 @@
package com.googlecode.dex2jar.ir.stmt; package com.googlecode.dex2jar.ir.stmt;
import java.util.Map;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
public class LabelStmt extends Stmt { import com.googlecode.dex2jar.ir.stmt.Stmt.E0Stmt;
public class LabelStmt extends E0Stmt {
public LabelStmt(Label label) { public LabelStmt(Label label) {
super(ST.LABEL); super(ST.LABEL);
@ -13,16 +13,6 @@ public class LabelStmt extends Stmt {
public Label label; public Label label;
@Override
public Stmt clone(Map<LabelStmt, LabelStmt> map) {
LabelStmt clone = map.get(this);
if (clone == null) {
clone = new LabelStmt(new Label());
map.put(this, clone);
}
return clone;
}
public String toString() { public String toString() {
return label + ":"; return label + ":";
} }

View File

@ -1,50 +1,23 @@
package com.googlecode.dex2jar.ir.stmt; package com.googlecode.dex2jar.ir.stmt;
import java.util.Map;
import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
import com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt;
public class LookupSwitchStmt extends E1Stmt {
public class LookupSwitchStmt extends Stmt {
public LabelStmt defaultTarget; public LabelStmt defaultTarget;
public ValueBox key; public int[] lookupValues;
public Value[] lookupValues;
public LabelStmt[] targets; public LabelStmt[] targets;
public LookupSwitchStmt() { public LookupSwitchStmt(ValueBox key, int[] lookupValues, LabelStmt[] targets, LabelStmt defaultTarget) {
super(ST.LOOKUP_SWITCH); super(ST.LOOKUP_SWITCH, key);
}
public LookupSwitchStmt(Value key, Value[] lookupValues, LabelStmt[] targets, LabelStmt defaultTarget) {
super(ST.LOOKUP_SWITCH);
this.key = new ValueBox(key);
this.lookupValues = lookupValues; this.lookupValues = lookupValues;
this.targets = targets; this.targets = targets;
this.defaultTarget = defaultTarget; this.defaultTarget = defaultTarget;
} }
@Override
public Stmt clone(Map<LabelStmt, LabelStmt> map) {
LabelStmt[] cloneTargets;
Value[] cloneValue;
if (targets != null) {
cloneValue = new Value[lookupValues.length];
cloneTargets = new LabelStmt[targets.length];
for (int i = 0; i < targets.length; i++) {
cloneTargets[i] = (LabelStmt) targets[i].clone(map);
cloneValue[i] = lookupValues[i];
}
} else {
cloneTargets = null;
cloneValue = null;
}
return new LookupSwitchStmt(key.value, cloneValue, cloneTargets, (LabelStmt) defaultTarget.clone(map));
}
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder("switch(").append(key).append(") {"); StringBuilder sb = new StringBuilder("switch(").append(op).append(") {");
for (int i = 0; i < lookupValues.length; i++) { for (int i = 0; i < lookupValues.length; i++) {
sb.append("case ").append(lookupValues[i]).append(": GOTO ").append(targets[i].label).append(";"); sb.append("case ").append(lookupValues[i]).append(": GOTO ").append(targets[i].label).append(";");

View File

@ -1,18 +1,13 @@
package com.googlecode.dex2jar.ir.stmt; package com.googlecode.dex2jar.ir.stmt;
import java.util.Map; import com.googlecode.dex2jar.ir.stmt.Stmt.E0Stmt;
public class NopStmt extends Stmt { public class NopStmt extends E0Stmt {
public NopStmt() { public NopStmt() {
super(ST.NOP); super(ST.NOP);
} }
@Override
public Stmt clone(Map<LabelStmt, LabelStmt> map) {
return new NopStmt();
}
public String toString() { public String toString() {
return "NOP"; return "NOP";
} }

View File

@ -1,18 +1,13 @@
package com.googlecode.dex2jar.ir.stmt; package com.googlecode.dex2jar.ir.stmt;
import java.util.Map; import com.googlecode.dex2jar.ir.stmt.Stmt.E0Stmt;
public class ReturnVoidStmt extends Stmt { public class ReturnVoidStmt extends E0Stmt {
public ReturnVoidStmt() { public ReturnVoidStmt() {
super(ST.RETURN_VOID); super(ST.RETURN_VOID);
} }
@Override
public Stmt clone(Map<LabelStmt, LabelStmt> map) {
return new ReturnVoidStmt();
}
@Override @Override
public String toString() { public String toString() {
return "return"; return "return";

View File

@ -1,9 +1,9 @@
package com.googlecode.dex2jar.ir.stmt; package com.googlecode.dex2jar.ir.stmt;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import com.googlecode.dex2jar.ir.ET;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
public abstract class Stmt { public abstract class Stmt {
@ -23,13 +23,13 @@ public abstract class Stmt {
/* default */Stmt pre; /* default */Stmt pre;
public final ST st; public final ST st;
public final ET et;
public Stmt(ST type) { public Stmt(ST type, ET et) {
this.st = type; this.st = type;
this.et = et;
} }
public abstract Stmt clone(Map<LabelStmt, LabelStmt> map);
public final Stmt getNext() { public final Stmt getNext() {
return next; return next;
} }
@ -38,4 +38,39 @@ public abstract class Stmt {
return pre; return pre;
} }
public static abstract class E0Stmt extends Stmt {
public E0Stmt(ST type) {
super(type, ET.E0);
}
}
public static abstract class E1Stmt extends Stmt {
public ValueBox op;
public E1Stmt(ST type, ValueBox op) {
super(type, ET.E1);
this.op = op;
}
}
public static abstract class E2Stmt extends Stmt {
public ValueBox op1;
public ValueBox op2;
public E2Stmt(ST type, ValueBox op1, ValueBox op2) {
super(type, ET.E2);
this.op1 = op1;
this.op2 = op2;
}
}
public static abstract class EnStmt extends Stmt {
public ValueBox[] ops;
public EnStmt(ST type, ValueBox[] ops) {
super(type, ET.E1);
this.ops = ops;
}
}
} }

View File

@ -1,5 +1,7 @@
package com.googlecode.dex2jar.ir.stmt; package com.googlecode.dex2jar.ir.stmt;
import static com.googlecode.dex2jar.ir.expr.Exprs.box;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import com.googlecode.dex2jar.ir.Value; import com.googlecode.dex2jar.ir.Value;
@ -11,9 +13,9 @@ public final class Stmts {
public static AssignStmt nAssign(ValueBox left, ValueBox right) { public static AssignStmt nAssign(ValueBox left, ValueBox right) {
return new AssignStmt(ST.ASSIGN, left, right); return new AssignStmt(ST.ASSIGN, left, right);
} }
public static AssignStmt nAssign(Value left, Value right) { public static AssignStmt nAssign(Value left, Value right) {
return new AssignStmt(ST.ASSIGN, left, right); return new AssignStmt(ST.ASSIGN, box(left), box(right));
} }
public static JumpStmt nGoto(LabelStmt target) { public static JumpStmt nGoto(LabelStmt target) {
@ -21,25 +23,27 @@ public final class Stmts {
} }
public static AssignStmt nIdentity(Value local, Value identityRef) { public static AssignStmt nIdentity(Value local, Value identityRef) {
return new AssignStmt(ST.IDENTITY, local, identityRef); return new AssignStmt(ST.IDENTITY, box(local), box(identityRef));
} }
public static JumpStmt nIf(Value a, LabelStmt target) { public static JumpStmt nIf(Value a, LabelStmt target) {
return new JumpStmt(ST.IF, a, target); return new JumpStmt(ST.IF, box(a), target);
} }
public static LabelStmt nLabel() { public static LabelStmt nLabel() {
return new LabelStmt(new Label()); return new LabelStmt(new Label());
} }
public static LabelStmt nLabel(Label label) { public static LabelStmt nLabel(Label label) {
return new LabelStmt(label); return new LabelStmt(label);
} }
public static UnopStmt nLock(Value op) { public static UnopStmt nLock(Value op) {
return new UnopStmt(ST.LOCK, op); return new UnopStmt(ST.LOCK, box(op));
} }
public static LookupSwitchStmt nLookupSwitch(Value key, Value[] lookupValues, LabelStmt[] targets, LabelStmt target) { public static LookupSwitchStmt nLookupSwitch(Value key, int[] lookupValues, LabelStmt[] targets, LabelStmt target) {
return new LookupSwitchStmt(key, lookupValues, targets, target); return new LookupSwitchStmt(box(key), lookupValues, targets, target);
} }
public static NopStmt nNop() { public static NopStmt nNop() {
@ -47,7 +51,7 @@ public final class Stmts {
} }
public static UnopStmt nReturn(Value op) { public static UnopStmt nReturn(Value op) {
return new UnopStmt(ST.RETURN, op); return new UnopStmt(ST.RETURN, box(op));
} }
public static ReturnVoidStmt nReturnVoid() { public static ReturnVoidStmt nReturnVoid() {
@ -60,11 +64,11 @@ public final class Stmts {
} }
public static UnopStmt nThrow(Value op) { public static UnopStmt nThrow(Value op) {
return new UnopStmt(ST.THROW, op); return new UnopStmt(ST.THROW, box(op));
} }
public static UnopStmt nUnLock(Value op) { public static UnopStmt nUnLock(Value op) {
return new UnopStmt(ST.UNLOCK, op); return new UnopStmt(ST.UNLOCK, box(op));
} }
private Stmts() { private Stmts() {

View File

@ -1,49 +1,29 @@
package com.googlecode.dex2jar.ir.stmt; package com.googlecode.dex2jar.ir.stmt;
import java.util.Map;
import com.googlecode.dex2jar.ir.Value; import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
import com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt;
public class TableSwitchStmt extends E1Stmt {
public class TableSwitchStmt extends Stmt {
public LabelStmt defaultTarget; public LabelStmt defaultTarget;
public ValueBox key;
public int lowIndex, highIndex; public int lowIndex, highIndex;
public LabelStmt[] targets; public LabelStmt[] targets;
public TableSwitchStmt() { public TableSwitchStmt() {
super(ST.TABLE_SWITCH); super(ST.TABLE_SWITCH, null);
} }
public TableSwitchStmt(Value key, int lowIndex, int highIndex, LabelStmt[] targets, LabelStmt defaultTarget) { public TableSwitchStmt(Value key, int lowIndex, int highIndex, LabelStmt[] targets, LabelStmt defaultTarget) {
super(ST.TABLE_SWITCH); super(ST.TABLE_SWITCH, new ValueBox(key));
this.key = new ValueBox(key);
this.lowIndex = lowIndex; this.lowIndex = lowIndex;
this.highIndex = highIndex; this.highIndex = highIndex;
this.targets = targets; this.targets = targets;
this.defaultTarget = defaultTarget; this.defaultTarget = defaultTarget;
} }
@Override
public Stmt clone(Map<LabelStmt, LabelStmt> map) {
LabelStmt[] cloneTargets;
if (targets != null) {
cloneTargets = new LabelStmt[targets.length];
for (int i = 0; i < targets.length; i++) {
cloneTargets[i] = (LabelStmt) targets[i].clone(map);
}
} else {
cloneTargets = null;
}
return new TableSwitchStmt(key.value, lowIndex, highIndex, cloneTargets, (LabelStmt) defaultTarget.clone(map));
}
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder("switch(").append(key).append(") {"); StringBuilder sb = new StringBuilder("switch(").append(op).append(") {");
for (int i = 0; i < targets.length; i++) { for (int i = 0; i < targets.length; i++) {
sb.append("case ").append(lowIndex + i).append(": GOTO ").append(targets[i].label).append(";"); sb.append("case ").append(lowIndex + i).append(": GOTO ").append(targets[i].label).append(";");

View File

@ -1,23 +1,12 @@
package com.googlecode.dex2jar.ir.stmt; package com.googlecode.dex2jar.ir.stmt;
import java.util.Map;
import com.googlecode.dex2jar.ir.Value;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
import com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt;
public class UnopStmt extends E1Stmt {
public class UnopStmt extends Stmt { public UnopStmt(ST type, ValueBox op) {
super(type, op);
public ValueBox op;
public UnopStmt(ST type, Value op) {
super(type);
this.op = new ValueBox(op);
}
@Override
public Stmt clone(Map<LabelStmt, LabelStmt> map) {
return new UnopStmt(st, op.value);
} }
public String toString() { public String toString() {

View File

@ -15,13 +15,11 @@ import com.googlecode.dex2jar.ir.Value.VT;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
import com.googlecode.dex2jar.ir.expr.ArrayExpr; import com.googlecode.dex2jar.ir.expr.ArrayExpr;
import com.googlecode.dex2jar.ir.expr.BinopExpr; import com.googlecode.dex2jar.ir.expr.BinopExpr;
import com.googlecode.dex2jar.ir.expr.CastExpr;
import com.googlecode.dex2jar.ir.expr.Exprs; import com.googlecode.dex2jar.ir.expr.Exprs;
import com.googlecode.dex2jar.ir.expr.FieldExpr; import com.googlecode.dex2jar.ir.expr.FieldExpr;
import com.googlecode.dex2jar.ir.expr.InstanceOfExpr;
import com.googlecode.dex2jar.ir.expr.InvokeExpr; import com.googlecode.dex2jar.ir.expr.InvokeExpr;
import com.googlecode.dex2jar.ir.expr.NewArrayExpr;
import com.googlecode.dex2jar.ir.expr.NewMutiArrayExpr; import com.googlecode.dex2jar.ir.expr.NewMutiArrayExpr;
import com.googlecode.dex2jar.ir.expr.TypeExpr;
import com.googlecode.dex2jar.ir.expr.UnopExpr; import com.googlecode.dex2jar.ir.expr.UnopExpr;
import com.googlecode.dex2jar.ir.stmt.AssignStmt; import com.googlecode.dex2jar.ir.stmt.AssignStmt;
import com.googlecode.dex2jar.ir.stmt.JumpStmt; import com.googlecode.dex2jar.ir.stmt.JumpStmt;
@ -48,34 +46,35 @@ public class LocalRemover implements Transformer {
} }
switch (st.st) { switch (st.st) {
case ASSIGN: case ASSIGN:
case IDENTITY:
AssignStmt as = (AssignStmt) st; AssignStmt as = (AssignStmt) st;
if (as.left.value.vt == VT.LOCAL) { if (as.op1.value.vt == VT.LOCAL) {
Local aLeft = (Local) as.left.value; Local aLeft = (Local) as.op1.value;
if (as.right.value.vt == VT.CONSTANT) {// remove new if (as.op2.value.vt == VT.CONSTANT) {// remove new
Constant c = (Constant) as.right.value; Constant c = (Constant) as.op2.value;
if (NEW_TYPE.equals(c.type)) { if (NEW_TYPE.equals(c.type)) {
list.remove(st); list.remove(st);
for (Iterator<AssignStmt> it = je._ls_inits.iterator(); it.hasNext();) { for (Iterator<AssignStmt> it = je._ls_inits.iterator(); it.hasNext();) {
AssignStmt stmt = it.next(); AssignStmt stmt = it.next();
InvokeExpr ie = (InvokeExpr) stmt.right.value; InvokeExpr ie = (InvokeExpr) stmt.op2.value;
if (ie.args[0].value == aLeft) { if (ie.ops[0].value == aLeft) {
it.remove(); it.remove();
ValueBox[] vb = new ValueBox[ie.args.length - 1]; ValueBox[] vb = new ValueBox[ie.ops.length - 1];
System.arraycopy(ie.args, 1, vb, 0, vb.length); System.arraycopy(ie.ops, 1, vb, 0, vb.length);
AssignStmt nas = Stmts.nAssign(as.left, AssignStmt nas = Stmts.nAssign(as.op1,
new ValueBox(Exprs.nInvokeNew(vb, ie.argmentTypes, ie.methodOwnerType))); new ValueBox(Exprs.nInvokeNew(vb, ie.argmentTypes, ie.methodOwnerType)));
list.replace(stmt, nas); list.replace(stmt, nas);
aLeft._ls_read_count--; aLeft._ls_read_count--;
orderList.set(orderList.indexOf(stmt), nas); orderList.set(orderList.indexOf(stmt), nas);
} }
} }
continue;
} }
continue;
} }
if (aLeft._ls_write_count == 1) { if (aLeft._ls_write_count == 1) {
switch (as.right.value.vt) { switch (as.op2.value.vt) {
case LOCAL: { case LOCAL: {
Local b = (Local) as.right.value; Local b = (Local) as.op2.value;
b._ls_read_count += aLeft._ls_read_count - 1; b._ls_read_count += aLeft._ls_read_count - 1;
je.locals.remove(aLeft); je.locals.remove(aLeft);
aLeft._ls_vb.value = b; aLeft._ls_vb.value = b;
@ -84,7 +83,7 @@ public class LocalRemover implements Transformer {
continue; continue;
} }
case CONSTANT: { case CONSTANT: {
as.left.value = as.right.value; as.op1.value = as.op2.value;
je.locals.remove(aLeft); je.locals.remove(aLeft);
list.remove(st); list.remove(st);
orderList.set(p, null); orderList.set(p, null);
@ -127,7 +126,7 @@ public class LocalRemover implements Transformer {
vbs.clear(); vbs.clear();
tmp.clear(); tmp.clear();
AssignStmt as = (AssignStmt) pre; AssignStmt as = (AssignStmt) pre;
Local preLocal = (Local) as.left.value; Local preLocal = (Local) as.op1.value;
execStmt(vbs, st, preLocal); execStmt(vbs, st, preLocal);
for (ValueBox vb : vbs) { for (ValueBox vb : vbs) {
switch (vb.value.vt) { switch (vb.value.vt) {
@ -142,13 +141,13 @@ public class LocalRemover implements Transformer {
while (!tmp.isEmpty()) { while (!tmp.isEmpty()) {
ValueBox vb = tmp.pop(); ValueBox vb = tmp.pop();
if (vb.value == preLocal) { if (vb.value == preLocal) {
vb.value = as.right.value; vb.value = as.op2.value;
list.remove(as); list.remove(as);
je.locals.remove(preLocal); je.locals.remove(preLocal);
pre = st.getPre(); pre = st.getPre();
if (pre != null && canRemove(pre)) { if (pre != null && canRemove(pre)) {
as = (AssignStmt) pre; as = (AssignStmt) pre;
preLocal = (Local) as.left.value; preLocal = (Local) as.op1.value;
} else { } else {
break; break;
} }
@ -163,11 +162,12 @@ public class LocalRemover implements Transformer {
private static boolean canRemove(Stmt pre) { private static boolean canRemove(Stmt pre) {
switch (pre.st) { switch (pre.st) {
case ASSIGN: case ASSIGN:
case IDENTITY:
AssignStmt as = (AssignStmt) pre; AssignStmt as = (AssignStmt) pre;
if (as.left.value.vt == VT.LOCAL) { if (as.op1.value.vt == VT.LOCAL) {
Local aLeft = (Local) as.left.value; Local aLeft = (Local) as.op1.value;
if (aLeft._ls_write_count == 1 && aLeft._ls_read_count == 1) { if (aLeft._ls_write_count == 1 && aLeft._ls_read_count == 1) {
switch (as.right.value.vt) { switch (as.op2.value.vt) {
case THIS_REF: case THIS_REF:
case PARAMETER_REF: case PARAMETER_REF:
case EXCEPTION_REF: case EXCEPTION_REF:
@ -192,23 +192,24 @@ public class LocalRemover implements Transformer {
switch (st.st) { switch (st.st) {
case ASSIGN: case ASSIGN:
case IDENTITY:
AssignStmt as = (AssignStmt) st; AssignStmt as = (AssignStmt) st;
if (as.left.value.vt != VT.LOCAL) { if (as.op1.value.vt != VT.LOCAL) {
execValue(stack, as.left, local); execValue(stack, as.op1, local);
} }
execValue(stack, as.right, local); execValue(stack, as.op2, local);
break; break;
case IF: case IF:
JumpStmt js = (JumpStmt) st; JumpStmt js = (JumpStmt) st;
execValue(stack, js.condition, local); execValue(stack, js.op, local);
break; break;
case LOOKUP_SWITCH: case LOOKUP_SWITCH:
LookupSwitchStmt lss = (LookupSwitchStmt) st; LookupSwitchStmt lss = (LookupSwitchStmt) st;
execValue(stack, lss.key, local); execValue(stack, lss.op, local);
break; break;
case TABLE_SWITCH: case TABLE_SWITCH:
TableSwitchStmt tss = (TableSwitchStmt) st; TableSwitchStmt tss = (TableSwitchStmt) st;
execValue(stack, tss.key, local); execValue(stack, tss.op, local);
break; break;
case RETURN: case RETURN:
case LOCK: case LOCK:
@ -261,17 +262,17 @@ public class LocalRemover implements Transformer {
} }
case ARRAY: case ARRAY:
ArrayExpr ae = (ArrayExpr) toReplace; ArrayExpr ae = (ArrayExpr) toReplace;
stack.add(ae.base); stack.add(ae.op1);
stack.add(ae.index); stack.add(ae.op2);
break; break;
case FIELD: case FIELD:
FieldExpr fe = (FieldExpr) toReplace; FieldExpr fe = (FieldExpr) toReplace;
if (fe.object != null) {// not a static field if (fe.op != null) {// not a static field
stack.add(fe.object); stack.add(fe.op);
} }
break; break;
case CAST: case CAST:
CastExpr ce = (CastExpr) toReplace; TypeExpr ce = (TypeExpr) toReplace;
stack.add(ce.op); stack.add(ce.op);
break; break;
case CMP: case CMP:
@ -288,8 +289,9 @@ public class LocalRemover implements Transformer {
stack.add(be.op2); stack.add(be.op2);
break; break;
} }
case NEW_ARRAY:
case INSTANCEOF: case INSTANCEOF:
InstanceOfExpr iof = (InstanceOfExpr) toReplace; TypeExpr iof = (TypeExpr) toReplace;
stack.add(iof.op); stack.add(iof.op);
break; break;
case INVOKE_INTERFACE: case INVOKE_INTERFACE:
@ -298,7 +300,7 @@ public class LocalRemover implements Transformer {
case INVOKE_NEW: case INVOKE_NEW:
case INVOKE_STATIC: case INVOKE_STATIC:
InvokeExpr ie = (InvokeExpr) toReplace; InvokeExpr ie = (InvokeExpr) toReplace;
for (ValueBox vb : ie.args) { for (ValueBox vb : ie.ops) {
stack.add(vb); stack.add(vb);
} }
break; break;
@ -308,13 +310,10 @@ public class LocalRemover implements Transformer {
UnopExpr ue = (UnopExpr) toReplace; UnopExpr ue = (UnopExpr) toReplace;
stack.add(ue.op); stack.add(ue.op);
break; break;
case NEW_ARRAY:
NewArrayExpr nae = (NewArrayExpr) toReplace;
stack.add(nae.size);
break;
case NEW_MUTI_ARRAY: case NEW_MUTI_ARRAY:
NewMutiArrayExpr nmae = (NewMutiArrayExpr) toReplace; NewMutiArrayExpr nmae = (NewMutiArrayExpr) toReplace;
for (ValueBox vb : nmae.sizes) { for (ValueBox vb : nmae.ops) {
stack.add(vb); stack.add(vb);
} }
break; break;

View File

@ -12,13 +12,11 @@ import com.googlecode.dex2jar.ir.Value.VT;
import com.googlecode.dex2jar.ir.ValueBox; import com.googlecode.dex2jar.ir.ValueBox;
import com.googlecode.dex2jar.ir.expr.ArrayExpr; import com.googlecode.dex2jar.ir.expr.ArrayExpr;
import com.googlecode.dex2jar.ir.expr.BinopExpr; import com.googlecode.dex2jar.ir.expr.BinopExpr;
import com.googlecode.dex2jar.ir.expr.CastExpr;
import com.googlecode.dex2jar.ir.expr.Exprs; import com.googlecode.dex2jar.ir.expr.Exprs;
import com.googlecode.dex2jar.ir.expr.FieldExpr; import com.googlecode.dex2jar.ir.expr.FieldExpr;
import com.googlecode.dex2jar.ir.expr.InstanceOfExpr;
import com.googlecode.dex2jar.ir.expr.InvokeExpr; import com.googlecode.dex2jar.ir.expr.InvokeExpr;
import com.googlecode.dex2jar.ir.expr.NewArrayExpr;
import com.googlecode.dex2jar.ir.expr.NewMutiArrayExpr; import com.googlecode.dex2jar.ir.expr.NewMutiArrayExpr;
import com.googlecode.dex2jar.ir.expr.TypeExpr;
import com.googlecode.dex2jar.ir.expr.UnopExpr; import com.googlecode.dex2jar.ir.expr.UnopExpr;
import com.googlecode.dex2jar.ir.stmt.AssignStmt; import com.googlecode.dex2jar.ir.stmt.AssignStmt;
import com.googlecode.dex2jar.ir.stmt.JumpStmt; import com.googlecode.dex2jar.ir.stmt.JumpStmt;
@ -104,11 +102,12 @@ public class LocalSpliter implements Transformer {
toVisitStack.push(lss.defaultTarget); toVisitStack.push(lss.defaultTarget);
break; break;
case ASSIGN: case ASSIGN:
case IDENTITY:
AssignStmt assignStmt = (AssignStmt) currentStmt; AssignStmt assignStmt = (AssignStmt) currentStmt;
if (assignStmt.left.value.vt == VT.LOCAL) { if (assignStmt.op1.value.vt == VT.LOCAL) {
System.arraycopy(currentFrame, 0, tmp, 0, tmp.length); System.arraycopy(currentFrame, 0, tmp, 0, tmp.length);
Local local = (Local) assignStmt.left.value; Local local = (Local) assignStmt.op1.value;
int reg = local._ls_index; int reg = local._ls_index;
Stmt next = currentStmt.getNext(); Stmt next = currentStmt.getNext();
ValueBox vb; ValueBox vb;
@ -128,13 +127,12 @@ public class LocalSpliter implements Transformer {
tmp[reg] = vb; tmp[reg] = vb;
currentFrame = tmp; currentFrame = tmp;
mergeFrame2Stmt(currentFrame, currentStmt.getNext(), locals); mergeFrame2Stmt(currentFrame, currentStmt.getNext(), locals);
assignStmt.left = ((Local) vb.value)._ls_vb; assignStmt.op1 = ((Local) vb.value)._ls_vb;
} else { } else {
mergeFrame2Stmt(currentFrame, currentStmt.getNext(), locals); mergeFrame2Stmt(currentFrame, currentStmt.getNext(), locals);
} }
toVisitStack.push(currentStmt.getNext()); toVisitStack.push(currentStmt.getNext());
break; break;
case IDENTITY:
case NOP: case NOP:
case LABEL: case LABEL:
case LOCK: case LOCK:
@ -166,12 +164,13 @@ public class LocalSpliter implements Transformer {
exec(st); exec(st);
switch (st.st) { switch (st.st) {
case ASSIGN: case ASSIGN:
case IDENTITY:
AssignStmt as = (AssignStmt) st; AssignStmt as = (AssignStmt) st;
if (as.left.value.vt == VT.LOCAL) { if (as.op1.value.vt == VT.LOCAL) {
as.left = ((Local) as.left.value)._ls_vb; as.op1 = ((Local) as.op1.value)._ls_vb;
} }
if (as.right.value.vt == VT.INVOKE_SPECIAL) { if (as.op2.value.vt == VT.INVOKE_SPECIAL) {
InvokeExpr ie = (InvokeExpr) as.right.value; InvokeExpr ie = (InvokeExpr) as.op2.value;
if (ie.methodName.equals("<init>")) { if (ie.methodName.equals("<init>")) {
jm._ls_inits.add(as); jm._ls_inits.add(as);
} }
@ -191,28 +190,26 @@ public class LocalSpliter implements Transformer {
ValueBox[] frame = st._ls_frame; ValueBox[] frame = st._ls_frame;
switch (st.st) { switch (st.st) {
case ASSIGN: case ASSIGN:
case IDENTITY:
AssignStmt assignStmt = (AssignStmt) st; AssignStmt assignStmt = (AssignStmt) st;
if (assignStmt.left.value.vt != VT.LOCAL) { if (assignStmt.op1.value.vt != VT.LOCAL) {
assignStmt.left = execValue(assignStmt.left, frame); assignStmt.op1 = execValue(assignStmt.op1, frame);
} }
assignStmt.right = execValue(assignStmt.right, frame); assignStmt.op2 = execValue(assignStmt.op2, frame);
break; break;
case GOTO: case GOTO:
case NOP: case NOP:
case LABEL: case LABEL:
case RETURN_VOID: case RETURN_VOID:
break; break;
case IDENTITY:
break;
case IF: case IF:
((JumpStmt) st).condition = execValue(((JumpStmt) st).condition, frame); ((JumpStmt) st).op = execValue(((JumpStmt) st).op, frame);
break; break;
case LOOKUP_SWITCH: case LOOKUP_SWITCH:
((LookupSwitchStmt) st).key = execValue(((LookupSwitchStmt) st).key, frame); ((LookupSwitchStmt) st).op = execValue(((LookupSwitchStmt) st).op, frame);
break; break;
case TABLE_SWITCH: case TABLE_SWITCH:
((TableSwitchStmt) st).key = execValue(((TableSwitchStmt) st).key, frame); ((TableSwitchStmt) st).op = execValue(((TableSwitchStmt) st).op, frame);
break; break;
case LOCK: case LOCK:
case THROW: case THROW:
@ -229,18 +226,16 @@ public class LocalSpliter implements Transformer {
Local local = (Local) frame[((Local) vb.value)._ls_index].value; Local local = (Local) frame[((Local) vb.value)._ls_index].value;
local._ls_read_count++; local._ls_read_count++;
return ((Local) frame[((Local) vb.value)._ls_index].value)._ls_vb; return ((Local) frame[((Local) vb.value)._ls_index].value)._ls_vb;
case CAST:
CastExpr ce = (CastExpr) vb.value;
ce.op = execValue(ce.op, frame);
break;
case FIELD: case FIELD:
FieldExpr fe = (FieldExpr) vb.value; FieldExpr fe = (FieldExpr) vb.value;
if (null != fe.object) { if (null != fe.op) {
fe.object = execValue(fe.object, frame); fe.op = execValue(fe.op, frame);
} }
break; break;
case INSTANCEOF: case INSTANCEOF:
InstanceOfExpr ioe = (InstanceOfExpr) vb.value; case NEW_ARRAY:
case CAST:
TypeExpr ioe = (TypeExpr) vb.value;
ioe.op = execValue(ioe.op, frame); ioe.op = execValue(ioe.op, frame);
break; break;
case LENGTH: case LENGTH:
@ -249,22 +244,16 @@ public class LocalSpliter implements Transformer {
UnopExpr ue = (UnopExpr) vb.value; UnopExpr ue = (UnopExpr) vb.value;
ue.op = execValue(ue.op, frame); ue.op = execValue(ue.op, frame);
break; break;
case NEW_ARRAY:
NewArrayExpr nae = (NewArrayExpr) vb.value;
execValue(nae.size, frame);
break;
case NEW_MUTI_ARRAY: case NEW_MUTI_ARRAY:
NewMutiArrayExpr nmae = (NewMutiArrayExpr) vb.value; NewMutiArrayExpr nmae = (NewMutiArrayExpr) vb.value;
for (int i = 0; i < nmae.sizes.length; i++) { for (int i = 0; i < nmae.ops.length; i++) {
nmae.sizes[i] = execValue(nmae.sizes[i], frame); nmae.ops[i] = execValue(nmae.ops[i], frame);
} }
break; break;
case ARRAY: case ARRAY:
ArrayExpr ae = (ArrayExpr) vb.value; ArrayExpr ae = (ArrayExpr) vb.value;
ae.base = execValue(ae.base, frame); ae.op1 = execValue(ae.op1, frame);
ae.index = execValue(ae.index, frame); ae.op2 = execValue(ae.op2, frame);
break; break;
case CMP: case CMP:
case CMPG: case CMPG:
@ -296,8 +285,8 @@ public class LocalSpliter implements Transformer {
case INVOKE_INTERFACE: case INVOKE_INTERFACE:
case INVOKE_NEW: case INVOKE_NEW:
InvokeExpr methodExpr = (InvokeExpr) vb.value; InvokeExpr methodExpr = (InvokeExpr) vb.value;
for (int i = 0; i < methodExpr.args.length; i++) { for (int i = 0; i < methodExpr.ops.length; i++) {
methodExpr.args[i] = execValue(methodExpr.args[i], frame); methodExpr.ops[i] = execValue(methodExpr.ops[i], frame);
} }
break; break;
case EXCEPTION_REF: case EXCEPTION_REF:

View File

@ -13,6 +13,7 @@ import static com.googlecode.dex2jar.ir.expr.Exprs.nLocal;
import static com.googlecode.dex2jar.ir.expr.Exprs.nNewArray; import static com.googlecode.dex2jar.ir.expr.Exprs.nNewArray;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nAssign; import static com.googlecode.dex2jar.ir.stmt.Stmts.nAssign;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nGoto; import static com.googlecode.dex2jar.ir.stmt.Stmts.nGoto;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nIdentity;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nIf; import static com.googlecode.dex2jar.ir.stmt.Stmts.nIf;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nLabel; import static com.googlecode.dex2jar.ir.stmt.Stmts.nLabel;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nReturn; import static com.googlecode.dex2jar.ir.stmt.Stmts.nReturn;
@ -207,7 +208,7 @@ public class LocalRemoverTest {
list.add(L2); list.add(L2);
list.add(nGoto(L4)); list.add(nGoto(L4));
list.add(L3); list.add(L3);
list.add(nAssign(ex, nExceptionRef(exType))); list.add(nIdentity(ex, nExceptionRef(exType)));
list.add(nAssign(ex, list.add(nAssign(ex,
nInvokeVirtual(new Value[] { ex }, exType, "toString", new Type[0], Type.getType(String.class)))); nInvokeVirtual(new Value[] { ex }, exType, "toString", new Type[0], Type.getType(String.class))));
list.add(nAssign(b, nNull())); list.add(nAssign(b, nNull()));

View File

@ -13,6 +13,7 @@ import static com.googlecode.dex2jar.ir.expr.Exprs.nLocal;
import static com.googlecode.dex2jar.ir.expr.Exprs.nNewArray; import static com.googlecode.dex2jar.ir.expr.Exprs.nNewArray;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nAssign; import static com.googlecode.dex2jar.ir.stmt.Stmts.nAssign;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nGoto; import static com.googlecode.dex2jar.ir.stmt.Stmts.nGoto;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nIdentity;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nIf; import static com.googlecode.dex2jar.ir.stmt.Stmts.nIf;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nLabel; import static com.googlecode.dex2jar.ir.stmt.Stmts.nLabel;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nReturn; import static com.googlecode.dex2jar.ir.stmt.Stmts.nReturn;
@ -54,7 +55,7 @@ public class LocalSplitTest {
new LocalSpliter().transform(jm); new LocalSpliter().transform(jm);
Assert.assertTrue(jm.locals.size() == 2); Assert.assertTrue(jm.locals.size() == 2);
Assert.assertEquals(st2.left.value, st3.op.value); Assert.assertEquals(st2.op1.value, st3.op.value);
} }
@Test @Test
@ -106,7 +107,7 @@ public class LocalSplitTest {
list.add(L2); list.add(L2);
list.add(nGoto(L4)); list.add(nGoto(L4));
list.add(L3); list.add(L3);
list.add(nAssign(ex, nExceptionRef(exType))); list.add(nIdentity(ex, nExceptionRef(exType)));
list.add(nAssign(ex, list.add(nAssign(ex,
nInvokeVirtual(new Value[] { ex }, exType, "toString", new Type[0], Type.getType(String.class)))); nInvokeVirtual(new Value[] { ex }, exType, "toString", new Type[0], Type.getType(String.class))));
list.add(nAssign(b, nNull())); list.add(nAssign(b, nNull()));

View File

@ -59,6 +59,7 @@ import static com.googlecode.dex2jar.ir.expr.Exprs.nUshr;
import static com.googlecode.dex2jar.ir.expr.Exprs.nXor; import static com.googlecode.dex2jar.ir.expr.Exprs.nXor;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nAssign; import static com.googlecode.dex2jar.ir.stmt.Stmts.nAssign;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nGoto; import static com.googlecode.dex2jar.ir.stmt.Stmts.nGoto;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nIdentity;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nIf; import static com.googlecode.dex2jar.ir.stmt.Stmts.nIf;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nLabel; import static com.googlecode.dex2jar.ir.stmt.Stmts.nLabel;
import static com.googlecode.dex2jar.ir.stmt.Stmts.nLock; import static com.googlecode.dex2jar.ir.stmt.Stmts.nLock;
@ -137,14 +138,14 @@ public class V3CodeAdapter implements DexCodeVisitor, Opcodes, DexOpcodes {
int i = 0; int i = 0;
if ((irMethod.access & ACC_STATIC) == 0) { if ((irMethod.access & ACC_STATIC) == 0) {
Local _this = nLocal("this", this.irMethod.owner); Local _this = nLocal("this", this.irMethod.owner);
list.add(nAssign(_this, nThisRef(this.irMethod.owner))); list.add(nIdentity(_this, nThisRef(this.irMethod.owner)));
locals[args[i]] = _this; locals[args[i]] = _this;
i++; i++;
} }
int j = 0; int j = 0;
for (; i < args.length; i++, j++) { for (; i < args.length; i++, j++) {
Local _arg = nLocal("arg_" + args[i], this.irMethod.args[j]); Local _arg = nLocal("arg_" + args[i], this.irMethod.args[j]);
list.add(nAssign(_arg, nParameterRef(this.irMethod.args[j], j))); list.add(nIdentity(_arg, nParameterRef(this.irMethod.args[j], j)));
locals[args[i]] = _arg; locals[args[i]] = _arg;
} }
} }
@ -480,13 +481,11 @@ public class V3CodeAdapter implements DexCodeVisitor, Opcodes, DexOpcodes {
@Override @Override
public void visitLookupSwitchStmt(int opcode, int aA, Label label, int[] cases, Label[] labels) { public void visitLookupSwitchStmt(int opcode, int aA, Label label, int[] cases, Label[] labels) {
Value vs[] = new Value[cases.length];
LabelStmt[] lss = new LabelStmt[cases.length]; LabelStmt[] lss = new LabelStmt[cases.length];
for (int i = 0; i < cases.length; i++) { for (int i = 0; i < cases.length; i++) {
vs[i] = nInt(cases[i]);
lss[i] = toLabelStmt(labels[i]); lss[i] = toLabelStmt(labels[i]);
} }
list.add(nLookupSwitch(locals[aA], vs, lss, toLabelStmt(label))); list.add(nLookupSwitch(locals[aA], cases, lss, toLabelStmt(label)));
} }
@Override @Override
@ -540,7 +539,7 @@ public class V3CodeAdapter implements DexCodeVisitor, Opcodes, DexOpcodes {
list.add(nAssign(locals[toReg], locals[tmp_reg])); list.add(nAssign(locals[toReg], locals[tmp_reg]));
break; break;
case OP_MOVE_EXCEPTION: case OP_MOVE_EXCEPTION:
list.add(nAssign(locals[toReg], nExceptionRef(Type.getType(Throwable.class)))); list.add(nIdentity(locals[toReg], nExceptionRef(Type.getType(Throwable.class))));
break; break;
} }
} }