Package com.strobel.assembler.flowanalysis

Examples of com.strobel.assembler.flowanalysis.ControlFlowNode


            //

            if (!handlerInfo.tryNodes.isEmpty() &&
                !handlerInfo.handlerNodes.isEmpty()) {

                final ControlFlowNode lastTryNode = handlerInfo.tryNodes.get(handlerInfo.tryNodes.size() - 1);
                final HandlerInfo nearestHandler = findNearestHandler(handlerInfo, handlersCopy);
                final ControlFlowNode lastCatchNode = nearestHandler.handlerNodes.get(nearestHandler.handlerNodes.size() - 1);

                if (lastTryNode.getBlockIndex() < lastCatchNode.getBlockIndex() - 1) {
                    final ControlFlowNode nodeAfterTry = cfg.getNodes().get(lastTryNode.getBlockIndex() + 1);

                    if (nodeAfterTry != null &&
                        nodeAfterTry.getNodeType() == ControlFlowNodeType.Normal &&
                        nodeAfterTry.getStart() == nodeAfterTry.getEnd() &&
                        nodeAfterTry.getEnd().getNext() == nearestHandler.handlerNodes.get(0).getStart() &&
                        nodeAfterTry.getStart().getOpCode().isUnconditionalBranch()) {

                        handlerInfo.tryNodes.add(nodeAfterTry);

                        if (handler.isCatch()) {
                            exceptionHandlers.set(
                                i,
                                ExceptionHandler.createCatch(
                                    new ExceptionBlock(
                                        handler.getTryBlock().getFirstInstruction(),
                                        nodeAfterTry.getStart()
                                    ),
                                    handler.getHandlerBlock(),
                                    handler.getCatchType()
                                )
                            );
                        }
                        else {
                            exceptionHandlers.set(
                                i,
                                ExceptionHandler.createFinally(
                                    new ExceptionBlock(
                                        handler.getTryBlock().getFirstInstruction(),
                                        nodeAfterTry.getStart()
                                    ),
                                    handler.getHandlerBlock()
                                )
                            );
                        }
View Full Code Here


        final List<ExceptionHandler> handlers = new ArrayList<>();

        for (final ExceptionTableEntry entry : tableEntries) {
            final Instruction handlerStart = instructions.atOffset(entry.getHandlerOffset());

            final ControlFlowNode handlerStartNode = firstOrDefault(
                cfg.getNodes(),
                new Predicate<ControlFlowNode>() {
                    @Override
                    public boolean test(final ControlFlowNode node) {
                        return node.getStart() == handlerStart;
                    }
                }
            );

            if (handlerStartNode == null) {
                throw new IllegalStateException(
                    format(
                        "Could not find entry node for handler at offset %d.",
                        handlerStart.getOffset()
                    )
                );
            }

            final Set<ControlFlowNode> dominationSet = new HashSet<>();
            final List<ControlFlowNode> dominatedNodes = new ArrayList<>();

            for (final ControlFlowNode node : cfg.getNodes()) {
                if (handlerStartNode.dominates(node)) {
                    if (dominationSet.add(node)) {
                        dominatedNodes.add(node);
                    }
                }
            }
View Full Code Here

        return handlers;
    }

    private void computeDominance(final ControlFlowGraph cfg) {
        final ControlFlowNode entryPoint = cfg.getEntryPoint();

        entryPoint.setImmediateDominator(entryPoint);

        final BooleanBox changed = new BooleanBox(true);

        while (changed.get()) {
            changed.set(false);
            cfg.resetVisited();

            entryPoint.traversePreOrder(
                new Function<ControlFlowNode, Iterable<ControlFlowNode>>() {
                    @Override
                    public final Iterable<ControlFlowNode> apply(final ControlFlowNode input) {
                        return input.getSuccessors();
                    }
                },
                new Block<ControlFlowNode>() {
                    @Override
                    public final void accept(final ControlFlowNode b) {
                        if (b == entryPoint) {
                            return;
                        }

                        ControlFlowNode newImmediateDominator = null;

                        for (final ControlFlowNode p : b.getPredecessors()) {
                            if (p.isVisited() && p != b) {
                                newImmediateDominator = p;
                                break;
                            }
                        }

                        if (newImmediateDominator == null) {
                            throw new IllegalStateException("Could not compute new immediate dominator!");
                        }

                        for (final ControlFlowNode p : b.getPredecessors()) {
                            if (p != b && p.getImmediateDominator() != null) {
                                newImmediateDominator = ControlFlowGraph.findCommonDominator(p, newImmediateDominator);
                            }
                        }

                        if (b.getImmediateDominator() != newImmediateDominator) {
                            b.setImmediateDominator(newImmediateDominator);
                            changed.set(true);
                        }
                    }
                }
            );

            for (final ControlFlowNode node : _nodes) {
                if (node.getUserData() instanceof ExceptionTableEntry) {
                    node.traversePreOrder(
                        new Function<ControlFlowNode, Iterable<ControlFlowNode>>() {
                            @Override
                            public final Iterable<ControlFlowNode> apply(final ControlFlowNode input) {
                                return input.getSuccessors();
                            }
                        },
                        new Block<ControlFlowNode>() {
                            @Override
                            public final void accept(final ControlFlowNode b) {
                                if (b == node) {
                                    return;
                                }

                                ControlFlowNode newImmediateDominator = null;

                                for (final ControlFlowNode p : b.getPredecessors()) {
                                    if (p.isVisited() && p != b) {
                                        newImmediateDominator = p;
                                        break;
                                    }
                                }

                                if (newImmediateDominator == null) {
                                    throw new IllegalStateException("Could not compute new immediate dominator!");
                                }

                                for (final ControlFlowNode p : b.getPredecessors()) {
                                    if (p != b && p.getImmediateDominator() != null) {
                                        newImmediateDominator = ControlFlowGraph.findCommonDominator(p, newImmediateDominator);
                                    }
                                }

                                if (b.getImmediateDominator() != newImmediateDominator) {
                                    b.setImmediateDominator(newImmediateDominator);
                                    changed.set(true);
                                }
                            }
                        }
                    );
                }
            }
        }

        entryPoint.setImmediateDominator(null);

        for (final ControlFlowNode node : _nodes) {
            final ControlFlowNode immediateDominator = node.getImmediateDominator();

            if (immediateDominator != null) {
                immediateDominator.getDominatorTreeChildren().add(node);
            }
        }
    }
View Full Code Here

        for (int i = 0; i < instructions.size(); i++) {
            _offsets[i] = instructions.get(i).getOffset();
        }

        _entryPoint = new ControlFlowNode(_nextBlockId++, 0, ControlFlowNodeType.EntryPoint);
        _regularExit = new ControlFlowNode(_nextBlockId++, -1, ControlFlowNodeType.RegularExit);

        final ControlFlowNode exceptionalExit = new ControlFlowNode(_nextBlockId++, -2, ControlFlowNodeType.ExceptionalExit);

        _nodes.add(_entryPoint);
        _nodes.add(_regularExit);
        _nodes.add(exceptionalExit);
    }
View Full Code Here

            final ExceptionBlock handlerTry = handler.getTryBlock();

            for (final ExceptionHandler other : _exceptionHandlers) {
                final ExceptionBlock otherTry = other.getTryBlock();
                final HandlerInfo finallyInfo = handlers.get(handler);
                final ControlFlowNode firstInFinally = firstOrDefault(finallyInfo.handlerNodes);

                if (firstInFinally == null) {
                    continue;
                }

                Instruction firstFinallyInstruction = firstInFinally.getStart();
                Instruction lastFinallyInstruction = lastOrDefault(finallyInfo.handlerNodes).getEnd();

                if (lastFinallyInstruction.getOpCode() == OpCode.ATHROW &&
                    lastFinallyInstruction.getPrevious() != null) {

                    //
                    // If a finally handler catches, stores, and rethrows an exception, NOP-out the
                    // instructions responsible for those operations.  In the decompiled output, we
                    // don't expect to see such behavior.
                    //

                    final Instruction rethrowException = lastFinallyInstruction;
                    final Instruction loadException;
                    final Instruction storeException;

                    switch (firstFinallyInstruction.getOpCode()) {
                        case ASTORE:
                        case ASTORE_1:
                        case ASTORE_2:
                        case ASTORE_3:
                        case ASTORE_W:
                            storeException = firstFinallyInstruction;
                            firstFinallyInstruction = firstFinallyInstruction.getNext();
                            break;

                        default:
                            storeException = null;
                            break;
                    }

                    final Instruction previousFinallyInstruction = lastFinallyInstruction.getPrevious();

                    switch (previousFinallyInstruction.getOpCode()) {
                        case ALOAD:
                        case ALOAD_1:
                        case ALOAD_2:
                        case ALOAD_3:
                        case ALOAD_W:
                            loadException = previousFinallyInstruction;
                            lastFinallyInstruction = previousFinallyInstruction.getPrevious();
                            break;

                        default:
                            loadException = null;
                            break;
                    }

                    if (storeException != null && loadException != null) {
                        rethrowingFinallyStarts.add(storeException);
                        storeException.setOpCode(OpCode.POP);
                        storeException.setOperand(null);
                        loadException.setOpCode(OpCode.NOP);
                        loadException.setOperand(null);
                        rethrowException.setOpCode(OpCode.NOP);

                        if (rethrowException.getNext() == null) {
                            _leaveFinallyInstructions.add(rethrowException);
                        }
                    }
                }
                else if (rethrowingFinallyStarts.contains(firstFinallyInstruction)) {
                    firstFinallyInstruction = firstFinallyInstruction.getNext();
                    lastFinallyInstruction = lastFinallyInstruction.getPrevious().getPrevious();
                }

                if (otherTry.getFirstInstruction().getOffset() == handlerTry.getFirstInstruction().getOffset() &&
                    otherTry.getLastInstruction().getOffset() == handlerTry.getLastInstruction().getOffset()) {

                    final HandlerInfo handlerInfo = handlers.get(other);
                    final ControlFlowNode lastInTry = lastOrDefault(handlerInfo.tryNodes);

                    if (lastInTry == null || lastInTry.precedes(firstInFinally)) {
                        continue;
                    }

                    ControlFlowNode firstAfterTry = null;

                    final Instruction lastInstructionInTry = lastInTry.getEnd();
                    final Instruction firstInstructionAfterTry = lastInstructionInTry.getNext();

                    if (firstInstructionAfterTry == null) {
                        continue;
                    }

                    for (final ControlFlowNode successor : lastInTry.getSuccessors()) {
                        if (successor.getStart() == firstInstructionAfterTry) {
                            firstAfterTry = successor;
                            break;
                        }
                    }

                    if (firstAfterTry == null || firstAfterTry == firstInFinally) {
                        continue;
                    }

                    assert firstAfterTry != null;

                    Instruction pTry, pFinally;

                    pTry = firstAfterTry.getStart();
                    pFinally = firstFinallyInstruction;

                    if ((pTry.getOpCode() == OpCode.GOTO ||
                         pTry.getOpCode() == OpCode.GOTO_W) &&
                        ((Instruction) pTry.getOperand(0)).getOffset() > lastFinallyInstruction.getOffset()) {
View Full Code Here

                        break;
                    }
                }
            }

            final ControlFlowNode node = new ControlFlowNode(_nodes.size(), blockStart, instructions.get(i));

            node.setUserData(blockStartExceptionHandler);

            _nodes.add(node);
        }
    }
