Skip to content

Commit

Permalink
Improve typing
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcMil committed Oct 19, 2024
1 parent 87ba387 commit 72b7640
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 6 deletions.
6 changes: 5 additions & 1 deletion src/main/java/soot/dexpler/DexBody.java
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,6 @@ public Body jimplify(Body b, SootMethod m) {
handleKnownDexTypes(b, jimple);

new SharedInitializationLocalSplitter(DalvikThrowAnalysis.v()).transform(jBody);

// split first to find undefined uses
getLocalSplitter().transform(jBody);

Expand Down Expand Up @@ -820,12 +819,17 @@ public Body jimplify(Body b, SootMethod m) {
}
}

getLocalSplitter().transform(jBody);

new soot.jimple.toolkits.typing.fast.TypeResolver(jBody) {

protected soot.jimple.toolkits.typing.fast.TypePromotionUseVisitor createTypePromotionUseVisitor(JimpleBody jb,
soot.jimple.toolkits.typing.fast.Typing tg) {
return new TypePromotionUseVisitor(jb, tg) {
protected boolean allowConversion(Type ancestor, Type child) {
if (ancestor == child) {
return true;
}
if ((ancestor instanceof IntegerType || ancestor instanceof FloatType)
&& (child instanceof IntegerType || child instanceof FloatType)) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,12 @@ public Value visit(Value op, Type useType, Stmt stmt, boolean checkOnly) {
return op;
}

Type t = AugEvalFunction.eval_(this.tg, op, stmt, this.jb);
final Type t = AugEvalFunction.eval_(this.tg, op, stmt, this.jb);
final boolean eqType = TypeResolver.typesEqual(t, useType);
if (eqType) {
//shortcut
return op;
}

if (!allowConversion(useType, t)) {
logger.error(String.format("Failed Typing in %s at statement %s: Is not cast compatible: %s <-- %s",
Expand All @@ -106,7 +111,7 @@ public Value visit(Value op, Type useType, Stmt stmt, boolean checkOnly) {
} else if (!checkOnly && op instanceof Local && (t instanceof Integer1Type || t instanceof Integer127Type
|| t instanceof Integer32767Type || t instanceof WeakObjectType)) {
Local v = (Local) op;
if (!TypeResolver.typesEqual(t, useType)) {
if (!eqType) {
Type t_ = this.promote(t, useType);
if (!TypeResolver.typesEqual(t, t_)) {
this.tg.set(v, t_);
Expand Down
50 changes: 50 additions & 0 deletions src/main/java/soot/jimple/toolkits/typing/fast/TypeResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import soot.ArrayType;
Expand Down Expand Up @@ -83,13 +85,39 @@ public class TypeResolver {

private final List<DefinitionStmt> assignments;
private final HashMap<Local, BitSet> depends;
private final Set<Local> singleAssignments;
private final LocalGenerator localGenerator;

public TypeResolver(JimpleBody jb) {
this.jb = jb;
this.assignments = new ArrayList<DefinitionStmt>();
this.depends = new HashMap<Local, BitSet>(jb.getLocalCount());
this.localGenerator = Scene.v().createLocalGenerator(jb);
Map<Local, Integer> map = new HashMap<>();
for (Unit stmt : this.jb.getUnits()) {
if (stmt instanceof DefinitionStmt) {
DefinitionStmt def = (DefinitionStmt) stmt;

Value lhs = def.getLeftOp();
if (lhs instanceof Local) {
Local l = (Local) lhs;
Integer c = map.get(l);
if (c == null) {
c = 0;
}
c++;
map.put(l, c);
}
}
}
Iterator<Entry<Local, Integer>> t = map.entrySet().iterator();
while (t.hasNext()) {
if (t.next().getValue() > 1) {
t.remove();
}
}
this.singleAssignments = map.keySet();

this.initAssignments();
}

Expand Down Expand Up @@ -504,6 +532,28 @@ protected Collection<Typing> applyAssignmentConstraints(Typing tg, IEvalFunction
wl.set(0, numAssignments);
sigma.add(new WorklistElement(tg, wl, new TypeDecision()));

if (tg.map.isEmpty()) {
//First get the easy cases out of the way.
for (int i = 0; i < numAssignments; i++) {
final DefinitionStmt stmt = this.assignments.get(i);
Value lhs = stmt.getLeftOp();
if (lhs instanceof Local) {
Local v = (Local) lhs;
if (singleAssignments.contains(v)) {
Collection<Type> d = ef.eval(tg, stmt.getRightOp(), stmt);
if (d.size() == 1) {
Type t_ = d.iterator().next();
d = reduceToAllowedTypesForLocal(Collections.singleton(t_), v);
if (d.size() == 1) {
tg.set(v, d.iterator().next());
wl.clear(i);
}
}
}
}
}
}

Set<Type> throwable = null;

while (!sigma.isEmpty()) {
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/soot/jimple/toolkits/typing/fast/Typing.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.Map;

import soot.Local;
import soot.NullType;
import soot.Type;

/**
Expand Down Expand Up @@ -56,7 +57,7 @@ public Type get(Local v) {
}

public Type set(Local v, Type t) {
return (t instanceof BottomType) ? null : this.map.put(v, t);
return (t instanceof BottomType || t instanceof NullType) ? null : this.map.put(v, t);
}

public Collection<Local> getAllLocals() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ protected void internalTransform(Body body, String phaseName, Map<String, String

DeadAssignmentEliminator.v().transform(body);
CopyPropagator.v().transform(body);
transformOnly(body);
}

public void transformOnly(Body body) {

final ExceptionalUnitGraph graph
= ExceptionalUnitGraphFactory.createExceptionalUnitGraph(body, throwAnalysis, omitExceptingUnitEdges);
Expand Down Expand Up @@ -177,8 +181,11 @@ protected void internalTransform(Body body, String phaseName, Map<String, String
for (Local lcl : clustersPerLocal.keySet()) {
Set<Cluster> clusters = clustersPerLocal.get(lcl);
if (clusters.size() <= 1) {
// Not interesting
continue;
//Do we have any non-cluster writes?
if (clusters.iterator().next().constantInitializers.containsAll(defs.getDefsOf(lcl))) {
// Not interesting
continue;
}
}
for (Cluster cluster : clusters) {
// we have an overlap, we need to split.
Expand Down

0 comments on commit 72b7640

Please sign in to comment.