Search in sources :

Example 21 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.

the class IPAnalysis method visitMethod.

@Override
protected void visitMethod(MethodNode m) {
    // Callbacks
    for (IPAnalysisVisitor v : visitors) {
        v.preVisitMethod(this, m);
    }
    // Do not trace library calls
    if (context.getApplication().isLibraryClass(m.owner.name)) {
        return;
    }
    // Create a mapping between the actual variable table indices and the parameter
    // indices in the method descriptor.
    boolean isStatic = (m.access & Opcodes.ACC_STATIC) != 0;
    int paramCount = Type.getArgumentTypes(m.desc).length;
    int off = (isStatic ? 0 : 1);
    int synthCount = paramCount + off;
    List<List<Expr>> lists = new ArrayList<>(synthCount);
    int[] idxs = new int[synthCount];
    // Scan for synthetic copies to populate indices
    ControlFlowGraph cfg = context.getIRCache().getFor(m);
    BasicBlock entry = cfg.getEntries().iterator().next();
    /* static:
		 *  first arg = 0
		 *
		 * non-static:
		 *  this = 0
		 *  first arg = 1*/
    int paramIndex = 0;
    for (Stmt stmt : entry) {
        if (stmt.getOpcode() == LOCAL_STORE) {
            CopyVarStmt cvs = (CopyVarStmt) stmt;
            if (cvs.isSynthetic()) {
                int varIndex = cvs.getVariable().getLocal().getIndex();
                if (!isStatic && varIndex == 0)
                    continue;
                idxs[paramIndex++] = varIndex;
                continue;
            }
        }
        break;
    }
    for (int j = 0; j < paramCount; j++) {
        lists.add(new ArrayList<>());
    }
    paramIndices.put(m, idxs);
    parameterInputs.put(m, lists);
    callers.put(m, new HashSet<>());
    // Callbacks
    for (IPAnalysisVisitor v : visitors) {
        v.postVisitMethod(this, m);
    }
}
Also used : CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) ArrayList(java.util.ArrayList) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Stmt(org.mapleir.ir.code.Stmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) ArrayList(java.util.ArrayList) List(java.util.List)

Example 22 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.

the class SSAGenPass method insertPhis.

private void insertPhis(BasicBlock b, Local l, int i, LinkedList<BasicBlock> queue) {
    if (b == null || b == builder.head) {
        // exit
        return;
    }
    Local newl = builder.graph.getLocals().get(l.getIndex(), 0, l.isStack());
    for (BasicBlock x : doms.iteratedFrontier(b)) {
        if (insertion.get(x) < i) {
            // pruned SSA
            if (liveness.in(x).contains(l)) {
                if ((l == svar0) && handlers.contains(x)) /* == faster than contains. */
                {
                    /* Note: this is quite subtle. Since there is a
						 * copy, (svar0 = catch()) at the start of each
						 * handler block, technically any natural flowing
						 * svar0 definition is killed upon entry to the
						 * block, so it is not considered live. One way to
						 * check if the variable is live-in, therefore, is
						 * by checking whether svar0 is live-out of the
						 * catch() definition. We handle it here, since
						 * the previous liveness check which is used for
						 * pruned SSA will fail in this case. */
                    /* Ok fuck that that, it's considered live-in
						 * even if there is a catch()::
						 *  #see SSaBlockLivenessAnalyser.precomputeBlock*/
                    boolean naturalFlow = false;
                    for (FlowEdge<BasicBlock> e : builder.graph.getReverseEdges(x)) {
                        if (e.getType() != FlowEdges.TRYCATCH) {
                            naturalFlow = true;
                            break;
                        }
                    }
                    if (naturalFlow) {
                        CopyVarStmt catcher = null;
                        for (Stmt stmt : x) {
                            if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
                                CopyVarStmt copy = (CopyVarStmt) stmt;
                                Expr e = copy.getExpression();
                                if (e.getOpcode() == Opcode.CATCH) {
                                    catcher = copy;
                                    break;
                                }
                            }
                        }
                        if (catcher == null) {
                            /* Handler but no catch copy?
								 * This can't happen since svar0 is
								 * the only reserved register for
								 * catch copies, and this block cannot
								 * be visited twice to insert a phi or
								 * psi(ephi) node. */
                            throw new IllegalStateException(x.getDisplayName());
                        }
                        /* Map<BasicBlock, Expression> vls = new HashMap<>();
							for(FlowEdge<BasicBlock> fe : builder.graph.getReverseEdges(x)) {
								vls.put(fe.src, new VarExpr(newl, null));
							}
							vls.put(x, catcher.getExpression().copy());
							catcher.delete();
							
							PhiExpr phi = new PhiExceptionExpr(vls);
							CopyPhiStmt assign = new CopyPhiStmt(new VarExpr(l, null), phi);
							
							x.add(0, assign); */
                        throw new UnsupportedOperationException(builder.method.toString());
                    }
                }
                if (builder.graph.getReverseEdges(x).size() > 1) {
                    Map<BasicBlock, Expr> vls = new HashMap<>();
                    for (FlowEdge<BasicBlock> fe : builder.graph.getReverseEdges(x)) {
                        vls.put(fe.src(), new VarExpr(newl, null));
                    }
                    PhiExpr phi = new PhiExpr(vls);
                    CopyPhiStmt assign = new CopyPhiStmt(new VarExpr(l, null), phi);
                    x.add(0, assign);
                }
            }
            insertion.put(x, i);
            if (process.get(x) < i) {
                process.put(x, i);
                queue.add(x);
            }
        }
    }
}
Also used : NullPermeableHashMap(org.mapleir.stdlib.collections.map.NullPermeableHashMap) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) BasicLocal(org.mapleir.ir.locals.impl.BasicLocal) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) SwitchStmt(org.mapleir.ir.code.stmt.SwitchStmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) PopStmt(org.mapleir.ir.code.stmt.PopStmt) ThrowStmt(org.mapleir.ir.code.stmt.ThrowStmt) UnconditionalJumpStmt(org.mapleir.ir.code.stmt.UnconditionalJumpStmt) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr)

