All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.dex2jar.ir.ts.JimpleTransformer Maven / Gradle / Ivy

package com.googlecode.dex2jar.ir.ts;

import com.googlecode.d2j.DexType;
import com.googlecode.dex2jar.ir.IrMethod;
import com.googlecode.dex2jar.ir.expr.Constant;
import com.googlecode.dex2jar.ir.expr.Exprs;
import com.googlecode.dex2jar.ir.expr.Local;
import com.googlecode.dex2jar.ir.expr.Value;
import com.googlecode.dex2jar.ir.expr.Value.VT;
import com.googlecode.dex2jar.ir.stmt.Stmt;
import com.googlecode.dex2jar.ir.stmt.Stmt.ST;
import com.googlecode.dex2jar.ir.stmt.Stmts;
import java.util.ArrayList;
import java.util.List;

/**
 * transform IR to simple 3-addr format
 * 

* a=b+c+d; => e=b+c; a=e+d; * * @author bob */ public class JimpleTransformer implements Transformer { static class N { public List tmp; int nextIdx; private final List locals; N(List tmp, List locals) { super(); this.tmp = tmp; this.locals = locals; nextIdx = locals.size(); } Value newAssign(Value x) { Local loc = Exprs.nLocal(nextIdx++); loc.valueType = x.valueType; locals.add(loc); tmp.add(Stmts.nAssign(loc, x)); return loc; } } @Override public void transform(IrMethod method) { List tmp = new ArrayList<>(); N n = new N(tmp, method.locals); for (Stmt p = method.stmts.getFirst(); p != null; p = p.getNext()) { tmp.clear(); convertStmt(p, n); for (Stmt t : tmp) { method.stmts.insertBefore(p, t); } } } private Value convertExpr(Value x, boolean keep, N tmp) { switch (x.et) { case E0: if (!keep) { switch (x.vt) { case CONSTANT: Constant cst = (Constant) x; if (cst.value instanceof String || cst.value instanceof DexType || cst.value.getClass().isArray()) { return tmp.newAssign(x); } break; case NEW: case STATIC_FIELD: return tmp.newAssign(x); default: } } break; case E1: x.setOp(convertExpr(x.getOp(), false, tmp)); if (!keep) { return tmp.newAssign(x); } break; case E2: x.setOp1(convertExpr(x.getOp1(), false, tmp)); x.setOp2(convertExpr(x.getOp2(), false, tmp)); if (!keep) { return tmp.newAssign(x); } break; case En: Value[] ops = x.getOps(); for (int i = 0; i < ops.length; i++) { ops[i] = convertExpr(ops[i], false, tmp); } if (!keep) { return tmp.newAssign(x); } break; default: break; } return x; } private void convertStmt(Stmt p, N tmp) { switch (p.et) { case E0: return; case E1: boolean keep; switch (p.st) { case LOOKUP_SWITCH: case TABLE_SWITCH: case RETURN: case THROW: keep = false; break; default: keep = true; break; } p.setOp(convertExpr(p.getOp(), keep, tmp)); break; case E2: if (p.st == ST.IDENTITY) { return; } else if (p.st == ST.FILL_ARRAY_DATA) { p.setOp1(convertExpr(p.getOp1(), false, tmp)); p.setOp2(convertExpr(p.getOp2(), true, tmp)); } else { p.setOp1(convertExpr(p.getOp1(), true, tmp)); p.setOp2(convertExpr(p.getOp2(), p.getOp1().vt == VT.LOCAL, tmp)); } break; case En: Value[] ops = p.getOps(); for (int i = 0; i < ops.length; i++) { ops[i] = convertExpr(ops[i], true, tmp); } break; default: break; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy