Package ru.andrew.jclazz.decompiler.engine.blockdetectors

Source Code of ru.andrew.jclazz.decompiler.engine.blockdetectors.UnconditionalBackLoopDetector

package ru.andrew.jclazz.decompiler.engine.blockdetectors;

import java.util.List;
import ru.andrew.jclazz.decompiler.engine.CodeItem;
import ru.andrew.jclazz.decompiler.engine.blocks.*;
import ru.andrew.jclazz.decompiler.engine.ops.GoToView;

public class UnconditionalBackLoopDetector implements Detector
{
    public void analyze(Block block)
    {
        block.reset();
        while (block.hasMoreOperations())
        {
            CodeItem citem = block.next();
            if (!(citem instanceof GoToView)) continue;

            GoToView gt = (GoToView) citem;
            if (gt.isBreak() || gt.isContinue() || gt.getLoop() != null) continue;
            if (!gt.isForwardBranch())
            {
                //if (isLastGoToWithSameTarget(block, gt))
                if (!isIfContinue(block, gt))
                {
                    createBackLoop(block, gt);
                }
                else
                {
                    gt.setContinue(true);
                }
            }
        }
    }

    private boolean isLastGoToWithSameTarget(Block block, GoToView gt)
    {
        List ops = block.getOperations();
        for (int i = 0; i < ops.size(); i++)
        {
            CodeItem citem = (CodeItem) ops.get(i);
            if (!(citem instanceof GoToView) || citem.getStartByte() <= gt.getStartByte()) continue;
            GoToView gt2 = (GoToView) citem;
            if (gt2.getTargetOperation() == gt.getTargetOperation())
            {
                return false;
            }
        }
        if (block.getParent() == null) return true;
        return isLastGoToWithSameTarget(block.getParent(), gt);
    }

    private boolean isIfContinue(Block block, GoToView priorTarget)
    {
        // priorTarget - backward goto, but this is not loop
        // Case: if - continue for while (...) {...} block
        Block loop = block;
        while (loop != null)
        {
            if ((loop instanceof Loop) && (((Loop) loop).getBeginPc() == priorTarget.getTargetOperation()))
            {
                // This is "if - continue" case
                return true;
            }
            loop = loop.getParent();
        }

        return false;
    }

    private void createBackLoop(Block block, GoToView gotoView)
    {
        // Searching for outermost block for loop
        Block parent = block;
        Block foundBlock;
        CodeItem target;
        do
        {
            target = parent.getOperationByStartByte(gotoView.getTargetOperation());
            foundBlock = parent;
            parent = parent.getParent();
        }
        while (target == null && parent != null);

        if (parent == null && target == null)
        {
            if (block instanceof Catch)
            {
                foundBlock = block.getParent();
            }
            else
            {
                foundBlock = block;
            }
        }

        Loop loop = new Loop(foundBlock, false);
        foundBlock.createSubBlock(gotoView.getTargetOperation(), gotoView.getStartByte(), loop);
        loop.setAlwaysTrueCondition(true);
        block.removeOperation(gotoView.getStartByte());
    }
}
TOP

Related Classes of ru.andrew.jclazz.decompiler.engine.blockdetectors.UnconditionalBackLoopDetector

TOP
Copyright © 2018 www.massapi.com. 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.