Example 23 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.

the class BoissinotDestructor method sequentialize.

private void sequentialize(BasicBlock b) {
    // TODO: just rebuild the instruction list
    LinkedHashMap<ParallelCopyVarStmt, Integer> p = new LinkedHashMap<>();
    for (int i = 0; i < b.size(); i++) {
        Stmt stmt = b.get(i);
        if (stmt instanceof ParallelCopyVarStmt)
            p.put((ParallelCopyVarStmt) stmt, i);
    }
    if (p.isEmpty())
        return;
    int indexOffset = 0;
    Local spill = locals.makeLatestVersion(p.entrySet().iterator().next().getKey().pairs.get(0).targ);
    for (Entry<ParallelCopyVarStmt, Integer> e : p.entrySet()) {
        ParallelCopyVarStmt pcvs = e.getKey();
        int index = e.getValue();
        if (pcvs.pairs.size() == 0)
            throw new IllegalArgumentException("pcvs is empty");
        else if (pcvs.pairs.size() == 1) {
            // constant sequentialize for trivial parallel copies
            CopyPair pair = pcvs.pairs.get(0);
            CopyVarStmt newCopy = new CopyVarStmt(new VarExpr(pair.targ, pair.type), new VarExpr(pair.source, pair.type));
            b.set(index + indexOffset, newCopy);
        } else {
            List<CopyVarStmt> sequentialized = pcvs.sequentialize(spill);
            b.remove(index + indexOffset--);
            for (CopyVarStmt cvs : sequentialized) {
                // warning: O(N^2) operation
                b.add(index + ++indexOffset, cvs);
            }
        }
    }
}
Also used : CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) VarExpr(org.mapleir.ir.code.expr.VarExpr)

Example 24 with CopyVarStmt

use of org.mapleir.ir.code.stmt.copy.CopyVarStmt in project maple-ir by LLVM-but-worse.

the class GenerationPass method handler.

protected void handler(TryCatchBlockNode tc) {
    LabelNode label = tc.handler;
    BasicBlock handler = resolveTarget(label);
    marks.add(tc.start);
    marks.add(tc.end);
    if (getInputStackFor(handler) != null) {
        // System.err.println("Double handler: " + handler.getId() + " " + tc);
        return;
    }
    ExpressionStack stack = new ExpressionStack(16);
    setInputStack(handler, stack);
    CaughtExceptionExpr expr = new CaughtExceptionExpr(tc.type);
    Type type = expr.getType();
    VarExpr var = _var_expr(0, type, true);
    CopyVarStmt stmt = copy(var, expr, handler);
    handler.add(stmt);
    stack.push(load_stack(0, type));
    queue(label);
    stacks.set(handler.getNumericId());
}
Also used : Type(org.objectweb.asm.Type) ComparisonType(org.mapleir.ir.code.stmt.ConditionalJumpStmt.ComparisonType) ValueComparisonType(org.mapleir.ir.code.expr.ComparisonExpr.ValueComparisonType) ArrayType(org.mapleir.ir.TypeUtils.ArrayType) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) ExpressionStack(org.mapleir.ir.code.ExpressionStack)

Aggregations

CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)24 Stmt (org.mapleir.ir.code.Stmt)18 BasicBlock (org.mapleir.ir.cfg.BasicBlock)17 VarExpr (org.mapleir.ir.code.expr.VarExpr)17 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)16 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)14 Local (org.mapleir.ir.locals.Local)13 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)12 Expr (org.mapleir.ir.code.Expr)10 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)8 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)6 PopStmt (org.mapleir.ir.code.stmt.PopStmt)6 SwitchStmt (org.mapleir.ir.code.stmt.SwitchStmt)6 ThrowStmt (org.mapleir.ir.code.stmt.ThrowStmt)6 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)6 Constraint (org.mapleir.ir.cfg.builder.ssaopt.Constraint)5 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)5 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)5 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)3 Type (org.objectweb.asm.Type)3