Search in sources :

Example 1 with DefaultSwitchEdge

use of org.mapleir.flowgraph.edges.DefaultSwitchEdge in project maple-ir by LLVM-but-worse.

the class GenerationPass method process.

protected void process(LabelNode label) {
    /* it may not be properly initialised yet, however. */
    BasicBlock block = builder.graph.getBlock(label);
    /* if it is, we don't need to process it. */
    if (block != null && finished.get(block.getNumericId())) {
        return;
    } else if (block == null) {
        block = makeBlock(label);
    } else {
    // i.e. not finished.
    }
    preprocess(block);
    /* populate instructions. */
    int codeIndex = insns.indexOf(label);
    finished.set(block.getNumericId());
    while (codeIndex < insns.size() - 1) {
        AbstractInsnNode ain = insns.get(++codeIndex);
        int type = ain.type();
        if (ain.opcode() != -1) {
            process(block, ain);
        }
        if (type == LABEL) {
            // split into new block
            BasicBlock immediate = resolveTarget((LabelNode) ain);
            builder.graph.addEdge(block, new ImmediateEdge<>(block, immediate));
            break;
        } else if (type == JUMP_INSN) {
            JumpInsnNode jin = (JumpInsnNode) ain;
            BasicBlock target = resolveTarget(jin.label);
            if (jin.opcode() == JSR) {
                throw new UnsupportedOperationException("jsr " + builder.method);
            } else if (jin.opcode() == GOTO) {
                builder.graph.addEdge(block, new UnconditionalJumpEdge<>(block, target));
            } else {
                builder.graph.addEdge(block, new ConditionalJumpEdge<>(block, target, jin.opcode()));
                int nextIndex = codeIndex + 1;
                AbstractInsnNode nextInsn = insns.get(nextIndex);
                if (!(nextInsn instanceof LabelNode)) {
                    LabelNode newLabel = new LabelNode();
                    insns.insert(ain, newLabel);
                    nextInsn = newLabel;
                }
                // create immediate successor reference if it's not already done
                BasicBlock immediate = resolveTarget((LabelNode) nextInsn);
                builder.graph.addEdge(block, new ImmediateEdge<>(block, immediate));
            }
            break;
        } else if (type == LOOKUPSWITCH_INSN) {
            LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) ain;
            for (int i = 0; i < lsin.keys.size(); i++) {
                BasicBlock target = resolveTarget(lsin.labels.get(i));
                builder.graph.addEdge(block, new SwitchEdge<>(block, target, lsin, lsin.keys.get(i)));
            }
            BasicBlock dflt = resolveTarget(lsin.dflt);
            builder.graph.addEdge(block, new DefaultSwitchEdge<>(block, dflt, lsin));
            break;
        } else if (type == TABLESWITCH_INSN) {
            TableSwitchInsnNode tsin = (TableSwitchInsnNode) ain;
            for (int i = tsin.min; i <= tsin.max; i++) {
                BasicBlock target = resolveTarget(tsin.labels.get(i - tsin.min));
                builder.graph.addEdge(block, new SwitchEdge<>(block, target, tsin, i));
            }
            BasicBlock dflt = resolveTarget(tsin.dflt);
            builder.graph.addEdge(block, new DefaultSwitchEdge<>(block, dflt, tsin));
            break;
        } else if (isExitOpcode(ain.opcode())) {
            break;
        }
    }
    // TODO: check if it should have an immediate.
    BasicBlock im = block.getImmediate();
    if (im != null) /* && !queue.contains(im)*/
    {
        // System.out.println("Updating " + block.getId() + " -> " + im.getId());
        // System.out.println("  Pre: " + currentStack);
        update_target_stack(block, im, currentStack);
    // System.out.println("  Pos: " + currentStack);
    }
}
Also used : DefaultSwitchEdge(org.mapleir.flowgraph.edges.DefaultSwitchEdge) SwitchEdge(org.mapleir.flowgraph.edges.SwitchEdge) BasicBlock(org.mapleir.ir.cfg.BasicBlock) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) DefaultSwitchEdge(org.mapleir.flowgraph.edges.DefaultSwitchEdge)

Aggregations

DefaultSwitchEdge (org.mapleir.flowgraph.edges.DefaultSwitchEdge)1 SwitchEdge (org.mapleir.flowgraph.edges.SwitchEdge)1 BasicBlock (org.mapleir.ir.cfg.BasicBlock)1 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)1