/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.dx.cf.code;

import com.android.dx.rop.cst.CstType;
import com.android.dx.rop.type.StdTypeList;
import com.android.dx.rop.type.Type;
import com.android.dx.util.ExceptionWithContext;
import com.android.dx.util.IntList;

/**
 * Representation of a Java method execution frame. A frame consists
 * of a set of locals and a value stack, and it can be told to act on
 * them to load and store values between them and an "arguments /
 * results" area.
 */
public final class Frame {
    /** {@code non-null;} the locals */
    private final LocalsArray locals;

    /** {@code non-null;} the stack */
    private final ExecutionStack stack;

    /** {@code null-ok;} stack of labels of subroutines that this block is nested in */
    private final IntList subroutines;

    /**
     * Constructs an instance.
     *
     * @param locals {@code non-null;} the locals array to use
     * @param stack {@code non-null;} the execution stack to use
     */
    private Frame(LocalsArray locals, ExecutionStack stack) {
        this(locals, stack, IntList.EMPTY);
    }

    /**
     * Constructs an instance.
     *
     * @param locals {@code non-null;} the locals array to use
     * @param stack {@code non-null;} the execution stack to use
     * @param subroutines {@code non-null;} list of subroutine start labels for
     * subroutines this frame is nested in
     */
    private Frame(LocalsArray locals,
            ExecutionStack stack, IntList subroutines) {
        if (locals == null) {
            throw new NullPointerException("locals == null");
        }

        if (stack == null) {
            throw new NullPointerException("stack == null");
        }

        subroutines.throwIfMutable();

        this.locals = locals;
        this.stack = stack;
        this.subroutines = subroutines;
    }

    /**
     * Constructs an instance. The locals array initially consists of
     * all-uninitialized values (represented as {@code null}s) and
     * the stack starts out empty.
     *
     * @param maxLocals {@code >= 0;} the maximum number of locals this instance
     * can refer to
     * @param maxStack {@code >= 0;} the maximum size of the stack for this
     * instance
     */
    public Frame(int maxLocals, int maxStack) {
        this(new OneLocalsArray(maxLocals), new ExecutionStack(maxStack));
    }

    /**
     * Makes and returns a mutable copy of this instance. The copy
     * contains copies of the locals and stack (that is, it doesn't
     * share them with the original).
     *
     * @return {@code non-null;} the copy
     */
    public Frame copy() {
        return new Frame(locals.copy(), stack.copy(), subroutines);
    }

    /**
     * Makes this instance immutable.
     */
    public void setImmutable() {
        locals.setImmutable();
        stack.setImmutable();
        // "subroutines" is always immutable
    }

    /**
     * Replaces all the occurrences of the given uninitialized type in
     * this frame with its initialized equivalent.
     *
     * @param type {@code non-null;} type to replace
     */
    public void makeInitialized(Type type) {
        locals.makeInitialized(type);
        stack.makeInitialized(type);
    }

    /**
     * Gets the locals array for this instance.
     *
     * @return {@code non-null;} the locals array
     */
    public LocalsArray getLocals() {
        return locals;
    }

    /**
     * Gets the execution stack for this instance.
     *
     * @return {@code non-null;} the execution stack
     */
    public ExecutionStack getStack() {
        return stack;
    }

    /**
     * Returns the largest subroutine nesting this block may be in. An
     * empty list is returned if this block is not in any subroutine.
     * Subroutines are identified by the label of their start block. The
     * list is ordered such that the deepest nesting (the actual subroutine
     * this block is in) is the last label in the list.
     *
     * @return {@code non-null;} list as noted above
     */
    public IntList getSubroutines() {
        return subroutines;
    }

    /**
     * Initialize this frame with the method's parameters. Used for the first
     * frame.
     *
     * @param params Type list of method parameters.
     */
    public void initializeWithParameters(StdTypeList params) {
        int at = 0;
        int sz = params.size();

        for (int i = 0; i < sz; i++) {
             Type one = params.get(i);
             locals.set(at, one);
             at += one.getCategory();
        }
    }

