/*
 * ProGuard -- shrinking, optimization, obfuscation, and preverification
 *             of Java bytecode.
 *
 * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package proguard.optimize.peephole;

import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;

import java.util.Arrays;

/**
 * This AttributeVisitor finds all instruction offsets, branch targets, and
 * exception targets in the CodeAttribute objects that it visits.
 *
 * @author Eric Lafortune
 */
public class BranchTargetFinder
extends      SimplifiedVisitor
implements   AttributeVisitor,
             InstructionVisitor,
             ExceptionInfoVisitor,
             ConstantVisitor
{
    //*
    private static final boolean DEBUG = false;
    /*/
    private static       boolean DEBUG = System.getProperty("btf") != null;
    //*/

    public static final int NONE = -1;

    // We'll explicitly mark instructions that are not part of a subroutine,
    // with NO_SUBROUTINE. Subroutines may just branch back into normal code
    // (e.g. due to a break instruction in Java code), and we want to avoid
    // marking such normal code as subroutine. The first mark wins, so we're
    // assuming that such code is marked as normal code before it is marked
    // as subroutine.
    public static final int UNKNOWN       = -1;
    public static final int NO_SUBROUTINE = -2;

    private static final short INSTRUCTION           = 1 << 0;
    private static final short BRANCH_ORIGIN         = 1 << 1;
    private static final short BRANCH_TARGET         = 1 << 2;
    private static final short AFTER_BRANCH          = 1 << 3;
    private static final short EXCEPTION_START       = 1 << 4;
    private static final short EXCEPTION_END         = 1 << 5;
    private static final short EXCEPTION_HANDLER     = 1 << 6;
    private static final short SUBROUTINE_INVOCATION = 1 << 7;
    private static final short SUBROUTINE_RETURNING  = 1 << 8;

    private static final int MAXIMUM_CREATION_OFFSETS = 32;


    private short[] instructionMarks      = new short[ClassConstants.TYPICAL_CODE_LENGTH + 1];
    private int[]   subroutineStarts      = new int[ClassConstants.TYPICAL_CODE_LENGTH];
    private int[]   subroutineEnds        = new int[ClassConstants.TYPICAL_CODE_LENGTH];
    private int[]   creationOffsets       = new int[ClassConstants.TYPICAL_CODE_LENGTH];
    private int[]   initializationOffsets = new int[ClassConstants.TYPICAL_CODE_LENGTH];
    private int     superInitializationOffset;
    private boolean containsSubroutines;

    private boolean repeat;
    private int     currentSubroutineStart;
    private int[]   recentCreationOffsets = new int[MAXIMUM_CREATION_OFFSETS];
    private int     recentCreationOffsetIndex;
    private boolean isInitializer;


    /**
     * Returns whether there is an instruction at the given offset in the
     * CodeAttribute that was visited most recently.
     */
    public boolean isInstruction(int offset)
    {
        return (instructionMarks[offset] & INSTRUCTION) != 0;
    }


    /**
     * Returns whether the instruction at the given offset is the target of
     * any kind in the CodeAttribute that was visited most recently.
     */
    public boolean isTarget(int offset)
    {
        return offset == 0 ||
               (instructionMarks[offset] & (BRANCH_TARGET   |
                                            EXCEPTION_START |
                                            EXCEPTION_END   |
                                            EXCEPTION_HANDLER)) != 0;
    }


    /**
     * Returns whether the instruction at the given offset is the origin of a
     * branch instruction in the CodeAttribute that was visited most recently.
     */
    public boolean isBranchOrigin(int offset)
    {
        return (instructionMarks[offset] & BRANCH_ORIGIN) != 0;
    }


    /**
     * Returns whether the instruction at the given offset is the target of a
     * branch instruction in the CodeAttribute that was visited most recently.
     */
    public boolean isBranchTarget(int offset)
    {
        return (instructionMarks[offset] & BRANCH_TARGET) != 0;
    }


    /**
     * Returns whether the instruction at the given offset comes right after a
     * definite branch instruction in the CodeAttribute that was visited most
     * recently.
     */
    public boolean isAfterBranch(int offset)
    {
        return (instructionMarks[offset] & AFTER_BRANCH) != 0;
    }


    /**
     * Returns whether the instruction at the given offset is the start of an
     * exception try block in the CodeAttribute that was visited most recently.
     */
    public boolean isExceptionStart(int offset)
    {
        return (instructionMarks[offset] & EXCEPTION_START) != 0;
    }


    /**
     * Returns whether the instruction at the given offset is the end of an
     * exception try block in the CodeAttribute that was visited most recently.
     */
    public boolean isExceptionEnd(int offset)
    {
        return (instructionMarks[offset] & EXCEPTION_END) != 0;
    }


    /**
     * Returns whether the instruction at the given offset is the start of an
     * exception catch block in the CodeAttribute that was visited most recently.
     */
    public boolean isExceptionHandler(int offset)
    {
        return (instructionMarks[offset] & EXCEPTION_HANDLER) != 0;
    }


    /**
     * Returns whether the instruction at the given offset is a subroutine
     * invocation in the CodeAttribute that was visited most recently.
     */
    public boolean isSubroutineInvocation(int offset)
    {
        return (instructionMarks[offset] & SUBROUTINE_INVOCATION) != 0;
    }


    /**
     * Returns whether the instruction at the given offset is the start of a
     * subroutine in the CodeAttribute that was visited most recently.
     */
    public boolean isSubroutineStart(int offset)
    {
        return subroutineStarts[offset] == offset;
    }


    /**
     * Returns whether the instruction at the given offset is part of a
     * subroutine in the CodeAttribute that was visited most recently.
     */
    public boolean isSubroutine(int offset)
    {
        return subroutineStarts[offset] >= 0;
    }


    /**
     * Returns whether the subroutine at the given offset is ever returning
     * by means of a regular 'ret' instruction.
     */
    public boolean isSubroutineReturning(int offset)
    {
        return (instructionMarks[offset] & SUBROUTINE_RETURNING) != 0;
    }


    /**
     * Returns the start offset of the subroutine at the given offset, in the
     * CodeAttribute that was visited most recently.
     */
    public int subroutineStart(int offset)
    {
        return subroutineStarts[offset];
    }


    /**
     * Returns the offset after the subroutine at the given offset, in the
     * CodeAttribute that was visited most recently.
     */
    public int subroutineEnd(int offset)
    {
        return subroutineEnds[offset];
    }


    /**
     * Returns whether the instruction at the given offset is a 'new'
     * instruction, in the CodeAttribute that was visited most recently.
     */
    public boolean isNew(int offset)
    {
        return initializationOffsets[offset] != NONE;
    }


    /**
     * Returns the instruction offset at which the object instance that is
     * created at the given 'new' instruction offset is initialized, or
     * <code>NONE</code> if it is not being created.
     */
    public int initializationOffset(int offset)
    {
        return initializationOffsets[offset];
    }


    /**
     * Returns whether the method is an instance initializer, in the
     * CodeAttribute that was visited most recently.
     */
    public boolean isInitializer()
    {
        return superInitializationOffset != NONE;
    }


    /**
     * Returns the instruction offset at which this initializer is calling
     * the "super" or "this" initializer method, or <code>NONE</code> if it is
     * not an initializer.
     */
    public int superInitializationOffset()
    {
        return superInitializationOffset;
    }


    /**
     * Returns whether the instruction at the given offset is the special
     * invocation of an instance initializer, in the CodeAttribute that was
     * visited most recently.
     */
    public boolean isInitializer(int offset)
    {
        return creationOffsets[offset] != NONE;
    }


    /**
     * Returns the offset of the 'new' instruction that corresponds to the
     * invocation of the instance initializer at the given offset, or
     * <code>AT_METHOD_ENTRY</code> if the invocation is calling the "super" or
     * "this" initializer method, , or <code>NONE</code> if it is not a 'new'
     * instruction.
     */
    public int creationOffset(int offset)
    {
        return creationOffsets[offset];
    }


    /**
     * Returns whether the method contains subroutines, in the CodeAttribute
     * that was visited most recently.
     */
    public boolean containsSubroutines()
    {
        return containsSubroutines;
    }


    // Implementations for AttributeVisitor.

    public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}


    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
    {
//        DEBUG =
//            clazz.getName().equals("abc/Def") &&
//            method.getName(clazz).equals("abc");

        // Make sure there are sufficiently large arrays.
        int codeLength = codeAttribute.u4codeLength;
        if (subroutineStarts.length < codeLength)
        {
            // Create new arrays.
            instructionMarks      = new short[codeLength + 1];
            subroutineStarts      = new int[codeLength];
            subroutineEnds        = new int[codeLength];
            creationOffsets       = new int[codeLength];
            initializationOffsets = new int[codeLength];

            // Reset the arrays.
            Arrays.fill(subroutineStarts,      0, codeLength, UNKNOWN);
            Arrays.fill(subroutineEnds,        0, codeLength, UNKNOWN);
            Arrays.fill(creationOffsets,       0, codeLength, NONE);
            Arrays.fill(initializationOffsets, 0, codeLength, NONE);
        }
        else
        {
            // Reset the arrays.
            Arrays.fill(instructionMarks,      0, codeLength, (short)0);
            Arrays.fill(subroutineStarts,      0, codeLength, UNKNOWN);
            Arrays.fill(subroutineEnds,        0, codeLength, UNKNOWN);
            Arrays.fill(creationOffsets,       0, codeLength, NONE);
            Arrays.fill(initializationOffsets, 0, codeLength, NONE);

            instructionMarks[codeLength] = 0;
        }

        superInitializationOffset = NONE;
        containsSubroutines       = false;

        // Iterate until all subroutines have been fully marked.
        do
        {
            repeat                    = false;
            currentSubroutineStart    = NO_SUBROUTINE;
            recentCreationOffsetIndex = 0;

            // Mark branch targets by going over all instructions.
            codeAttribute.instructionsAccept(clazz, method, this);

            // Mark branch targets in the exception table.
            codeAttribute.exceptionsAccept(clazz, method, this);
        }
        while (repeat);

        // The end of the code is a branch target sentinel.
        instructionMarks[codeLength] = BRANCH_TARGET;

        if (containsSubroutines)
        {
            // Set the subroutine returning flag and the subroutine end at each
            // subroutine start.
            int previousSubroutineStart = NO_SUBROUTINE;

            for (int offset = 0; offset < codeLength; offset++)
            {
                if (isInstruction(offset))
                {
                    int subroutineStart = subroutineStarts[offset];

                    if (subroutineStart >= 0 &&
                        isSubroutineReturning(offset))
                    {
                        instructionMarks[subroutineStart] |= SUBROUTINE_RETURNING;
                    }

                    if (previousSubroutineStart >= 0)
                    {
                        subroutineEnds[previousSubroutineStart] = offset;
                    }

                    previousSubroutineStart = subroutineStart;
                }
            }

            if (previousSubroutineStart >= 0)
            {
                subroutineEnds[previousSubroutineStart] = codeLength;
            }

            // Set the subroutine returning flag and the subroutine end at each
            // subroutine instruction, based on the marks at the subroutine
            // start.
            for (int offset = 0; offset < codeLength; offset++)
            {
                if (isSubroutine(offset))
                {
                    int subroutineStart = subroutineStarts[offset];

                    if (isSubroutineReturning(subroutineStart))
                    {
                        instructionMarks[offset] |= SUBROUTINE_RETURNING;
                    }

                    subroutineEnds[offset] = subroutineEnds[subroutineStart];
                }
            }
        }

        if (DEBUG)
        {
            System.out.println();
            System.out.println("Branch targets: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));

            for (int index = 0; index < codeLength; index++)
            {
                if (isInstruction(index))
                {
                    System.out.println("" +
                                       (isBranchOrigin(index)         ? 'B' : '-') +
                                       (isAfterBranch(index)          ? 'b' : '-') +
                                       (isBranchTarget(index)         ? 'T' : '-') +
                                       (isExceptionStart(index)       ? 'E' : '-') +
                                       (isExceptionEnd(index)         ? 'e' : '-') +
                                       (isExceptionHandler(index)     ? 'H' : '-') +
                                       (isSubroutineInvocation(index) ? 'J' : '-') +
                                       (isSubroutineStart(index)      ? 'S' : '-') +
                                       (isSubroutineReturning(index)  ? 'r' : '-') +
                                       (isSubroutine(index)           ? " ["+subroutineStart(index)+" -> "+subroutineEnd(index)+"]" : "") +
                                       (isNew(index)                  ? " ["+initializationOffset(index)+"] " : " ---- ") +
                                       InstructionFactory.create(codeAttribute.code, index).toString(index));
                }
            }
        }
    }


    // Implementations for InstructionVisitor.

    public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)
    {
        // Mark the instruction.
        instructionMarks[offset] |= INSTRUCTION;

        // Check if this is an instruction of a subroutine.
        checkSubroutine(offset);

        byte opcode = simpleInstruction.opcode;
        if (opcode == InstructionConstants.OP_IRETURN ||
            opcode == InstructionConstants.OP_LRETURN ||
            opcode == InstructionConstants.OP_FRETURN ||
            opcode == InstructionConstants.OP_DRETURN ||
            opcode == InstructionConstants.OP_ARETURN ||
            opcode == InstructionConstants.OP_ATHROW)
        {
            // Mark the branch origin.
            markBranchOrigin(offset);

            // Mark the next instruction.
            markAfterBranchOrigin(offset + simpleInstruction.length(offset));
        }
    }


    public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
    {
        // Mark the instruction.
        instructionMarks[offset] |= INSTRUCTION;

        // Check if this is an instruction of a subroutine.
        checkSubroutine(offset);

        byte opcode = constantInstruction.opcode;
        if (opcode == InstructionConstants.OP_NEW)
        {
            // Push the 'new' instruction offset on the stack.
            recentCreationOffsets[recentCreationOffsetIndex++] = offset;
        }
        else if (opcode == InstructionConstants.OP_INVOKESPECIAL)
        {
            // Is it calling an instance initializer?
            isInitializer = false;
            clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
            if (isInitializer)
            {
                // Do we have any 'new' instruction offsets on the stack?
                if (recentCreationOffsetIndex > 0)
                {
                    // Pop the 'new' instruction offset from the stack.
                    int recentCreationOffset = recentCreationOffsets[--recentCreationOffsetIndex];

                    // Link the creation offset and the initialization offset.
                    // TODO: There could be multiple initialization offsets.
                    creationOffsets[offset] = recentCreationOffset;

                    initializationOffsets[recentCreationOffset] = offset;
                }
                else
                {
                    // Remember the super initialization offset.
                    // TODO: There could be multiple initialization offsets.
                    // For instance, in the constructor of the generated class
                    // groovy.inspect.swingui.GeneratedBytecodeAwareGroovyClassLoader
                    // in groovy-all-2.2.1.jar.
                    superInitializationOffset = offset;
                }
            }
        }
    }


    public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
    {
        // Mark the instruction.
        instructionMarks[offset] |= INSTRUCTION;

        // Check if this is an instruction of a subroutine.
        checkSubroutine(offset);

        if (variableInstruction.opcode == InstructionConstants.OP_RET)
        {
            // Mark the method.
            containsSubroutines = true;

            // Mark the branch origin.
            markBranchOrigin(offset);

            // Mark the subroutine return at its return instruction.
            instructionMarks[offset] |= SUBROUTINE_RETURNING;

            // Mark the next instruction.
            markAfterBranchOrigin(offset + variableInstruction.length(offset));
        }
    }


    public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)
    {
        int branchOffset = branchInstruction.branchOffset;
        int targetOffset = offset + branchOffset;

        // Mark the branch origin.
        markBranchOrigin(offset);

        // Check if this is an instruction of a subroutine.
        checkSubroutine(offset);

        // Mark the branch target.
        markBranchTarget(offset, branchOffset);

        byte opcode = branchInstruction.opcode;
        if (opcode == InstructionConstants.OP_JSR ||
            opcode == InstructionConstants.OP_JSR_W)
        {
            // Mark the method.
            containsSubroutines = true;

            // Mark the subroutine invocation.
            instructionMarks[offset] |= SUBROUTINE_INVOCATION;

            // Mark the new subroutine start.
            markBranchSubroutineStart(offset, branchOffset, targetOffset);
        }
        else if (currentSubroutineStart != UNKNOWN)
        {
            // Mark the continued subroutine start.
            markBranchSubroutineStart(offset, branchOffset, currentSubroutineStart);
        }

        if (opcode == InstructionConstants.OP_GOTO ||
            opcode == InstructionConstants.OP_GOTO_W)
        {
            // Mark the next instruction.
            markAfterBranchOrigin(offset + branchInstruction.length(offset));
        }
    }


    public void visitAnySwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SwitchInstruction switchInstruction)
    {
        // Mark the branch origin.
        markBranchOrigin(offset);

        // Check if this is an instruction of a subroutine.
        checkSubroutine(offset);

        // Mark the branch targets of the default jump offset.
        markBranch(offset, switchInstruction.defaultOffset);

        // Mark the branch targets of the jump offsets.
        markBranches(offset, switchInstruction.jumpOffsets);

        // Mark the next instruction.
        markAfterBranchOrigin(offset + switchInstruction.length(offset));
    }


    // Implementations for ConstantVisitor.

    public void visitAnyConstant(Clazz clazz, Constant constant) {}


    public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
    {
        // Remember whether the method is an initializer.
        isInitializer = methodrefConstant.getName(clazz).equals(ClassConstants.METHOD_NAME_INIT);
    }


    // Implementations for ExceptionInfoVisitor.

    public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
    {
        int startPC   = exceptionInfo.u2startPC;
        int endPC     = exceptionInfo.u2endPC;
        int handlerPC = exceptionInfo.u2handlerPC;

        // Mark the exception offsets.
        instructionMarks[startPC]   |= EXCEPTION_START;
        instructionMarks[endPC]     |= EXCEPTION_END;
        instructionMarks[handlerPC] |= EXCEPTION_HANDLER;

        // Mark the handler as part of a subroutine if necessary.
        if (subroutineStarts[handlerPC] == UNKNOWN &&
            subroutineStarts[startPC]   != UNKNOWN)
        {
            subroutineStarts[handlerPC] = subroutineStarts[startPC];

            // We'll have to go over all instructions again.
            repeat = true;
        }
    }


    // Small utility methods.

    /**
     * Marks the branch targets and their subroutine starts at the given
     * offsets.
     */
    private void markBranches(int offset, int[] jumpOffsets)
    {
        for (int index = 0; index < jumpOffsets.length; index++)
        {
            markBranch(offset, jumpOffsets[index]);
        }
    }


    /**
     * Marks the branch target and its subroutine start at the given offset.
     */
    private void markBranch(int offset, int jumpOffset)
    {
        markBranchTarget(offset, jumpOffset);

        if (currentSubroutineStart != UNKNOWN)
        {
            markBranchSubroutineStart(offset, jumpOffset, currentSubroutineStart);
        }
    }

    /**
     * Marks the branch origin at the given offset.
     */
    private void markBranchOrigin(int offset)
    {
        instructionMarks[offset] |= INSTRUCTION | BRANCH_ORIGIN;
    }


    /**
     * Marks the branch target at the given offset.
     */
    private void markBranchTarget(int offset, int jumpOffset)
    {
        int targetOffset = offset + jumpOffset;

        instructionMarks[targetOffset] |= BRANCH_TARGET;
    }


    /**
     * Marks the subroutine start at the given offset, if applicable.
     */
    private void markBranchSubroutineStart(int offset,
                                           int jumpOffset,
                                           int subroutineStart)
    {
        int targetOffset = offset + jumpOffset;

        // Are we marking a subroutine and branching to an offset that hasn't
        // been marked yet?
        if (subroutineStarts[targetOffset] == UNKNOWN)
        {
            // Is it a backward branch?
            if (jumpOffset < 0)
            {
                // Remember the smallest subroutine start.
                if (subroutineStart > targetOffset)
                {
                    subroutineStart = targetOffset;
                }

                // We'll have to go over all instructions again.
                repeat = true;
            }

            // Mark the subroutine start of the target.
            subroutineStarts[targetOffset] = subroutineStart;
        }
    }


    /**
     * Marks the instruction at the given offset, after a branch.
     */
    private void markAfterBranchOrigin(int nextOffset)
    {
        instructionMarks[nextOffset] |= AFTER_BRANCH;

        // Stop marking a subroutine.
        currentSubroutineStart = UNKNOWN;
    }


    /**
     * Checks if the specified instruction is inside a subroutine.
     */
    private void checkSubroutine(int offset)
    {
        // Are we inside a previously marked subroutine?
        if (subroutineStarts[offset] != UNKNOWN)
        {
            // Start marking a subroutine.
            currentSubroutineStart = subroutineStarts[offset];
        }

        // Are we marking a subroutine?
        else if (currentSubroutineStart != UNKNOWN)
        {
            // Mark the subroutine start.
            subroutineStarts[offset] = currentSubroutineStart;
        }
    }
}