View Full Code Here

            final Instruction end = node.getEnd();

            if (end != null &&
                end.getOffset() < _instructions.get(_instructions.size() - 1).getEndOffset()) {

                final ControlFlowNode innermostHandler = findInnermostExceptionHandlerNode(node.getEnd().getOffset());

                if (innermostHandler == null) {
                    continue;
                }

                for (final ExceptionTableEntry entry : _tableEntries) {
                    final ExceptionTableEntry handlerEntry = (ExceptionTableEntry) innermostHandler.getUserData();

                    if (handlerEntry == null) {
                        continue;
                    }

                    if (entry.getStartOffset() == handlerEntry.getStartOffset() &&
                        entry.getEndOffset() == handlerEntry.getEndOffset()) {

                        final ControlFlowNode handlerNode = firstOrDefault(
                            _nodes,
                            new Predicate<ControlFlowNode>() {
                                @Override
                                public boolean test(final ControlFlowNode node) {
                                    return node.getUserData() == entry;
View Full Code Here

        assert index >= 0;
        return index;
    }

    private ControlFlowEdge createEdge(final ControlFlowNode fromNode, final Instruction toInstruction, final JumpType type) {
        ControlFlowNode target = null;

        for (final ControlFlowNode node : _nodes) {
            if (node.getStart() != null && node.getStart().getOffset() == toInstruction.getOffset()) {
                if (target != null) {
                    throw new IllegalStateException("Multiple edge targets detected!");
View Full Code Here

        final List<ControlFlowNode> nodes = cfg.getNodes();
        final Map<Instruction, ControlFlowNode> nodeLookup = new IdentityHashMap<>();

        for (int j = 0; j < nodes.size(); j++) {
            final ControlFlowNode node = nodes.get(j);

            if (node.getNodeType() != ControlFlowNodeType.Normal) {
                continue;
            }

            for (Instruction i = node.getStart();
                 i != null && i.getOffset() < node.getEnd().getEndOffset();
                 i = i.getNext()) {

                nodeLookup.put(i, node);
            }
        }

        for (int i = 0; i < entries.size(); i++) {
            int minOffset = Integer.MAX_VALUE;

            final HandlerWithRange entry = entries.get(i);

            ControlFlowNode tryEnd = null;

            for (int j = 0; j < nodes.size(); j++) {
                final ControlFlowNode node = nodes.get(j);
                final Instruction end = node.getEnd();

                if (end != null && end.getOffset() == entry.entry.getEndOffset()) {
                    final Instruction previousInstruction = node.getStart().getPrevious();
                    final HandlerWithRange nearestHandler = findNearestHandler(entries, entry);
                    final Instruction firstHandlerInstruction = body.atOffset(nearestHandler.range.getStart());

                    if (end.getOpCode() == OpCode.GOTO && end.getNext() == firstHandlerInstruction) {
                        tryEnd = nodeLookup.get(end);
                    }
                    else if (previousInstruction != null) {
                        tryEnd = nodeLookup.get(previousInstruction);
                    }

                    break;
                }
            }

            for (int j = 0; j < nodes.size(); j++) {
                final ControlFlowNode node = nodes.get(j);

                if (node.getNodeType() != ControlFlowNodeType.Normal) {
                    continue;
                }

                if (node.getStart().getOffset() == entry.range.getStart()) {
                    final ControlFlowNode end = findHandlerEnd(node, tryEnd, new LinkedHashSet<ControlFlowNode>(), cfg.getRegularExit());

                    if (end != null && end.getNodeType() == ControlFlowNodeType.Normal) {
                        minOffset = end.getEnd().getEndOffset();
                    }
                    else {
                        minOffset = node.getEnd().getEndOffset();
                    }
View Full Code Here

            if (tryEnd != null && tryEnd.dominates(successor)) {
                continue;
            }

            if (successor.getDominatorTreeChildren().isEmpty()) {
                final ControlFlowNode result = findHandlerEnd(successor, tryEnd, visited, regularExit);

                if (result != null) {
                    return result;
                }
View Full Code Here

TOP

Related Classes of com.strobel.assembler.flowanalysis.ControlFlowNode

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.