    /**
     * Returns a Frame instance representing the frame state that should
     * be used when returning from a subroutine. The stack state of all
     * subroutine invocations is identical, but the locals state may differ.
     *
     * @param startLabel {@code >=0;} The label of the returning subroutine's
     * start block
     * @param subLabel {@code >=0;} A calling label of a subroutine
     * @return {@code null-ok;} an appropriatly-constructed instance, or null
     * if label is not in the set
     */
    public Frame subFrameForLabel(int startLabel, int subLabel) {
        LocalsArray subLocals = null;

        if (locals instanceof LocalsArraySet) {
            subLocals = ((LocalsArraySet)locals).subArrayForLabel(subLabel);
        }

        IntList newSubroutines;
        try {
            newSubroutines = subroutines.mutableCopy();

            if (newSubroutines.pop() != startLabel) {
                throw new RuntimeException("returning from invalid subroutine");
            }
            newSubroutines.setImmutable();
        } catch (IndexOutOfBoundsException ex) {
            throw new RuntimeException("returning from invalid subroutine");
        } catch (NullPointerException ex) {
            throw new NullPointerException("can't return from non-subroutine");
        }
       
        return (subLocals == null) ? null
                : new Frame(subLocals, stack, newSubroutines);
    }

    /**
     * Merges two frames. If the merged result is the same as this frame,
     * then this instance is returned.
     *
     * @param other {@code non-null;} another frame
     * @return {@code non-null;} the result of merging the two frames
     */
    public Frame mergeWith(Frame other) {
        LocalsArray resultLocals;
        ExecutionStack resultStack;
        IntList resultSubroutines;

        resultLocals = getLocals().merge(other.getLocals());
        resultStack = getStack().merge(other.getStack());
        resultSubroutines = mergeSubroutineLists(other.subroutines);

        resultLocals = adjustLocalsForSubroutines(
                resultLocals, resultSubroutines);

        if ((resultLocals == getLocals())
                && (resultStack == getStack())
                && subroutines == resultSubroutines) {
            return this;
        }

        return new Frame(resultLocals, resultStack, resultSubroutines);
    }

    /**
     * Merges this frame's subroutine lists with another. The result
     * is the deepest common nesting (effectively, the common prefix of the
     * two lists).
     * 
     * @param otherSubroutines label list of subroutine start blocks, from
     * least-nested to most-nested.
     * @return {@code non-null;} merged subroutine nest list as described above
     */
    private IntList mergeSubroutineLists(IntList otherSubroutines) {
        if (subroutines.equals(otherSubroutines)) {
            return subroutines;
        }

        IntList resultSubroutines = new IntList();

        int szSubroutines = subroutines.size();
        int szOthers = otherSubroutines.size();
        for (int i = 0; i < szSubroutines && i < szOthers
                && (subroutines.get(i) == otherSubroutines.get(i)); i++) {
            resultSubroutines.add(i);
        }

        resultSubroutines.setImmutable();

        return resultSubroutines;
    }

    /**
     * Adjusts a locals array to account for a merged subroutines list.
     * If a frame merge results in, effectively, a subroutine return through
     * a throw then the current locals will be a LocalsArraySet that will
     * need to be trimmed of all OneLocalsArray elements that relevent to
     * the subroutine that is returning.
     *
     * @param locals {@code non-null;} LocalsArray from before a merge
     * @param subroutines {@code non-null;} a label list of subroutine start blocks
     * representing the subroutine nesting of the block being merged into.
     * @return {@code non-null;} locals set appropriate for merge
     */
    private static LocalsArray adjustLocalsForSubroutines(
            LocalsArray locals, IntList subroutines) {
        if (! (locals instanceof LocalsArraySet)) {
            // nothing to see here
            return locals;
        }

        LocalsArraySet laSet = (LocalsArraySet)locals;

        if (subroutines.size() == 0) {
            /*
             * We've merged from a subroutine context to a non-subroutine
             * context, likely via a throw. Our successor will only need
             * to consider the primary locals state, not the state of
             * all possible subroutine paths.
             */

            return laSet.getPrimary();
        }

        /*
         * It's unclear to me if the locals set needs to be trimmed here.
         * If it does, then I believe it is all of the calling blocks
         * in the subroutine at the end of "subroutines" passed into
         * this method that should be removed.
         */
        return laSet;
    }

