mirror of
https://github.com/pxb1988/dex2jar.git
synced 2024-11-23 13:19:46 +00:00
修改IR结构
--HG-- branch : 0.0.9.x
This commit is contained in:
parent
627987347a
commit
346e1254b0
@ -2,7 +2,9 @@ package com.googlecode.dex2jar.ir;
|
||||
|
||||
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 Type STRING = Type.getType(String.class);
|
||||
|
5
dex-ir/src/main/java/com/googlecode/dex2jar/ir/ET.java
Normal file
5
dex-ir/src/main/java/com/googlecode/dex2jar/ir/ET.java
Normal file
@ -0,0 +1,5 @@
|
||||
package com.googlecode.dex2jar.ir;
|
||||
|
||||
public enum ET {
|
||||
E0, E1, E2, En
|
||||
}
|
@ -2,7 +2,9 @@ package com.googlecode.dex2jar.ir;
|
||||
|
||||
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 String name;
|
||||
|
||||
|
@ -2,18 +2,58 @@ package com.googlecode.dex2jar.ir;
|
||||
|
||||
public abstract class Value {
|
||||
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, //
|
||||
INVOKE_STATIC, SUB, USHR, INVOKE_VIRTUAL, INVOKE_NEW, XOR, LOCAL, CONSTANT, THIS_REF, PARAMETER_REF, EXCEPTION_REF, NOT
|
||||
}
|
||||
|
||||
final public VT vt;
|
||||
final public ET et;
|
||||
|
||||
/**
|
||||
* @param vt
|
||||
*/
|
||||
public Value(VT vt) {
|
||||
public Value(VT vt, ET et) {
|
||||
super();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,24 +1,20 @@
|
||||
package com.googlecode.dex2jar.ir.expr;
|
||||
|
||||
import com.googlecode.dex2jar.ir.Value;
|
||||
import com.googlecode.dex2jar.ir.Value.E2Expr;
|
||||
import com.googlecode.dex2jar.ir.ValueBox;
|
||||
|
||||
public class ArrayExpr extends Value {
|
||||
|
||||
public ValueBox base;
|
||||
public ValueBox index;
|
||||
public class ArrayExpr extends E2Expr {
|
||||
|
||||
public ArrayExpr() {
|
||||
super(VT.ARRAY);
|
||||
super(VT.ARRAY, null, null);
|
||||
}
|
||||
|
||||
public ArrayExpr(Value base, Value index) {
|
||||
super(VT.ARRAY);
|
||||
this.base = new ValueBox(base);
|
||||
this.index = new ValueBox(index);
|
||||
super(VT.ARRAY, new ValueBox(base), new ValueBox(index));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return base + "[" + index + "]";
|
||||
return op1 + "[" + op2 + "]";
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,13 @@
|
||||
package com.googlecode.dex2jar.ir.expr;
|
||||
|
||||
import com.googlecode.dex2jar.ir.Value;
|
||||
import com.googlecode.dex2jar.ir.Value.E2Expr;
|
||||
import com.googlecode.dex2jar.ir.ValueBox;
|
||||
|
||||
public class BinopExpr extends Value {
|
||||
|
||||
public ValueBox op1;
|
||||
public ValueBox op2;
|
||||
public class BinopExpr extends E2Expr {
|
||||
|
||||
public BinopExpr(VT type, Value op1, Value op2) {
|
||||
super(type);
|
||||
this.op1 = new ValueBox(op1);
|
||||
this.op2 = new ValueBox(op2);
|
||||
super(type, new ValueBox(op1), new ValueBox(op2));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@ -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 + ")";
|
||||
}
|
||||
|
||||
}
|
@ -9,7 +9,11 @@ import com.googlecode.dex2jar.ir.ValueBox;
|
||||
|
||||
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) {
|
||||
return new ValueBox[0];
|
||||
}
|
||||
@ -32,8 +36,8 @@ public final class Exprs {
|
||||
return new ArrayExpr(base, index);
|
||||
}
|
||||
|
||||
public static CastExpr nCast(Value obj, Type type) {
|
||||
return new CastExpr(obj, type);
|
||||
public static TypeExpr nCast(Value obj, Type type) {
|
||||
return new TypeExpr(obj, type);
|
||||
}
|
||||
|
||||
public static BinopExpr nCmp(Value a, Value b) {
|
||||
@ -56,8 +60,8 @@ public final class Exprs {
|
||||
return new BinopExpr(VT.EQ, a, b);
|
||||
}
|
||||
|
||||
public static TypeRefExpr nExceptionRef(Type type) {
|
||||
return new TypeRefExpr(VT.EXCEPTION_REF, type, -1);
|
||||
public static RefExpr nExceptionRef(Type type) {
|
||||
return new RefExpr(VT.EXCEPTION_REF, type, -1);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public static InstanceOfExpr nInstanceOf(Value value, Type type) {
|
||||
return new InstanceOfExpr(value, type);
|
||||
public static TypeExpr nInstanceOf(Value value, Type type) {
|
||||
return new TypeExpr(value, type);
|
||||
}
|
||||
|
||||
public static InvokeExpr nInvokeInterface(Value[] regs, Type owner, String name, Type[] argmentTypes,
|
||||
@ -137,20 +141,20 @@ public final class Exprs {
|
||||
// return new NewExpr(type);
|
||||
// }
|
||||
|
||||
public static NewArrayExpr nNewArray(Type elementType, Value size) {
|
||||
return new NewArrayExpr(elementType, size);
|
||||
public static TypeExpr nNewArray(Type elementType, Value size) {
|
||||
return new TypeExpr(size, elementType);
|
||||
}
|
||||
|
||||
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) {
|
||||
return new BinopExpr(VT.OR, a, b);
|
||||
}
|
||||
|
||||
public static TypeRefExpr nParameterRef(Type type, int index) {
|
||||
return new TypeRefExpr(VT.PARAMETER_REF, type, index);
|
||||
public static RefExpr nParameterRef(Type type, int index) {
|
||||
return new RefExpr(VT.PARAMETER_REF, type, index);
|
||||
}
|
||||
|
||||
public static BinopExpr nRem(Value a, Value b) {
|
||||
@ -173,8 +177,8 @@ public final class Exprs {
|
||||
return new BinopExpr(VT.SUB, a, b);
|
||||
}
|
||||
|
||||
public static TypeRefExpr nThisRef(Type type) {
|
||||
return new TypeRefExpr(VT.THIS_REF, type, -1);
|
||||
public static RefExpr nThisRef(Type type) {
|
||||
return new RefExpr(VT.THIS_REF, type, -1);
|
||||
}
|
||||
|
||||
public static BinopExpr nUshr(Value a, Value b) {
|
||||
|
@ -2,26 +2,25 @@ 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 FieldExpr extends Value {
|
||||
public class FieldExpr extends E1Expr {
|
||||
|
||||
public String fieldName;
|
||||
public Type fieldType;
|
||||
public Type fieldOwnerType;
|
||||
public ValueBox object;
|
||||
public ValueBox op;
|
||||
|
||||
public FieldExpr(ValueBox object, Type ownerType, String fieldName, Type fieldType) {
|
||||
super(VT.FIELD);
|
||||
this.object = object;
|
||||
super(VT.FIELD,object);
|
||||
this.fieldType = fieldType;
|
||||
this.fieldName = fieldName;
|
||||
this.fieldOwnerType = ownerType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return (object == null ? fieldOwnerType.getClassName() : object) + "." + fieldName;
|
||||
return (op == null ? fieldOwnerType.getClassName() : op) + "." + fieldName;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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() + ")";
|
||||
}
|
||||
}
|
@ -2,25 +2,22 @@ package com.googlecode.dex2jar.ir.expr;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import com.googlecode.dex2jar.ir.Value;
|
||||
import com.googlecode.dex2jar.ir.Value.EnExpr;
|
||||
import com.googlecode.dex2jar.ir.ValueBox;
|
||||
|
||||
public class InvokeExpr extends Value {
|
||||
public class InvokeExpr extends EnExpr {
|
||||
|
||||
public Type[] argmentTypes;
|
||||
public ValueBox args[];
|
||||
public String methodName;
|
||||
public Type methodOwnerType;
|
||||
public Type methodReturnType;
|
||||
|
||||
public InvokeExpr(VT type, ValueBox[] args, Type ownerType, String methodName, Type[] argmentTypes, Type returnType) {
|
||||
super(type);
|
||||
super(type, args);
|
||||
this.methodReturnType = returnType;
|
||||
this.methodName = methodName;
|
||||
this.methodOwnerType = ownerType;
|
||||
this.argmentTypes = argmentTypes;
|
||||
this.args = args;
|
||||
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@ -29,18 +26,18 @@ public class InvokeExpr extends Value {
|
||||
if (super.vt == VT.INVOKE_NEW) {
|
||||
sb.append("new ").append(methodOwnerType.getClassName()).append('(');
|
||||
} 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('(');
|
||||
i++;
|
||||
}
|
||||
boolean first = true;
|
||||
for (; i < args.length; i++) {
|
||||
for (; i < ops.length; i++) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(args[i]);
|
||||
sb.append(ops[i]);
|
||||
}
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
|
@ -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 + "]";
|
||||
}
|
||||
}
|
@ -2,31 +2,26 @@ package com.googlecode.dex2jar.ir.expr;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import com.googlecode.dex2jar.ir.Value;
|
||||
import com.googlecode.dex2jar.ir.Value.EnExpr;
|
||||
import com.googlecode.dex2jar.ir.ValueBox;
|
||||
|
||||
|
||||
public class NewMutiArrayExpr extends Value {
|
||||
public class NewMutiArrayExpr extends EnExpr {
|
||||
|
||||
public Type baseType;
|
||||
public int dimension;
|
||||
public ValueBox[] sizes;
|
||||
|
||||
public NewMutiArrayExpr(Type base, int dimension, Value[] sizes) {
|
||||
super(VT.NEW_MUTI_ARRAY);
|
||||
public NewMutiArrayExpr(Type base, int dimension, ValueBox[] sizes) {
|
||||
super(VT.NEW_MUTI_ARRAY, sizes);
|
||||
this.baseType = base;
|
||||
this.dimension = dimension;
|
||||
this.sizes = new ValueBox[sizes.length];
|
||||
for (int i = 0; i < sizes.length; i++) {
|
||||
this.sizes[i] = new ValueBox(sizes[i]);
|
||||
}
|
||||
this.ops = new ValueBox[sizes.length];
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("new ").append(baseType);
|
||||
for (int i = 0; i < dimension; i++) {
|
||||
sb.append('[').append(sizes[i]).append(']');
|
||||
sb.append('[').append(ops[i]).append(']');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
@ -2,12 +2,12 @@ package com.googlecode.dex2jar.ir.expr;
|
||||
|
||||
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);
|
||||
this.parameterIndex = index;
|
||||
}
|
@ -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";
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +1,17 @@
|
||||
package com.googlecode.dex2jar.ir.expr;
|
||||
|
||||
import com.googlecode.dex2jar.ir.Value;
|
||||
import com.googlecode.dex2jar.ir.Value.E1Expr;
|
||||
import com.googlecode.dex2jar.ir.ValueBox;
|
||||
|
||||
public class UnopExpr extends Value {
|
||||
|
||||
public ValueBox op;
|
||||
public class UnopExpr extends E1Expr {
|
||||
|
||||
/**
|
||||
* @param type
|
||||
* @param value
|
||||
*/
|
||||
public UnopExpr(VT type, Value value) {
|
||||
super(type);
|
||||
this.op = new ValueBox(value);
|
||||
super(type, new ValueBox(value));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@ -1,38 +1,20 @@
|
||||
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.stmt.Stmt.E2Stmt;
|
||||
|
||||
public class AssignStmt extends Stmt {
|
||||
|
||||
public ValueBox left;
|
||||
public ValueBox right;
|
||||
public class AssignStmt extends E2Stmt {
|
||||
|
||||
public AssignStmt(ST type, ValueBox left, ValueBox right) {
|
||||
super(type);
|
||||
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);
|
||||
super(type, left, right);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
switch (st) {
|
||||
case ASSIGN:
|
||||
return left + " = " + right;
|
||||
return op1 + " = " + op2;
|
||||
case IDENTITY:
|
||||
return left + " := " + right;
|
||||
return op1 + " := " + op2;
|
||||
}
|
||||
return super.toString();
|
||||
}
|
||||
|
@ -1,20 +1,12 @@
|
||||
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.stmt.Stmt.E1Stmt;
|
||||
|
||||
public class JumpStmt extends E1Stmt {
|
||||
|
||||
public class JumpStmt extends Stmt {
|
||||
|
||||
public ValueBox condition;
|
||||
public LabelStmt target;
|
||||
|
||||
private JumpStmt(ST type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* GOTO
|
||||
*
|
||||
@ -22,8 +14,7 @@ public class JumpStmt extends Stmt {
|
||||
* @param target
|
||||
*/
|
||||
public JumpStmt(ST type, LabelStmt target) {
|
||||
this(type);
|
||||
this.target = target;
|
||||
this(type, null, target);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -33,14 +24,9 @@ public class JumpStmt extends Stmt {
|
||||
* @param condition
|
||||
* @param target
|
||||
*/
|
||||
public JumpStmt(ST type, Value condition, LabelStmt target) {
|
||||
this(type, target);
|
||||
this.condition = new ValueBox(condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stmt clone(Map<LabelStmt, LabelStmt> map) {
|
||||
return new JumpStmt(st, condition.value, (LabelStmt) target.clone(map));
|
||||
public JumpStmt(ST type, ValueBox condition, LabelStmt target) {
|
||||
super(type, condition);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@ -48,7 +34,7 @@ public class JumpStmt extends Stmt {
|
||||
case GOTO:
|
||||
return "GOTO " + target;
|
||||
case IF:
|
||||
return "if " + condition + " GOTO " + target;
|
||||
return "if " + op + " GOTO " + target;
|
||||
}
|
||||
return super.toString();
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.googlecode.dex2jar.ir.stmt;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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) {
|
||||
super(ST.LABEL);
|
||||
@ -13,16 +13,6 @@ public class LabelStmt extends Stmt {
|
||||
|
||||
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() {
|
||||
return label + ":";
|
||||
}
|
||||
|
@ -1,50 +1,23 @@
|
||||
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.stmt.Stmt.E1Stmt;
|
||||
|
||||
|
||||
public class LookupSwitchStmt extends Stmt {
|
||||
public class LookupSwitchStmt extends E1Stmt {
|
||||
|
||||
public LabelStmt defaultTarget;
|
||||
public ValueBox key;
|
||||
public Value[] lookupValues;
|
||||
public int[] lookupValues;
|
||||
public LabelStmt[] targets;
|
||||
|
||||
public LookupSwitchStmt() {
|
||||
super(ST.LOOKUP_SWITCH);
|
||||
}
|
||||
|
||||
public LookupSwitchStmt(Value key, Value[] lookupValues, LabelStmt[] targets, LabelStmt defaultTarget) {
|
||||
super(ST.LOOKUP_SWITCH);
|
||||
this.key = new ValueBox(key);
|
||||
public LookupSwitchStmt(ValueBox key, int[] lookupValues, LabelStmt[] targets, LabelStmt defaultTarget) {
|
||||
super(ST.LOOKUP_SWITCH, key);
|
||||
this.lookupValues = lookupValues;
|
||||
this.targets = targets;
|
||||
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() {
|
||||
StringBuilder sb = new StringBuilder("switch(").append(key).append(") {");
|
||||
StringBuilder sb = new StringBuilder("switch(").append(op).append(") {");
|
||||
|
||||
for (int i = 0; i < lookupValues.length; i++) {
|
||||
sb.append("case ").append(lookupValues[i]).append(": GOTO ").append(targets[i].label).append(";");
|
||||
|
@ -1,18 +1,13 @@
|
||||
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() {
|
||||
super(ST.NOP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stmt clone(Map<LabelStmt, LabelStmt> map) {
|
||||
return new NopStmt();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "NOP";
|
||||
}
|
||||
|
@ -1,18 +1,13 @@
|
||||
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() {
|
||||
super(ST.RETURN_VOID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stmt clone(Map<LabelStmt, LabelStmt> map) {
|
||||
return new ReturnVoidStmt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "return";
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.googlecode.dex2jar.ir.stmt;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.googlecode.dex2jar.ir.ET;
|
||||
import com.googlecode.dex2jar.ir.ValueBox;
|
||||
|
||||
public abstract class Stmt {
|
||||
@ -23,13 +23,13 @@ public abstract class Stmt {
|
||||
/* default */Stmt pre;
|
||||
|
||||
public final ST st;
|
||||
public final ET et;
|
||||
|
||||
public Stmt(ST type) {
|
||||
public Stmt(ST type, ET et) {
|
||||
this.st = type;
|
||||
this.et = et;
|
||||
}
|
||||
|
||||
public abstract Stmt clone(Map<LabelStmt, LabelStmt> map);
|
||||
|
||||
public final Stmt getNext() {
|
||||
return next;
|
||||
}
|
||||
@ -38,4 +38,39 @@ public abstract class Stmt {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.googlecode.dex2jar.ir.stmt;
|
||||
|
||||
import static com.googlecode.dex2jar.ir.expr.Exprs.box;
|
||||
|
||||
import org.objectweb.asm.Label;
|
||||
|
||||
import com.googlecode.dex2jar.ir.Value;
|
||||
@ -11,9 +13,9 @@ public final class Stmts {
|
||||
public static AssignStmt nAssign(ValueBox left, ValueBox right) {
|
||||
return new AssignStmt(ST.ASSIGN, left, 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) {
|
||||
@ -21,25 +23,27 @@ public final class Stmts {
|
||||
}
|
||||
|
||||
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) {
|
||||
return new JumpStmt(ST.IF, a, target);
|
||||
return new JumpStmt(ST.IF, box(a), target);
|
||||
}
|
||||
|
||||
public static LabelStmt nLabel() {
|
||||
return new LabelStmt(new Label());
|
||||
}
|
||||
|
||||
public static LabelStmt nLabel(Label label) {
|
||||
return new LabelStmt(label);
|
||||
}
|
||||
|
||||
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) {
|
||||
return new LookupSwitchStmt(key, lookupValues, targets, target);
|
||||
public static LookupSwitchStmt nLookupSwitch(Value key, int[] lookupValues, LabelStmt[] targets, LabelStmt target) {
|
||||
return new LookupSwitchStmt(box(key), lookupValues, targets, target);
|
||||
}
|
||||
|
||||
public static NopStmt nNop() {
|
||||
@ -47,7 +51,7 @@ public final class Stmts {
|
||||
}
|
||||
|
||||
public static UnopStmt nReturn(Value op) {
|
||||
return new UnopStmt(ST.RETURN, op);
|
||||
return new UnopStmt(ST.RETURN, box(op));
|
||||
}
|
||||
|
||||
public static ReturnVoidStmt nReturnVoid() {
|
||||
@ -60,11 +64,11 @@ public final class Stmts {
|
||||
}
|
||||
|
||||
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) {
|
||||
return new UnopStmt(ST.UNLOCK, op);
|
||||
return new UnopStmt(ST.UNLOCK, box(op));
|
||||
}
|
||||
|
||||
private Stmts() {
|
||||
|
@ -1,49 +1,29 @@
|
||||
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.stmt.Stmt.E1Stmt;
|
||||
|
||||
|
||||
public class TableSwitchStmt extends Stmt {
|
||||
public class TableSwitchStmt extends E1Stmt {
|
||||
|
||||
public LabelStmt defaultTarget;
|
||||
public ValueBox key;
|
||||
public int lowIndex, highIndex;
|
||||
public LabelStmt[] targets;
|
||||
|
||||
public TableSwitchStmt() {
|
||||
super(ST.TABLE_SWITCH);
|
||||
super(ST.TABLE_SWITCH, null);
|
||||
}
|
||||
|
||||
public TableSwitchStmt(Value key, int lowIndex, int highIndex, LabelStmt[] targets, LabelStmt defaultTarget) {
|
||||
super(ST.TABLE_SWITCH);
|
||||
this.key = new ValueBox(key);
|
||||
super(ST.TABLE_SWITCH, new ValueBox(key));
|
||||
this.lowIndex = lowIndex;
|
||||
this.highIndex = highIndex;
|
||||
this.targets = targets;
|
||||
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() {
|
||||
StringBuilder sb = new StringBuilder("switch(").append(key).append(") {");
|
||||
StringBuilder sb = new StringBuilder("switch(").append(op).append(") {");
|
||||
|
||||
for (int i = 0; i < targets.length; i++) {
|
||||
sb.append("case ").append(lowIndex + i).append(": GOTO ").append(targets[i].label).append(";");
|
||||
|
@ -1,23 +1,12 @@
|
||||
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.stmt.Stmt.E1Stmt;
|
||||
|
||||
public class UnopStmt extends E1Stmt {
|
||||
|
||||
public class UnopStmt extends Stmt {
|
||||
|
||||
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 UnopStmt(ST type, ValueBox op) {
|
||||
super(type, op);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@ -15,13 +15,11 @@ import com.googlecode.dex2jar.ir.Value.VT;
|
||||
import com.googlecode.dex2jar.ir.ValueBox;
|
||||
import com.googlecode.dex2jar.ir.expr.ArrayExpr;
|
||||
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.FieldExpr;
|
||||
import com.googlecode.dex2jar.ir.expr.InstanceOfExpr;
|
||||
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.TypeExpr;
|
||||
import com.googlecode.dex2jar.ir.expr.UnopExpr;
|
||||
import com.googlecode.dex2jar.ir.stmt.AssignStmt;
|
||||
import com.googlecode.dex2jar.ir.stmt.JumpStmt;
|
||||
@ -48,34 +46,35 @@ public class LocalRemover implements Transformer {
|
||||
}
|
||||
switch (st.st) {
|
||||
case ASSIGN:
|
||||
case IDENTITY:
|
||||
AssignStmt as = (AssignStmt) st;
|
||||
if (as.left.value.vt == VT.LOCAL) {
|
||||
Local aLeft = (Local) as.left.value;
|
||||
if (as.right.value.vt == VT.CONSTANT) {// remove new
|
||||
Constant c = (Constant) as.right.value;
|
||||
if (as.op1.value.vt == VT.LOCAL) {
|
||||
Local aLeft = (Local) as.op1.value;
|
||||
if (as.op2.value.vt == VT.CONSTANT) {// remove new
|
||||
Constant c = (Constant) as.op2.value;
|
||||
if (NEW_TYPE.equals(c.type)) {
|
||||
list.remove(st);
|
||||
for (Iterator<AssignStmt> it = je._ls_inits.iterator(); it.hasNext();) {
|
||||
AssignStmt stmt = it.next();
|
||||
InvokeExpr ie = (InvokeExpr) stmt.right.value;
|
||||
if (ie.args[0].value == aLeft) {
|
||||
InvokeExpr ie = (InvokeExpr) stmt.op2.value;
|
||||
if (ie.ops[0].value == aLeft) {
|
||||
it.remove();
|
||||
ValueBox[] vb = new ValueBox[ie.args.length - 1];
|
||||
System.arraycopy(ie.args, 1, vb, 0, vb.length);
|
||||
AssignStmt nas = Stmts.nAssign(as.left,
|
||||
ValueBox[] vb = new ValueBox[ie.ops.length - 1];
|
||||
System.arraycopy(ie.ops, 1, vb, 0, vb.length);
|
||||
AssignStmt nas = Stmts.nAssign(as.op1,
|
||||
new ValueBox(Exprs.nInvokeNew(vb, ie.argmentTypes, ie.methodOwnerType)));
|
||||
list.replace(stmt, nas);
|
||||
aLeft._ls_read_count--;
|
||||
orderList.set(orderList.indexOf(stmt), nas);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (aLeft._ls_write_count == 1) {
|
||||
switch (as.right.value.vt) {
|
||||
switch (as.op2.value.vt) {
|
||||
case LOCAL: {
|
||||
Local b = (Local) as.right.value;
|
||||
Local b = (Local) as.op2.value;
|
||||
b._ls_read_count += aLeft._ls_read_count - 1;
|
||||
je.locals.remove(aLeft);
|
||||
aLeft._ls_vb.value = b;
|
||||
@ -84,7 +83,7 @@ public class LocalRemover implements Transformer {
|
||||
continue;
|
||||
}
|
||||
case CONSTANT: {
|
||||
as.left.value = as.right.value;
|
||||
as.op1.value = as.op2.value;
|
||||
je.locals.remove(aLeft);
|
||||
list.remove(st);
|
||||
orderList.set(p, null);
|
||||
@ -127,7 +126,7 @@ public class LocalRemover implements Transformer {
|
||||
vbs.clear();
|
||||
tmp.clear();
|
||||
AssignStmt as = (AssignStmt) pre;
|
||||
Local preLocal = (Local) as.left.value;
|
||||
Local preLocal = (Local) as.op1.value;
|
||||
execStmt(vbs, st, preLocal);
|
||||
for (ValueBox vb : vbs) {
|
||||
switch (vb.value.vt) {
|
||||
@ -142,13 +141,13 @@ public class LocalRemover implements Transformer {
|
||||
while (!tmp.isEmpty()) {
|
||||
ValueBox vb = tmp.pop();
|
||||
if (vb.value == preLocal) {
|
||||
vb.value = as.right.value;
|
||||
vb.value = as.op2.value;
|
||||
list.remove(as);
|
||||
je.locals.remove(preLocal);
|
||||
pre = st.getPre();
|
||||
if (pre != null && canRemove(pre)) {
|
||||
as = (AssignStmt) pre;
|
||||
preLocal = (Local) as.left.value;
|
||||
preLocal = (Local) as.op1.value;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -163,11 +162,12 @@ public class LocalRemover implements Transformer {
|
||||
private static boolean canRemove(Stmt pre) {
|
||||
switch (pre.st) {
|
||||
case ASSIGN:
|
||||
case IDENTITY:
|
||||
AssignStmt as = (AssignStmt) pre;
|
||||
if (as.left.value.vt == VT.LOCAL) {
|
||||
Local aLeft = (Local) as.left.value;
|
||||
if (as.op1.value.vt == VT.LOCAL) {
|
||||
Local aLeft = (Local) as.op1.value;
|
||||
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 PARAMETER_REF:
|
||||
case EXCEPTION_REF:
|
||||
@ -192,23 +192,24 @@ public class LocalRemover implements Transformer {
|
||||
|
||||
switch (st.st) {
|
||||
case ASSIGN:
|
||||
case IDENTITY:
|
||||
AssignStmt as = (AssignStmt) st;
|
||||
if (as.left.value.vt != VT.LOCAL) {
|
||||
execValue(stack, as.left, local);
|
||||
if (as.op1.value.vt != VT.LOCAL) {
|
||||
execValue(stack, as.op1, local);
|
||||
}
|
||||
execValue(stack, as.right, local);
|
||||
execValue(stack, as.op2, local);
|
||||
break;
|
||||
case IF:
|
||||
JumpStmt js = (JumpStmt) st;
|
||||
execValue(stack, js.condition, local);
|
||||
execValue(stack, js.op, local);
|
||||
break;
|
||||
case LOOKUP_SWITCH:
|
||||
LookupSwitchStmt lss = (LookupSwitchStmt) st;
|
||||
execValue(stack, lss.key, local);
|
||||
execValue(stack, lss.op, local);
|
||||
break;
|
||||
case TABLE_SWITCH:
|
||||
TableSwitchStmt tss = (TableSwitchStmt) st;
|
||||
execValue(stack, tss.key, local);
|
||||
execValue(stack, tss.op, local);
|
||||
break;
|
||||
case RETURN:
|
||||
case LOCK:
|
||||
@ -261,17 +262,17 @@ public class LocalRemover implements Transformer {
|
||||
}
|
||||
case ARRAY:
|
||||
ArrayExpr ae = (ArrayExpr) toReplace;
|
||||
stack.add(ae.base);
|
||||
stack.add(ae.index);
|
||||
stack.add(ae.op1);
|
||||
stack.add(ae.op2);
|
||||
break;
|
||||
case FIELD:
|
||||
FieldExpr fe = (FieldExpr) toReplace;
|
||||
if (fe.object != null) {// not a static field
|
||||
stack.add(fe.object);
|
||||
if (fe.op != null) {// not a static field
|
||||
stack.add(fe.op);
|
||||
}
|
||||
break;
|
||||
case CAST:
|
||||
CastExpr ce = (CastExpr) toReplace;
|
||||
TypeExpr ce = (TypeExpr) toReplace;
|
||||
stack.add(ce.op);
|
||||
break;
|
||||
case CMP:
|
||||
@ -288,8 +289,9 @@ public class LocalRemover implements Transformer {
|
||||
stack.add(be.op2);
|
||||
break;
|
||||
}
|
||||
case NEW_ARRAY:
|
||||
case INSTANCEOF:
|
||||
InstanceOfExpr iof = (InstanceOfExpr) toReplace;
|
||||
TypeExpr iof = (TypeExpr) toReplace;
|
||||
stack.add(iof.op);
|
||||
break;
|
||||
case INVOKE_INTERFACE:
|
||||
@ -298,7 +300,7 @@ public class LocalRemover implements Transformer {
|
||||
case INVOKE_NEW:
|
||||
case INVOKE_STATIC:
|
||||
InvokeExpr ie = (InvokeExpr) toReplace;
|
||||
for (ValueBox vb : ie.args) {
|
||||
for (ValueBox vb : ie.ops) {
|
||||
stack.add(vb);
|
||||
}
|
||||
break;
|
||||
@ -308,13 +310,10 @@ public class LocalRemover implements Transformer {
|
||||
UnopExpr ue = (UnopExpr) toReplace;
|
||||
stack.add(ue.op);
|
||||
break;
|
||||
case NEW_ARRAY:
|
||||
NewArrayExpr nae = (NewArrayExpr) toReplace;
|
||||
stack.add(nae.size);
|
||||
break;
|
||||
|
||||
case NEW_MUTI_ARRAY:
|
||||
NewMutiArrayExpr nmae = (NewMutiArrayExpr) toReplace;
|
||||
for (ValueBox vb : nmae.sizes) {
|
||||
for (ValueBox vb : nmae.ops) {
|
||||
stack.add(vb);
|
||||
}
|
||||
break;
|
||||
|
@ -12,13 +12,11 @@ import com.googlecode.dex2jar.ir.Value.VT;
|
||||
import com.googlecode.dex2jar.ir.ValueBox;
|
||||
import com.googlecode.dex2jar.ir.expr.ArrayExpr;
|
||||
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.FieldExpr;
|
||||
import com.googlecode.dex2jar.ir.expr.InstanceOfExpr;
|
||||
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.TypeExpr;
|
||||
import com.googlecode.dex2jar.ir.expr.UnopExpr;
|
||||
import com.googlecode.dex2jar.ir.stmt.AssignStmt;
|
||||
import com.googlecode.dex2jar.ir.stmt.JumpStmt;
|
||||
@ -104,11 +102,12 @@ public class LocalSpliter implements Transformer {
|
||||
toVisitStack.push(lss.defaultTarget);
|
||||
break;
|
||||
case ASSIGN:
|
||||
case IDENTITY:
|
||||
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);
|
||||
Local local = (Local) assignStmt.left.value;
|
||||
Local local = (Local) assignStmt.op1.value;
|
||||
int reg = local._ls_index;
|
||||
Stmt next = currentStmt.getNext();
|
||||
ValueBox vb;
|
||||
@ -128,13 +127,12 @@ public class LocalSpliter implements Transformer {
|
||||
tmp[reg] = vb;
|
||||
currentFrame = tmp;
|
||||
mergeFrame2Stmt(currentFrame, currentStmt.getNext(), locals);
|
||||
assignStmt.left = ((Local) vb.value)._ls_vb;
|
||||
assignStmt.op1 = ((Local) vb.value)._ls_vb;
|
||||
} else {
|
||||
mergeFrame2Stmt(currentFrame, currentStmt.getNext(), locals);
|
||||
}
|
||||
toVisitStack.push(currentStmt.getNext());
|
||||
break;
|
||||
case IDENTITY:
|
||||
case NOP:
|
||||
case LABEL:
|
||||
case LOCK:
|
||||
@ -166,12 +164,13 @@ public class LocalSpliter implements Transformer {
|
||||
exec(st);
|
||||
switch (st.st) {
|
||||
case ASSIGN:
|
||||
case IDENTITY:
|
||||
AssignStmt as = (AssignStmt) st;
|
||||
if (as.left.value.vt == VT.LOCAL) {
|
||||
as.left = ((Local) as.left.value)._ls_vb;
|
||||
if (as.op1.value.vt == VT.LOCAL) {
|
||||
as.op1 = ((Local) as.op1.value)._ls_vb;
|
||||
}
|
||||
if (as.right.value.vt == VT.INVOKE_SPECIAL) {
|
||||
InvokeExpr ie = (InvokeExpr) as.right.value;
|
||||
if (as.op2.value.vt == VT.INVOKE_SPECIAL) {
|
||||
InvokeExpr ie = (InvokeExpr) as.op2.value;
|
||||
if (ie.methodName.equals("<init>")) {
|
||||
jm._ls_inits.add(as);
|
||||
}
|
||||
@ -191,28 +190,26 @@ public class LocalSpliter implements Transformer {
|
||||
ValueBox[] frame = st._ls_frame;
|
||||
switch (st.st) {
|
||||
case ASSIGN:
|
||||
case IDENTITY:
|
||||
AssignStmt assignStmt = (AssignStmt) st;
|
||||
if (assignStmt.left.value.vt != VT.LOCAL) {
|
||||
assignStmt.left = execValue(assignStmt.left, frame);
|
||||
if (assignStmt.op1.value.vt != VT.LOCAL) {
|
||||
assignStmt.op1 = execValue(assignStmt.op1, frame);
|
||||
}
|
||||
assignStmt.right = execValue(assignStmt.right, frame);
|
||||
assignStmt.op2 = execValue(assignStmt.op2, frame);
|
||||
break;
|
||||
case GOTO:
|
||||
case NOP:
|
||||
case LABEL:
|
||||
|
||||
case RETURN_VOID:
|
||||
break;
|
||||
case IDENTITY:
|
||||
break;
|
||||
case IF:
|
||||
((JumpStmt) st).condition = execValue(((JumpStmt) st).condition, frame);
|
||||
((JumpStmt) st).op = execValue(((JumpStmt) st).op, frame);
|
||||
break;
|
||||
case LOOKUP_SWITCH:
|
||||
((LookupSwitchStmt) st).key = execValue(((LookupSwitchStmt) st).key, frame);
|
||||
((LookupSwitchStmt) st).op = execValue(((LookupSwitchStmt) st).op, frame);
|
||||
break;
|
||||
case TABLE_SWITCH:
|
||||
((TableSwitchStmt) st).key = execValue(((TableSwitchStmt) st).key, frame);
|
||||
((TableSwitchStmt) st).op = execValue(((TableSwitchStmt) st).op, frame);
|
||||
break;
|
||||
case LOCK:
|
||||
case THROW:
|
||||
@ -229,18 +226,16 @@ public class LocalSpliter implements Transformer {
|
||||
Local local = (Local) frame[((Local) vb.value)._ls_index].value;
|
||||
local._ls_read_count++;
|
||||
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:
|
||||
FieldExpr fe = (FieldExpr) vb.value;
|
||||
if (null != fe.object) {
|
||||
fe.object = execValue(fe.object, frame);
|
||||
if (null != fe.op) {
|
||||
fe.op = execValue(fe.op, frame);
|
||||
}
|
||||
break;
|
||||
case INSTANCEOF:
|
||||
InstanceOfExpr ioe = (InstanceOfExpr) vb.value;
|
||||
case NEW_ARRAY:
|
||||
case CAST:
|
||||
TypeExpr ioe = (TypeExpr) vb.value;
|
||||
ioe.op = execValue(ioe.op, frame);
|
||||
break;
|
||||
case LENGTH:
|
||||
@ -249,22 +244,16 @@ public class LocalSpliter implements Transformer {
|
||||
UnopExpr ue = (UnopExpr) vb.value;
|
||||
ue.op = execValue(ue.op, frame);
|
||||
break;
|
||||
|
||||
case NEW_ARRAY:
|
||||
NewArrayExpr nae = (NewArrayExpr) vb.value;
|
||||
execValue(nae.size, frame);
|
||||
|
||||
break;
|
||||
case NEW_MUTI_ARRAY:
|
||||
NewMutiArrayExpr nmae = (NewMutiArrayExpr) vb.value;
|
||||
for (int i = 0; i < nmae.sizes.length; i++) {
|
||||
nmae.sizes[i] = execValue(nmae.sizes[i], frame);
|
||||
for (int i = 0; i < nmae.ops.length; i++) {
|
||||
nmae.ops[i] = execValue(nmae.ops[i], frame);
|
||||
}
|
||||
break;
|
||||
case ARRAY:
|
||||
ArrayExpr ae = (ArrayExpr) vb.value;
|
||||
ae.base = execValue(ae.base, frame);
|
||||
ae.index = execValue(ae.index, frame);
|
||||
ae.op1 = execValue(ae.op1, frame);
|
||||
ae.op2 = execValue(ae.op2, frame);
|
||||
break;
|
||||
case CMP:
|
||||
case CMPG:
|
||||
@ -296,8 +285,8 @@ public class LocalSpliter implements Transformer {
|
||||
case INVOKE_INTERFACE:
|
||||
case INVOKE_NEW:
|
||||
InvokeExpr methodExpr = (InvokeExpr) vb.value;
|
||||
for (int i = 0; i < methodExpr.args.length; i++) {
|
||||
methodExpr.args[i] = execValue(methodExpr.args[i], frame);
|
||||
for (int i = 0; i < methodExpr.ops.length; i++) {
|
||||
methodExpr.ops[i] = execValue(methodExpr.ops[i], frame);
|
||||
}
|
||||
break;
|
||||
case EXCEPTION_REF:
|
||||
|
@ -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.stmt.Stmts.nAssign;
|
||||
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.nLabel;
|
||||
import static com.googlecode.dex2jar.ir.stmt.Stmts.nReturn;
|
||||
@ -207,7 +208,7 @@ public class LocalRemoverTest {
|
||||
list.add(L2);
|
||||
list.add(nGoto(L4));
|
||||
list.add(L3);
|
||||
list.add(nAssign(ex, nExceptionRef(exType)));
|
||||
list.add(nIdentity(ex, nExceptionRef(exType)));
|
||||
list.add(nAssign(ex,
|
||||
nInvokeVirtual(new Value[] { ex }, exType, "toString", new Type[0], Type.getType(String.class))));
|
||||
list.add(nAssign(b, nNull()));
|
||||
|
@ -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.stmt.Stmts.nAssign;
|
||||
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.nLabel;
|
||||
import static com.googlecode.dex2jar.ir.stmt.Stmts.nReturn;
|
||||
@ -54,7 +55,7 @@ public class LocalSplitTest {
|
||||
new LocalSpliter().transform(jm);
|
||||
|
||||
Assert.assertTrue(jm.locals.size() == 2);
|
||||
Assert.assertEquals(st2.left.value, st3.op.value);
|
||||
Assert.assertEquals(st2.op1.value, st3.op.value);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -106,7 +107,7 @@ public class LocalSplitTest {
|
||||
list.add(L2);
|
||||
list.add(nGoto(L4));
|
||||
list.add(L3);
|
||||
list.add(nAssign(ex, nExceptionRef(exType)));
|
||||
list.add(nIdentity(ex, nExceptionRef(exType)));
|
||||
list.add(nAssign(ex,
|
||||
nInvokeVirtual(new Value[] { ex }, exType, "toString", new Type[0], Type.getType(String.class))));
|
||||
list.add(nAssign(b, nNull()));
|
||||
|
@ -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.stmt.Stmts.nAssign;
|
||||
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.nLabel;
|
||||
import static com.googlecode.dex2jar.ir.stmt.Stmts.nLock;
|
||||
@ -137,14 +138,14 @@ public class V3CodeAdapter implements DexCodeVisitor, Opcodes, DexOpcodes {
|
||||
int i = 0;
|
||||
if ((irMethod.access & ACC_STATIC) == 0) {
|
||||
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;
|
||||
i++;
|
||||
}
|
||||
int j = 0;
|
||||
for (; i < args.length; i++, 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;
|
||||
}
|
||||
}
|
||||
@ -480,13 +481,11 @@ public class V3CodeAdapter implements DexCodeVisitor, Opcodes, DexOpcodes {
|
||||
|
||||
@Override
|
||||
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];
|
||||
for (int i = 0; i < cases.length; i++) {
|
||||
vs[i] = nInt(cases[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
|
||||
@ -540,7 +539,7 @@ public class V3CodeAdapter implements DexCodeVisitor, Opcodes, DexOpcodes {
|
||||
list.add(nAssign(locals[toReg], locals[tmp_reg]));
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user