Package com.strobel.assembler.ir

Examples of com.strobel.assembler.ir.Instruction


        // Step 5: Replace LeaveTry edges with EndFinally edges.
        //

        for (int n = _nodes.size(), i = n - 1; i >= 0; i--) {
            final ControlFlowNode node = _nodes.get(i);
            final Instruction end = node.getEnd();

            if (end != null && !node.getOutgoing().isEmpty()) {
                for (final ControlFlowEdge edge : node.getOutgoing()) {
                    if (edge.getType() == JumpType.LeaveTry) {
                        assert end.getOpCode().isBranch();

                        final ControlFlowNode handlerBlock = findInnermostHandlerBlock(end.getOffset());
                        ControlFlowNode finallyBlock = findInnermostFinallyHandlerNode(end.getOffset());

                        if (handlerBlock != finallyBlock) {
                            final ExceptionHandler handler = handlerBlock.getExceptionHandler();
                            final ControlFlowNode adjacentFinally = findInnermostFinallyHandlerNode(handler.getTryBlock().getLastInstruction().getOffset());

                            if (finallyBlock.getNodeType() != ControlFlowNodeType.FinallyHandler || finallyBlock != adjacentFinally) {
                                finallyBlock = adjacentFinally;
                            }
                        }

                        final ControlFlowNode target = edge.getTarget();

                        target.getIncoming().remove(edge);
                        node.getOutgoing().remove(edge);

                        if (finallyBlock.getNodeType() == ControlFlowNodeType.ExceptionalExit) {
                            createEdge(node, finallyBlock, JumpType.Normal);
                            continue;
                        }

                        assert finallyBlock.getNodeType() == ControlFlowNodeType.FinallyHandler;

                        Instruction targetAddress = target.getStart();

                        if (targetAddress == null && target.getExceptionHandler() != null) {
                            targetAddress = target.getExceptionHandler().getHandlerBlock().getFirstInstruction();
                        }
View Full Code Here


        // Step 5b: Copy finally blocks into the LeaveTry edges.
        //

        for (int n = _nodes.size(), i = n - 1; i >= 0; i--) {
            final ControlFlowNode node = _nodes.get(i);
            final Instruction end = node.getEnd();

            if (end != null &&
                node.getOutgoing().size() == 1 &&
                node.getOutgoing().get(0).getType() == JumpType.LeaveTry) {

                assert end.getOpCode() == OpCode.GOTO ||
                       end.getOpCode() == OpCode.GOTO_W;

                final ControlFlowEdge edge = node.getOutgoing().get(0);
                final ControlFlowNode target = edge.getTarget();

                target.getIncoming().remove(edge);
                node.getOutgoing().clear();

                final ControlFlowNode handler = findInnermostExceptionHandlerNode(end.getEndOffset());

                assert handler.getNodeType() == ControlFlowNodeType.FinallyHandler;

                final ControlFlowNode copy = copyFinallySubGraph(handler, handler.getEndFinallyNode(), target);
View Full Code Here

    private static boolean isNarrower(final ExceptionHandler handler, final ExceptionHandler anchor) {
        if (handler == null || anchor == null) {
            return false;
        }

        final Instruction tryStart = handler.getTryBlock().getFirstInstruction();
        final Instruction anchorTryStart = anchor.getTryBlock().getFirstInstruction();

        if (tryStart.getOffset() > anchorTryStart.getOffset()) {
            return true;
        }

        final Instruction tryEnd = handler.getTryBlock().getLastInstruction();
        final Instruction anchorTryEnd = anchor.getTryBlock().getLastInstruction();

        return tryStart.getOffset() == anchorTryStart.getOffset() &&
               tryEnd.getOffset() < anchorTryEnd.getOffset();
    }
View Full Code Here

    private static boolean isNarrower(final InstructionBlock block, final InstructionBlock anchor) {
        if (block == null || anchor == null) {
            return false;
        }

        final Instruction start = block.getFirstInstruction();
        final Instruction anchorStart = anchor.getFirstInstruction();
        final Instruction end = block.getLastInstruction();
        final Instruction anchorEnd = anchor.getLastInstruction();

        if (start.getOffset() > anchorStart.getOffset()) {
            return end.getOffset() < anchorEnd.getEndOffset();
        }

        return start.getOffset() == anchorStart.getOffset() &&
               end.getOffset() < anchorEnd.getOffset();
    }
View Full Code Here

        final List<ExceptionHandler> handlers = new ArrayList<>();
        final Map<ExceptionTableEntry, ControlFlowNode> handlerStartNodes = new IdentityHashMap<>();

        for (final ExceptionTableEntry entry : builder._tableEntries) {
            final Instruction handlerStart = instructions.atOffset(entry.getHandlerOffset());
            final ControlFlowNode handlerStartNode = builder.findNode(handlerStart);

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

            if (handlerStartNode.getIncoming().isEmpty()) {
                builder.createEdge(cfg.getEntryPoint(), handlerStartNode, JumpType.Normal);
            }

            handlerStartNodes.put(entry, handlerStartNode);
        }

        cfg.computeDominance();
        cfg.computeDominanceFrontier();

        for (final ExceptionTableEntry entry : builder._tableEntries) {
            final ControlFlowNode handlerStart = handlerStartNodes.get(entry);
            final List<ControlFlowNode> dominatedNodes = new ArrayList<>();

            for (final ControlFlowNode node : findDominatedNodes(cfg, handlerStart)) {
                if (node.getNodeType() == ControlFlowNodeType.Normal) {
                    dominatedNodes.add(node);
                }
            }

            Collections.sort(
                dominatedNodes,
                new Comparator<ControlFlowNode>() {
                    @Override
                    public int compare(@NotNull final ControlFlowNode o1, @NotNull final ControlFlowNode o2) {
                        return Integer.compare(o1.getBlockIndex(), o2.getBlockIndex());
                    }
                }
            );

            for (int i = 1; i < dominatedNodes.size(); i++) {
                final ControlFlowNode prev = dominatedNodes.get(i - 1);
                final ControlFlowNode node = dominatedNodes.get(i);

                if (node.getBlockIndex() != prev.getBlockIndex() + 1) {
                    for (int j = i; j < dominatedNodes.size(); j++) {
                        dominatedNodes.remove(i);
                        break;
                    }
                }
            }

            final Instruction lastInstruction = instructions.get(instructions.size() - 1);

            final InstructionBlock tryBlock;

            if (entry.getEndOffset() == lastInstruction.getEndOffset()) {
                tryBlock = new InstructionBlock(
                    instructions.atOffset(entry.getStartOffset()),
                    lastInstruction
                );
            }
View Full Code Here

        //

        final InstructionCollection instructions = _instructions;

        for (int i = 0, n = instructions.size(); i < n; i++) {
            final Instruction blockStart = instructions.get(i);
            final ExceptionHandler blockStartExceptionHandler = findInnermostExceptionHandler(blockStart.getOffset());

            //
            // See how big we can make that block...
            //
            for (; i + 1 < n; i++) {
                final Instruction instruction = instructions.get(i);
                final OpCode opCode = instruction.getOpCode();

                if (opCode.isBranch() && !opCode.isJumpToSubroutine() /*|| opCode.canThrow()*/ || _hasIncomingJumps[i + 1]) {
                    break;
                }

                final Instruction next = instruction.getNext();

                if (next != null) {
                    //
                    // Ensure that blocks never contain instructions from different try blocks.
                    //
                    final ExceptionHandler innermostExceptionHandler = findInnermostExceptionHandler(next.getOffset());

                    if (innermostExceptionHandler != blockStartExceptionHandler) {
                        break;
                    }
                }
View Full Code Here

        final InstructionCollection instructions = _instructions;

        createEdge(_entryPoint, instructions.get(0), JumpType.Normal);

        for (final ControlFlowNode node : _nodes) {
            final Instruction end = node.getEnd();

            if (end == null || end.getOffset() >= _instructions.get(_instructions.size() - 1).getEndOffset()) {
                continue;
            }

            final OpCode endOpCode = end.getOpCode();

            //
            // Create normal edges from one instruction to the next.
            //
            if (!endOpCode.isUnconditionalBranch() || endOpCode.isJumpToSubroutine()) {
                final Instruction next = end.getNext();

                if (next != null && !isHandlerStart(next)) {
                    createEdge(node, next, JumpType.Normal);
                }
            }
View Full Code Here

        // Step 4: Create edges for the exceptional control flow.
        //

        for (final ControlFlowNode node : _nodes) {
            if (node.getNodeType() == ControlFlowNodeType.Normal) {
                final Instruction end = node.getEnd();
                final ExceptionHandler innermostHandler = findInnermostExceptionHandler(node.getEnd().getOffset());

                if (innermostHandler != null) {
                    for (final ExceptionHandler other : _handlerPlaceholders) {
                        if (other.getTryBlock().equals(innermostHandler.getTryBlock())) {
                            final ControlFlowNode handlerNode = firstOrDefault(
                                _nodes,
                                new Predicate<ControlFlowNode>() {
                                    @Override
                                    public boolean test(final ControlFlowNode node) {
                                        return node.getExceptionHandler() == other;
                                    }
                                }
                            );

                            if (node != handlerNode) {
                                createEdge(node, handlerNode, JumpType.JumpToExceptionHandler);
                            }
                        }
                    }
                }
                else if (end.getOpCode() == OpCode.ATHROW) {
                    createEdge(node, _exceptionalExit, JumpType.JumpToExceptionHandler);
                }
            }

            final ExceptionHandler exceptionHandler = node.getExceptionHandler();
View Full Code Here

    private static boolean isNarrower(final ExceptionHandler handler, final ExceptionHandler anchor) {
        if (handler == null || anchor == null) {
            return false;
        }

        final Instruction tryStart = handler.getTryBlock().getFirstInstruction();
        final Instruction anchorTryStart = anchor.getTryBlock().getFirstInstruction();

        if (tryStart.getOffset() > anchorTryStart.getOffset()) {
            return true;
        }

        final Instruction tryEnd = handler.getTryBlock().getLastInstruction();
        final Instruction anchorTryEnd = anchor.getTryBlock().getLastInstruction();

        return tryStart.getOffset() == anchorTryStart.getOffset() &&
               tryEnd.getOffset() < anchorTryEnd.getOffset();
    }
View Full Code Here

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

        for (final ExceptionTableEntry entry : _tableEntries) {
            final ExceptionHandler handler;
            final Instruction afterTry = _instructions.tryGetAtOffset(entry.getEndOffset());

            if (entry.getCatchType() == null) {
                handler = ExceptionHandler.createFinally(
                    new InstructionBlock(
                        _instructions.atOffset(entry.getStartOffset()),
                        afterTry != null ? afterTry.getPrevious() : last(_instructions)
                    ),
                    new InstructionBlock(
                        _instructions.atOffset(entry.getHandlerOffset()),
                        _instructions.atOffset(entry.getHandlerOffset())
                    )
                );
            }
            else {
                handler = ExceptionHandler.createCatch(
                    new InstructionBlock(
                        _instructions.atOffset(entry.getStartOffset()),
                        afterTry != null ? afterTry.getPrevious() : last(_instructions)
                    ),
                    new InstructionBlock(
                        _instructions.atOffset(entry.getHandlerOffset()),
                        _instructions.atOffset(entry.getHandlerOffset())
                    ),
View Full Code Here

TOP

Related Classes of com.strobel.assembler.ir.Instruction

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.