use of org.mapleir.ir.code.expr.invoke.InvocationExpr in project maple-ir by LLVM-but-worse.
the class SSAGenPass method aggregateInitialisers.
private void aggregateInitialisers() {
for (BasicBlock b : builder.graph.vertices()) {
for (Stmt stmt : new ArrayList<>(b)) {
if (stmt.getOpcode() == Opcode.POP) {
PopStmt pop = (PopStmt) stmt;
Expr expr = pop.getExpression();
if (expr.getOpcode() == Opcode.INVOKE) {
InvocationExpr invoke = (InvocationExpr) expr;
if (invoke.getCallType() == InvocationExpr.CallType.SPECIAL && invoke.getName().equals("<init>")) {
Expr inst = invoke.getPhysicalReceiver();
if (inst.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr var = (VarExpr) inst;
VersionedLocal local = (VersionedLocal) var.getLocal();
AbstractCopyStmt def = pool.defs.get(local);
Expr rhs = def.getExpression();
if (rhs.getOpcode() == Opcode.ALLOC_OBJ) {
// replace pop(x.<init>()) with x := new Klass();
// remove x := new Klass;
// here we are assuming that the new object
// can't be used until it is initialised.
Expr[] args = invoke.getParameterExprs();
// we want to reuse the exprs, so free it first.
pop.deleteAt(0);
Expr[] newArgs = Arrays.copyOf(args, args.length);
for (int i = args.length - 1; i >= 0; i--) {
args[i].unlink();
}
// remove the old def
def.delete();
int index = b.indexOf(pop);
// add a copy statement before the pop (x = newExpr)
InitialisedObjectExpr newExpr = new InitialisedObjectExpr(invoke.getOwner(), invoke.getDesc(), newArgs);
CopyVarStmt newCvs = new CopyVarStmt(var, newExpr);
pool.defs.put(local, newCvs);
pool.uses.get(local).remove(var);
b.add(index, newCvs);
// remove the pop statement
b.remove(pop);
// update the latestval constraints
LatestValue lval = latest.get(local);
if (lval.hasConstraints()) {
/* need to check this out (shouldn't happen) */
System.out.println("Constraints:");
for (Constraint c : lval.getConstraints()) {
System.out.println(" " + c);
}
throw new IllegalStateException(lval.toString());
} else {
lval.makeConstraints(newExpr);
}
}
} else if (inst.getOpcode() == Opcode.ALLOC_OBJ) {
// replace pop(new Klass.<init>(args)) with pop(new Klass(args))
// UninitialisedObjectExpr obj = (UninitialisedObjectExpr) inst;
Expr[] args = invoke.getParameterExprs();
// we want to reuse the exprs, so free it first.
invoke.unlink();
for (Expr e : args) {
e.unlink();
}
Expr[] newArgs = Arrays.copyOf(args, args.length);
InitialisedObjectExpr newExpr = new InitialisedObjectExpr(invoke.getOwner(), invoke.getDesc(), newArgs);
// replace pop contents
// no changes to defs or uses
pop.setExpression(newExpr);
} else {
System.err.println(b);
System.err.println("Stmt: " + stmt.getDisplayName() + ". " + stmt);
System.err.println("Inst: " + inst);
System.err.println(builder.graph);
throw new RuntimeException("interesting1 " + inst.getClass());
}
}
}
}
}
}
}
use of org.mapleir.ir.code.expr.invoke.InvocationExpr in project maple-ir by LLVM-but-worse.
the class GenerationPass method _call.
protected void _call(int op, String owner, String name, String desc) {
save_stack(false);
int argLen = Type.getArgumentTypes(desc).length + (op == INVOKESTATIC ? 0 : 1);
Expr[] args = new Expr[argLen];
for (int i = args.length - 1; i >= 0; i--) {
args[i] = pop();
}
InvocationExpr callExpr = new InvocationExpr(InvocationExpr.CallType.resolveCallType(op), args, owner, name, desc);
if (callExpr.getType() == Type.VOID_TYPE) {
addStmt(new PopStmt(callExpr));
} else {
int index = currentStack.height();
Type type = assign_stack(index, callExpr);
push(load_stack(index, type));
}
}
use of org.mapleir.ir.code.expr.invoke.InvocationExpr in project maple-ir by LLVM-but-worse.
the class ConcreteStaticInvocationPass method accept.
@Override
public int accept(AnalysisContext cxt, IPass prev, List<IPass> completed) {
int fixed = 0;
InvocationResolver resolver = cxt.getInvocationResolver();
for (ClassNode cn : cxt.getApplication().iterate()) {
for (MethodNode mn : cn.methods) {
ControlFlowGraph cfg = cxt.getIRCache().getFor(mn);
for (BasicBlock b : cfg.vertices()) {
for (Stmt stmt : b) {
for (Expr e : stmt.enumerateOnlyChildren()) {
if (e.getOpcode() == Opcode.INVOKE) {
InvocationExpr invoke = (InvocationExpr) e;
if (invoke.isStatic()) {
MethodNode invoked = resolver.resolveStaticCall(invoke.getOwner(), invoke.getName(), invoke.getDesc());
if (invoked != null) {
if (!invoked.owner.name.equals(invoke.getOwner())) {
invoke.setOwner(invoked.owner.name);
fixed++;
}
}
}
}
}
}
}
}
}
System.out.printf(" corrected %d dodgy static calls.%n", fixed);
return fixed;
}
use of org.mapleir.ir.code.expr.invoke.InvocationExpr in project maple-ir by LLVM-but-worse.
the class ConstantParameterPass method patchCall.
private void patchCall(String newDesc, Expr call, boolean[] dead) {
if (call.getOpcode() == Opcode.INIT_OBJ) {
InitialisedObjectExpr init = (InitialisedObjectExpr) call;
CodeUnit parent = init.getParent();
Expr[] newArgs = buildArgs(init.getArgumentExprs(), false, dead);
InitialisedObjectExpr init2 = new InitialisedObjectExpr(init.getOwner(), newDesc, newArgs);
parent.overwrite(init2, parent.indexOf(init));
} else if (call.getOpcode() == Opcode.INVOKE) {
InvocationExpr invoke = (InvocationExpr) call;
CodeUnit parent = invoke.getParent();
Expr[] newArgs = buildArgs(invoke.getArgumentExprs(), invoke.getCallType() != InvocationExpr.CallType.STATIC, dead);
InvocationExpr invoke2 = new InvocationExpr(invoke.getCallType(), newArgs, invoke.getOwner(), invoke.getName(), newDesc);
parent.overwrite(invoke2, parent.indexOf(invoke));
} else {
throw new UnsupportedOperationException(call.toString());
}
}
use of org.mapleir.ir.code.expr.invoke.InvocationExpr in project maple-ir by LLVM-but-worse.
the class LiftConstructorCallsPass method tryLift.
private boolean tryLift(MethodNode m, ControlFlowGraph cfg) {
Local lvar0_0 = cfg.getLocals().get(0, 0, false);
/* only contains synthetic copies */
BasicBlock entry = cfg.getEntries().iterator().next();
for (BasicBlock b : cfg.vertices()) {
for (Stmt stmt : b) {
for (Expr e : stmt.enumerateOnlyChildren()) {
if (e.getOpcode() == INVOKE) {
InvocationExpr invoke = (InvocationExpr) e;
if (invoke.getOwner().equals(m.owner.superName) && invoke.getName().equals("<init>")) {
Expr p1 = invoke.getPhysicalReceiver();
if (p1.getOpcode() == LOCAL_LOAD && ((VarExpr) p1).getLocal() == lvar0_0) {
Set<FlowEdge<BasicBlock>> predsEdges = cfg.getReverseEdges(b);
FlowEdge<BasicBlock> incoming;
if (predsEdges.size() == 1 && ((incoming = predsEdges.iterator().next()).getType() == FlowEdges.IMMEDIATE) && incoming.src() == entry) {
// BasicBlock liftBlock = new BasicBlock(cfg, cfg.vertices().size() + 1, new LabelNode());
/* split the block before the invocation and
* insert a new block. */
split(cfg, b, stmt);
return true;
} else {
System.err.printf(" warn(nolift) for %s in %n%s%n", invoke, ControlFlowGraph.printBlock(b));
System.err.printf(" preds: %s%n", predsEdges);
}
} else {
throw new IllegalStateException(String.format("broken super call: %s", invoke));
}
}
}
}
}
}
return false;
}
Aggregations