    /**
     * Merges this frame with the frame of a subroutine caller at
     * {@code predLabel}. Only called on the frame at the first
     * block of a subroutine.
     *
     * @param other {@code non-null;} another frame
     * @param subLabel label of subroutine start block
     * @param predLabel label of calling block
     * @return {@code non-null;} the result of merging the two frames
     */
    public Frame mergeWithSubroutineCaller(Frame other, int subLabel,
            int predLabel) {
        LocalsArray resultLocals;
        ExecutionStack resultStack;

        resultLocals = getLocals().mergeWithSubroutineCaller(
                other.getLocals(), predLabel);
        resultStack = getStack().merge(other.getStack());

        IntList newOtherSubroutines = other.subroutines.mutableCopy();
        newOtherSubroutines.add(subLabel);
        newOtherSubroutines.setImmutable();

        if ((resultLocals == getLocals())
                && (resultStack == getStack())
                && subroutines.equals(newOtherSubroutines)) {
            return this;
        }

        IntList resultSubroutines;

        if (subroutines.equals(newOtherSubroutines)) {
            resultSubroutines = subroutines;
        } else {
            /*
             * The new subroutines list should be the deepest of the two
             * lists being merged, but the postfix of the resultant list
             * must be equal to the shorter list.
             */
            IntList nonResultSubroutines;

            if (subroutines.size() > newOtherSubroutines.size()) {
                resultSubroutines = subroutines;
                nonResultSubroutines = newOtherSubroutines;
            } else {
                resultSubroutines = newOtherSubroutines;
                nonResultSubroutines = subroutines;
            }

            int szResult = resultSubroutines.size();
            int szNonResult = nonResultSubroutines.size();

            for (int i = szNonResult - 1; i >=0; i-- ) {
                if (nonResultSubroutines.get(i)
                        != resultSubroutines.get(
                        i + (szResult - szNonResult))) {
                    throw new
                            RuntimeException("Incompatible merged subroutines");
                }
            }
            
        }

        return new Frame(resultLocals, resultStack, resultSubroutines);
    }

    /**
     * Makes a frame for a subroutine start block, given that this is the
     * ending frame of one of the subroutine's calling blocks. Subroutine
     * calls may be nested and thus may have nested locals state, so we
     * start with an initial state as seen by the subroutine, but keep track
     * of the individual locals states that will be expected when the individual
     * subroutine calls return.
     *
     * @param subLabel label of subroutine start block
     * @param callerLabel {@code >=0;} label of the caller block where this frame
     * came from.
     * @return a new instance to begin a called subroutine.
     */
    public Frame makeNewSubroutineStartFrame(int subLabel, int callerLabel) {
        IntList newSubroutines = subroutines.mutableCopy();
        newSubroutines.add(subLabel);
        Frame newFrame = new Frame(locals.getPrimary(), stack,
                IntList.makeImmutable(subLabel));
        return newFrame.mergeWithSubroutineCaller(this, subLabel, callerLabel);
    }

    /**
     * Makes a new frame for an exception handler block invoked from this
     * frame.
     *
     * @param exceptionClass exception that the handler block will handle
     * @return new frame
     */
    public Frame makeExceptionHandlerStartFrame(CstType exceptionClass) {
        ExecutionStack newStack = getStack().copy();

        newStack.clear();
        newStack.push(exceptionClass);

        return new Frame(getLocals(), newStack, subroutines);
    }

    /**
     * Annotates (adds context to) the given exception with information
     * about this frame.
     *
     * @param ex {@code non-null;} the exception to annotate
     */
    public void annotate(ExceptionWithContext ex) {
        locals.annotate(ex);
        stack.annotate(ex);
    }
}
