130 lines
3.8 KiB
Java
130 lines
3.8 KiB
Java
package com.ibm.wala.dalvik.analysis.typeInference;
|
|
|
|
import com.ibm.wala.analysis.typeInference.TypeAbstraction;
|
|
import com.ibm.wala.analysis.typeInference.TypeInference;
|
|
import com.ibm.wala.analysis.typeInference.TypeVariable;
|
|
import com.ibm.wala.fixpoint.AbstractOperator;
|
|
import com.ibm.wala.fixpoint.IVariable;
|
|
import com.ibm.wala.ssa.IR;
|
|
import com.ibm.wala.ssa.SSAPhiInstruction;
|
|
import com.ibm.wala.ssa.SymbolTable;
|
|
|
|
public class DalvikTypeInference extends TypeInference {
|
|
@Override
|
|
protected TypeVariable[] makeStmtRHS(int size) {
|
|
return new DalvikTypeVariable[size];
|
|
}
|
|
|
|
private static AbstractOperator<TypeVariable> dalvikPhiOp = new DalvikPhiOperator();
|
|
|
|
protected DalvikTypeInference(IR ir, boolean doPrimitives) {
|
|
super(ir, doPrimitives);
|
|
}
|
|
|
|
protected void initialize() {
|
|
init(ir, this.new DalvikTypeVarFactory(), this.new TypeOperatorFactory());
|
|
}
|
|
|
|
public static DalvikTypeInference make(IR ir, boolean doPrimitives) {
|
|
return new DalvikTypeInference(ir, doPrimitives);
|
|
}
|
|
|
|
public class DalvikTypeVarFactory extends TypeInference.TypeVarFactory {
|
|
|
|
@Override
|
|
public IVariable makeVariable(int valueNumber) {
|
|
SymbolTable st = ir.getSymbolTable();
|
|
if (st.isIntegerConstant(valueNumber) && st.isZero(valueNumber)) {
|
|
return new DalvikTypeVariable(language.getPrimitive(language.getConstantType(Integer.valueOf(0))), true);
|
|
} else {
|
|
if (doPrimitives) {
|
|
if (st.isConstant(valueNumber)) {
|
|
if (st.isBooleanConstant(valueNumber)) {
|
|
return new DalvikTypeVariable(language.getPrimitive(language.getConstantType(Boolean.TRUE)));
|
|
}
|
|
}
|
|
}
|
|
return new DalvikTypeVariable(TypeAbstraction.TOP);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected class TypeOperatorFactory extends TypeInference.TypeOperatorFactory {
|
|
|
|
@Override
|
|
public void visitPhi(SSAPhiInstruction instruction) {
|
|
assert dalvikPhiOp != null;
|
|
this.result = dalvikPhiOp;
|
|
}
|
|
|
|
}
|
|
|
|
private static final class DalvikPhiOperator extends AbstractOperator<TypeVariable> {
|
|
private DalvikPhiOperator() {
|
|
}
|
|
|
|
@Override
|
|
public byte evaluate(TypeVariable _lhs, TypeVariable[] _rhs) {
|
|
/**
|
|
* TODO: Find a better solution than downcasting. Downcasting is
|
|
* really ugly, although I can be sure here that it succeeds because
|
|
* I control what type the parameters have. There must be a cleaner
|
|
* solution which does not cause tons of changes in WALA's code, but
|
|
* I don't see it yet...
|
|
*/
|
|
assert _lhs instanceof DalvikTypeVariable;
|
|
assert _rhs instanceof DalvikTypeVariable[];
|
|
DalvikTypeVariable lhs = (DalvikTypeVariable) _lhs;
|
|
DalvikTypeVariable[] rhs = (DalvikTypeVariable[]) _rhs;
|
|
TypeAbstraction lhsType = lhs.getType();
|
|
TypeAbstraction meet = TypeAbstraction.TOP;
|
|
boolean ignoreZero = containsNonPrimitiveAndZero(rhs);
|
|
for (int i = 0; i < rhs.length; i++) {
|
|
if (rhs[i] != null && rhs[i].getType() != null && !(ignoreZero && rhs[i].isIntZeroConstant())) {
|
|
TypeVariable r = rhs[i];
|
|
meet = meet.meet(r.getType());
|
|
}
|
|
}
|
|
if (lhsType.equals(meet)) {
|
|
return NOT_CHANGED;
|
|
} else {
|
|
lhs.setType(meet);
|
|
return CHANGED;
|
|
}
|
|
}
|
|
|
|
private boolean containsNonPrimitiveAndZero(DalvikTypeVariable[] types) {
|
|
boolean containsNonPrimitive = false;
|
|
boolean containsZero = false;
|
|
for (int i = 0; i < types.length; i++) {
|
|
if (types[i] != null) {
|
|
if (types[i].getType() != null && types[i].getType().getTypeReference() != null
|
|
&& !types[i].getType().getTypeReference().isPrimitiveType()) {
|
|
containsNonPrimitive = true;
|
|
}
|
|
if (types[i].isIntZeroConstant()) {
|
|
containsZero = true;
|
|
}
|
|
}
|
|
}
|
|
return containsNonPrimitive && containsZero;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "phi meet (dalvik)";
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return 2297;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
return (o instanceof DalvikPhiOperator);
|
|
}
|
|
}
|
|
}
|
|
|