com.googlecode.d2j.node.analysis.DvmFrame Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle Show documentation
Show all versions of gradle Show documentation
fakeradnroid gradle builder
package com.googlecode.d2j.node.analysis;
import com.googlecode.d2j.MethodHandle;
import com.googlecode.d2j.Proto;
import com.googlecode.d2j.node.insn.*;
import com.googlecode.d2j.reader.Op;
import java.util.ArrayList;
import java.util.List;
public class DvmFrame {
public V[] values;
public V tmp;
public DvmFrame(int totalRegister) {
values = (V[]) new Object[totalRegister];
}
public void setReg(int i, V v) {
if (i > values.length || i < 0) {
return;
}
values[i] = v;
}
public DvmFrame init(DvmFrame extends V> src) {
this.tmp = src.tmp;
System.arraycopy(src.values, 0, this.values, 0, this.values.length);
return this;
}
public void execute(DexStmtNode insn, DvmInterpreter interpreter) {
if (insn.op == null) {// label or others
return;
}
switch (insn.op) {
case CONST:
case CONST_4:
case CONST_16:
case CONST_HIGH16:
case CONST_WIDE:
case CONST_WIDE_16:
case CONST_WIDE_32:
case CONST_WIDE_HIGH16:
case CONST_STRING:
case CONST_STRING_JUMBO:
case CONST_CLASS:
setReg(((ConstStmtNode) insn).a, interpreter.newOperation(insn));
setTmp(null);
break;
case SGET:
case SGET_BOOLEAN:
case SGET_BYTE:
case SGET_CHAR:
case SGET_OBJECT:
case SGET_SHORT:
case SGET_WIDE:
setReg(((FieldStmtNode) insn).a, interpreter.newOperation(insn));
setTmp(null);
break;
case NEW_INSTANCE:
setReg(((TypeStmtNode) insn).a, interpreter.newOperation(insn));
setTmp(null);
break;
case MOVE:
case MOVE_16:
case MOVE_FROM16:
case MOVE_OBJECT:
case MOVE_OBJECT_16:
case MOVE_OBJECT_FROM16:
case MOVE_WIDE:
case MOVE_WIDE_FROM16:
case MOVE_WIDE_16:
Stmt2RNode stmt2RNode = (Stmt2RNode) insn;
setReg(stmt2RNode.a, interpreter.copyOperation(insn, getReg(stmt2RNode.b)));
setTmp(null);
break;
case MOVE_RESULT:
case MOVE_RESULT_WIDE:
case MOVE_RESULT_OBJECT:
case MOVE_EXCEPTION:
setReg(((Stmt1RNode) insn).a, interpreter.copyOperation(insn, getTmp()));
setTmp(null);
break;
case NOT_INT:
case NOT_LONG:
case NEG_DOUBLE:
case NEG_FLOAT:
case NEG_INT:
case NEG_LONG:
case INT_TO_BYTE:
case INT_TO_CHAR:
case INT_TO_DOUBLE:
case INT_TO_FLOAT:
case INT_TO_LONG:
case INT_TO_SHORT:
case FLOAT_TO_DOUBLE:
case FLOAT_TO_INT:
case FLOAT_TO_LONG:
case DOUBLE_TO_FLOAT:
case DOUBLE_TO_INT:
case DOUBLE_TO_LONG:
case LONG_TO_DOUBLE:
case LONG_TO_FLOAT:
case LONG_TO_INT:
case ARRAY_LENGTH:
Stmt2RNode stmt2RNode1 = (Stmt2RNode) insn;
setReg(stmt2RNode1.a, interpreter.unaryOperation(insn, getReg(stmt2RNode1.b)));
setTmp(null);
break;
case IF_EQZ:
case IF_GEZ:
case IF_GTZ:
case IF_LEZ:
case IF_LTZ:
case IF_NEZ:
interpreter.unaryOperation(insn, getReg(((JumpStmtNode) insn).a));
setTmp(null);
break;
case SPARSE_SWITCH:
interpreter.unaryOperation(insn, getReg(((SparseSwitchStmtNode) insn).a));
setTmp(null);
break;
case PACKED_SWITCH:
interpreter.unaryOperation(insn, getReg(((PackedSwitchStmtNode) insn).a));
setTmp(null);
break;
case SPUT:
case SPUT_BOOLEAN:
case SPUT_BYTE:
case SPUT_CHAR:
case SPUT_OBJECT:
case SPUT_SHORT:
case SPUT_WIDE:
interpreter.unaryOperation(insn, getReg(((FieldStmtNode) insn).a));
setTmp(null);
break;
case IGET:
case IGET_BOOLEAN:
case IGET_BYTE:
case IGET_CHAR:
case IGET_OBJECT:
case IGET_SHORT:
case IGET_WIDE:
FieldStmtNode fieldStmtNode = (FieldStmtNode) insn;
setReg(fieldStmtNode.a, interpreter.unaryOperation(insn, getReg(fieldStmtNode.b)));
setTmp(null);
break;
case NEW_ARRAY:
case INSTANCE_OF: {
TypeStmtNode typeStmtNode = (TypeStmtNode) insn;
setReg(typeStmtNode.a, interpreter.unaryOperation(insn, getReg(typeStmtNode.b)));
setTmp(null);
}
break;
case CHECK_CAST: {
TypeStmtNode typeStmtNode = (TypeStmtNode) insn;
setReg(typeStmtNode.a, interpreter.unaryOperation(insn, getReg(typeStmtNode.a)));
setTmp(null);
}
break;
case MONITOR_ENTER:
case MONITOR_EXIT:
case THROW:
interpreter.unaryOperation(insn, getReg(((Stmt1RNode) insn).a));
setTmp(null);
break;
case RETURN:
case RETURN_WIDE:
case RETURN_OBJECT:
interpreter.returnOperation(insn, getReg(((Stmt1RNode) insn).a));
setTmp(null);
break;
case AGET:
case AGET_BOOLEAN:
case AGET_BYTE:
case AGET_CHAR:
case AGET_OBJECT:
case AGET_SHORT:
case AGET_WIDE:
case CMP_LONG:
case CMPG_DOUBLE:
case CMPG_FLOAT:
case CMPL_DOUBLE:
case CMPL_FLOAT:
case ADD_DOUBLE:
case ADD_FLOAT:
case ADD_INT:
case ADD_LONG:
case SUB_DOUBLE:
case SUB_FLOAT:
case SUB_INT:
case SUB_LONG:
case MUL_DOUBLE:
case MUL_FLOAT:
case MUL_INT:
case MUL_LONG:
case DIV_DOUBLE:
case DIV_FLOAT:
case DIV_INT:
case DIV_LONG:
case REM_DOUBLE:
case REM_FLOAT:
case REM_INT:
case REM_LONG:
case AND_INT:
case AND_LONG:
case OR_INT:
case OR_LONG:
case XOR_INT:
case XOR_LONG:
case SHL_INT:
case SHL_LONG:
case SHR_INT:
case SHR_LONG:
case USHR_INT:
case USHR_LONG:
Stmt3RNode stmt3RNode = (Stmt3RNode) insn;
setReg(stmt3RNode.a, interpreter.binaryOperation(insn, getReg(stmt3RNode.b), getReg(stmt3RNode.c)));
setTmp(null);
break;
case IF_EQ:
case IF_GE:
case IF_GT:
case IF_LE:
case IF_LT:
case IF_NE:
JumpStmtNode jumpStmtNode = (JumpStmtNode) insn;
interpreter.binaryOperation(insn, getReg(jumpStmtNode.a), getReg(jumpStmtNode.b));
setTmp(null);
break;
case IPUT:
case IPUT_BOOLEAN:
case IPUT_BYTE:
case IPUT_CHAR:
case IPUT_OBJECT:
case IPUT_SHORT:
case IPUT_WIDE:
FieldStmtNode fieldStmtNode1 = (FieldStmtNode) insn;
interpreter.binaryOperation(insn, getReg(fieldStmtNode1.b), getReg(fieldStmtNode1.a));
setTmp(null);
break;
case APUT:
case APUT_BOOLEAN:
case APUT_BYTE:
case APUT_CHAR:
case APUT_OBJECT:
case APUT_SHORT:
case APUT_WIDE:
Stmt3RNode stmt3RNode1 = (Stmt3RNode) insn;
interpreter.ternaryOperation(insn, getReg(stmt3RNode1.b), getReg(stmt3RNode1.c), getReg(stmt3RNode1.a));
setTmp(null);
break;
case INVOKE_VIRTUAL_RANGE:
case INVOKE_VIRTUAL:
case INVOKE_SUPER_RANGE:
case INVOKE_DIRECT_RANGE:
case INVOKE_SUPER:
case INVOKE_DIRECT:
case INVOKE_STATIC_RANGE:
case INVOKE_STATIC:
case INVOKE_INTERFACE_RANGE:
case INVOKE_INTERFACE:
case INVOKE_CUSTOM:
case INVOKE_CUSTOM_RANGE:
case INVOKE_POLYMORPHIC:
case INVOKE_POLYMORPHIC_RANGE: {
int i = 0;
AbstractMethodStmtNode methodStmtNode = (AbstractMethodStmtNode) insn;
List v;
Proto proto = methodStmtNode.getProto();
boolean isStatic = false;
if (insn.op == Op.INVOKE_STATIC || insn.op == Op.INVOKE_STATIC_RANGE) {
isStatic = true;
} else if (insn.op == Op.INVOKE_CUSTOM || insn.op == Op.INVOKE_CUSTOM_RANGE) {
isStatic = true;
}
if (isStatic) {
v = new ArrayList<>(proto.getParameterTypes().length);
} else {
v = new ArrayList<>(proto.getParameterTypes().length + 1);
v.add(getReg(methodStmtNode.args[i++]));
}
for (String type : proto.getParameterTypes()) {
v.add(getReg(methodStmtNode.args[i]));
char t = type.charAt(0);
if (t == 'J' || t == 'D') {
i += 2;
} else {
i += 1;
}
}
setTmp(interpreter.naryOperation(insn, v));
}
break;
case FILLED_NEW_ARRAY:
case FILLED_NEW_ARRAY_RANGE: {
FilledNewArrayStmtNode filledNewArrayStmtNode = (FilledNewArrayStmtNode) insn;
List v = new ArrayList<>(filledNewArrayStmtNode.args.length);
for (int i = 0; i < filledNewArrayStmtNode.args.length; i++) {
v.add(getReg(filledNewArrayStmtNode.args[i]));
}
setTmp(interpreter.naryOperation(insn, v));
}
break;
case ADD_DOUBLE_2ADDR:
case ADD_FLOAT_2ADDR:
case ADD_INT_2ADDR:
case ADD_LONG_2ADDR:
case SUB_DOUBLE_2ADDR:
case SUB_FLOAT_2ADDR:
case SUB_INT_2ADDR:
case SUB_LONG_2ADDR:
case MUL_DOUBLE_2ADDR:
case MUL_FLOAT_2ADDR:
case MUL_INT_2ADDR:
case MUL_LONG_2ADDR:
case DIV_DOUBLE_2ADDR:
case DIV_FLOAT_2ADDR:
case DIV_INT_2ADDR:
case DIV_LONG_2ADDR:
case REM_DOUBLE_2ADDR:
case REM_FLOAT_2ADDR:
case REM_INT_2ADDR:
case REM_LONG_2ADDR:
case AND_INT_2ADDR:
case AND_LONG_2ADDR:
case OR_INT_2ADDR:
case OR_LONG_2ADDR:
case XOR_INT_2ADDR:
case XOR_LONG_2ADDR:
case SHL_INT_2ADDR:
case SHL_LONG_2ADDR:
case SHR_INT_2ADDR:
case SHR_LONG_2ADDR:
case USHR_INT_2ADDR:
case USHR_LONG_2ADDR:
Stmt2RNode stmt2RNode2 = (Stmt2RNode) insn;
setReg(stmt2RNode2.a, interpreter.binaryOperation(insn, getReg(stmt2RNode2.a), getReg(stmt2RNode2.b)));
setTmp(null);
break;
case ADD_INT_LIT16:
case ADD_INT_LIT8:
case RSUB_INT_LIT8:
case RSUB_INT:
case MUL_INT_LIT8:
case MUL_INT_LIT16:
case DIV_INT_LIT16:
case DIV_INT_LIT8:
case REM_INT_LIT16:
case REM_INT_LIT8:
case AND_INT_LIT16:
case AND_INT_LIT8:
case OR_INT_LIT16:
case OR_INT_LIT8:
case XOR_INT_LIT16:
case XOR_INT_LIT8:
case SHL_INT_LIT8:
case SHR_INT_LIT8:
case USHR_INT_LIT8:
Stmt2R1NNode stmt2R1NNode = (Stmt2R1NNode) insn;
setReg(stmt2R1NNode.distReg, interpreter.unaryOperation(insn, getReg(stmt2R1NNode.srcReg)));
setTmp(null);
break;
case FILL_ARRAY_DATA:
interpreter.unaryOperation(insn,getReg(((FillArrayDataStmtNode)insn).ra));
setTmp(null);
break;
case GOTO:
case GOTO_16:
case GOTO_32:
case RETURN_VOID:
case BAD_OP:
setTmp(null);
break;
default:
throw new RuntimeException();
}
}
public V getTmp() {
return tmp;
}
public void setTmp(V v) {
this.tmp = v;
}
public V getReg(int b) {
if (b > values.length || b < 0) {
return null;
}
return values[b];
}
public int getTotalRegisters() {
return values.length;
}
}