use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.
the class SSAGenPass method resolveShadowedLocals.
private void resolveShadowedLocals() {
Set<VersionedLocal> visited = new HashSet<>();
for (Entry<VersionedLocal, Set<VersionedLocal>> e : shadowed.entrySet()) {
if (!visited.contains(e.getKey())) {
Set<VersionedLocal> set = e.getValue();
visited.addAll(set);
Set<VersionedLocal> lvars = new HashSet<>();
for (VersionedLocal l : set) {
if (!l.isStack()) {
lvars.add(l);
}
}
/* find a suitable spill variable:
* favour lvars
* favour lowest version */
VersionedLocal spill;
if (lvars.isEmpty()) {
/* all vars are svars. */
spill = findLowest(set);
} else if (lvars.size() == 1) {
spill = lvars.iterator().next();
} else {
/* multiple lvars. // TODO: tweak? */
// System.err.println(e.getKey() + " " + lvars);
spill = findLowest(lvars);
}
// System.out.println(set + " spill; " + spill);
/* now that we've chosen a spill var, we
* find the original copy, i.e. the one
* which has a runtime computed value
* as it's rhs. we then replace the
* target of that copy to the spill
* var and remove the definitions of the
* shadowed vars. we then rename all
* uses of the shadowed vars with the
* spill. */
Set<AbstractCopyStmt> orig = new HashSet<>();
Set<VarExpr> spillUses = pool.uses.get(spill);
// System.out.println(set);
for (VersionedLocal vl : set) {
AbstractCopyStmt copy = pool.defs.get(vl);
// System.out.println(vl);
Expr ex = copy.getExpression();
if (vl != spill) {
if (ex.getOpcode() != Opcode.LOCAL_LOAD) {
orig.add(copy);
} else {
// System.out.println("del1: " + copy);
removeSimpleCopy(copy);
}
/* transfer the uses of each shadowed
* var to the spill var, since we
* rename all of the shadowed vars. */
Set<VarExpr> useSet = pool.uses.get(vl);
// System.out.println("uses of " + vl + " ; " + useSet);
for (VarExpr v : useSet) {
v.setLocal(spill);
}
spillUses.addAll(useSet);
useSet.clear();
pool.uses.remove(vl);
} else {
// System.out.println("del2: " + copy);
removeSimpleCopy(copy);
}
pool.defs.remove(vl);
}
if (orig.size() != 1) {
throw new UnsupportedOperationException(String.format("set:%s, spill:%s, orig:%s", set, spill, orig));
}
AbstractCopyStmt copy = orig.iterator().next();
copy.getVariable().setLocal(spill);
pool.defs.put(spill, copy);
}
}
}
use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.
the class DumbExceptionAnalysis method getPossibleUserThrowables.
@Override
public Set<Type> getPossibleUserThrowables(CodeUnit u) {
Set<Type> set = new HashSet<>();
if (u.isFlagSet(CodeUnit.FLAG_STMT)) {
Stmt s = (Stmt) u;
canThrowStmt(s, set);
for (Expr e : s.enumerateOnlyChildren()) {
canThrowExpr(e, set);
}
} else {
for (Expr e : ((Expr) u).enumerateWithSelf()) {
canThrowExpr(e, set);
}
}
return set;
}
use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.
the class ExpressionEvaluator method eval.
public ConstantExpr eval(LocalsPool pool, Expr e) {
if (e.getOpcode() == CONST_LOAD) {
return ((ConstantExpr) e).copy();
} else if (e.getOpcode() == ARITHMETIC) {
ArithmeticExpr ae = (ArithmeticExpr) e;
Expr l = ae.getLeft();
Expr r = ae.getRight();
Expr le = eval(pool, l);
Expr re = eval(pool, r);
if (le != null && re != null) {
ConstantExpr lc = (ConstantExpr) le;
ConstantExpr rc = (ConstantExpr) re;
EvaluationFunctor<Number> b = factory.arithmetic(lc.getType(), rc.getType(), ae.getType(), ae.getOperator());
return new ConstantExpr(b.eval(lc.getConstant(), rc.getConstant()));
}
} else if (e.getOpcode() == NEGATE) {
NegationExpr neg = (NegationExpr) e;
Expr e2 = eval(pool, neg.getExpression());
if (e2 != null) {
ConstantExpr ce = (ConstantExpr) e2;
EvaluationFunctor<Number> b = factory.negate(e2.getType());
return new ConstantExpr(b.eval(ce.getConstant()));
}
} else if (e.getOpcode() == LOCAL_LOAD) {
VarExpr v = (VarExpr) e;
Local l = v.getLocal();
AbstractCopyStmt def = pool.defs.get(l);
Expr rhs = def.getExpression();
if (rhs.getOpcode() == LOCAL_LOAD) {
VarExpr v2 = (VarExpr) rhs;
// synthetic copies lhs = rhs;
if (v2.getLocal() == l) {
return null;
}
}
return eval(pool, rhs);
} else if (e.getOpcode() == CAST) {
CastExpr cast = (CastExpr) e;
Expr e2 = eval(pool, cast.getExpression());
if (e2 != null) {
ConstantExpr ce = (ConstantExpr) e2;
if (!ce.getType().equals(cast.getExpression().getType())) {
throw new IllegalStateException(ce.getType() + " : " + cast.getExpression().getType());
}
Type from = ce.getType();
Type to = cast.getType();
boolean p1 = TypeUtils.isPrimitive(from);
boolean p2 = TypeUtils.isPrimitive(to);
if (p1 != p2) {
throw new IllegalStateException(from + " to " + to);
}
if (!p1 && !p2) {
return null;
}
EvaluationFunctor<Number> b = factory.cast(from, to);
return new ConstantExpr(b.eval(ce.getConstant()), to);
}
} else if (e.getOpcode() == COMPARE) {
ComparisonExpr comp = (ComparisonExpr) e;
Expr l = comp.getLeft();
Expr r = comp.getRight();
Expr le = eval(pool, l);
Expr re = eval(pool, r);
if (le != null && re != null) {
ConstantExpr lc = (ConstantExpr) le;
ConstantExpr rc = (ConstantExpr) re;
EvaluationFunctor<Number> b = factory.compare(lc.getType(), rc.getType(), comp.getComparisonType());
return new ConstantExpr(b.eval(lc.getConstant(), rc.getConstant()), Type.INT_TYPE);
}
}
return null;
}
use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.
the class ExpressionEvaluator method reassociate.
private ArithmeticExpr reassociate(LocalsPool pool, ArithmeticExpr ae) {
ArithmeticExpr leftAe = (ArithmeticExpr) ae.getLeft();
Operator operatorA = leftAe.getOperator();
Operator operatorB = ae.getOperator();
Expr r1 = eval(pool, leftAe.getRight());
Expr r2 = eval(pool, ae.getRight());
if (r1 != null && r2 != null) {
ConstantExpr cr1 = (ConstantExpr) r1;
ConstantExpr cr2 = (ConstantExpr) r2;
int sign = 0;
if ((operatorA == MUL && operatorB == MUL)) {
sign = 1;
} else if (operatorA == ADD && (operatorB == ADD || operatorB == SUB)) {
// what about overflow?? integers mod 2^32 forms a group over addition...should be ok?
sign = 1;
} else if (operatorA == SUB && (operatorB == ADD || operatorB == SUB)) {
sign = -1;
}
if (sign != 0) {
ConstantExpr cr1r2 = eval(pool, new ArithmeticExpr(sign > 0 ? cr2 : new NegationExpr(cr2), cr1, operatorB));
Object associated = cr1r2.getConstant();
return new ArithmeticExpr(new ConstantExpr(associated, cr1r2.getType()), leftAe.getLeft().copy(), operatorA);
}
}
return null;
}
use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.
the class ExpressionEvaluator method simplifyMultiplication.
private Expr simplifyMultiplication(LocalsPool pool, ArithmeticExpr e) {
if (e.getOperator() != Operator.MUL)
throw new IllegalArgumentException("Only works on multiplication exprs");
Expr r = e.getRight();
ConstantExpr re = eval(pool, r);
if (re != null) {
Object o = re.getConstant();
if (o instanceof Integer || o instanceof Long) {
if (FieldRSADecryptionPass.__eq((Number) o, 1, o instanceof Long)) {
return e.getLeft().copy();
} else if (FieldRSADecryptionPass.__eq((Number) o, 0, o instanceof Long)) {
return new ConstantExpr(0, re.getType());
}
}
}
return null;
}
Aggregations