/*
 * 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.code.RegisterSpec;
import com.android.dx.rop.type.Type;
import com.android.dx.rop.type.TypeBearer;
import com.android.dx.util.ExceptionWithContext;
import com.android.dx.util.Hex;
import com.android.dx.util.MutabilityControl;
import com.android.dx.util.ToHuman;

/**
 * Representation of an array of local variables, with Java semantics.
 * 
 * <p><b>Note:</b> For the most part, the documentation for this class
 * ignores the distinction between {@link Type} and {@link
 * TypeBearer}.</p>
 */
public abstract class LocalsArray extends MutabilityControl implements ToHuman {

    /**
     * Constructs an instance, explicitly indicating the mutability.
     *
     * @param mutable {@code true} if this instance is mutable
     */   
    protected LocalsArray(boolean mutable) {
        super(mutable);
    }

    /**
     * Makes and returns a mutable copy of this instance.
     * 
     * @return {@code non-null;} the copy
     */
    public abstract LocalsArray copy();

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

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

    /**
     * Gets the maximum number of locals this instance can refer to.
     * 
     * @return the max locals
     */
    public abstract int getMaxLocals();

    /**
     * Sets the type stored at the given local index. If the given type
     * is category-2, then (a) the index must be at least two less than
     * {@link #getMaxLocals} and (b) the next index gets invalidated
     * by the operation. In case of either category, if the <i>previous</i>
     * local contains a category-2 value, then it too is invalidated by
     * this operation.
     * 
     * @param idx {@code >= 0, < getMaxLocals();} which local
     * @param type {@code non-null;} new type for the local at {@code idx}
     */
    public abstract void set(int idx, TypeBearer type);

    /**
     * Sets the type for the local indicated by the given register spec
     * to that register spec (which includes type and optional name
     * information). This is identical to calling
     * {@code set(spec.getReg(), spec)}.
     * 
     * @param spec {@code non-null;} register spec to use as the basis for the update
     */
    public abstract void set(RegisterSpec spec);

    /**
     * Invalidates the local at the given index.
     * 
     * @param idx {@code >= 0, < getMaxLocals();} which local
     */
    public abstract void invalidate(int idx);

    /**
     * Gets the type stored at the given local index, or {@code null}
     * if the given local is uninitialized / invalid.
     * 
     * @param idx {@code >= 0, < getMaxLocals();} which local
     * @return {@code null-ok;} the type of value stored in that local
     */
    public abstract TypeBearer getOrNull(int idx);

    /**
     * Gets the type stored at the given local index, only succeeding if
     * the given local contains a valid type (though it is allowed to
     * be an uninitialized instance).
     * 
     * @param idx {@code >= 0, < getMaxLocals();} which local
     * @return {@code non-null;} the type of value stored in that local
     * @throws SimException thrown if {@code idx} is valid, but
     * the contents are invalid
     */
    public abstract TypeBearer get(int idx);

    /**
     * Gets the type stored at the given local index, which is expected
     * to be an initialized category-1 value.
     * 
     * @param idx {@code >= 0, < getMaxLocals();} which local
     * @return {@code non-null;} the type of value stored in that local
     * @throws SimException thrown if {@code idx} is valid, but
     * one of the following holds: (a) the local is invalid; (b) the local
     * contains an uninitialized instance; (c) the local contains a
     * category-2 value
     */
    public abstract TypeBearer getCategory1(int idx);

    /**
     * Gets the type stored at the given local index, which is expected
     * to be a category-2 value.
     * 
     * @param idx {@code >= 0, < getMaxLocals();} which local
     * @return {@code non-null;} the type of value stored in that local
     * @throws SimException thrown if {@code idx} is valid, but
     * one of the following holds: (a) the local is invalid; (b) the local
     * contains a category-1 value
     */
    public abstract TypeBearer getCategory2(int idx);

    /**
     * Merges this instance with {@code other}. If the merged result is
     * the same as this instance, then this is returned (not a copy).
     *
     * @param other {@code non-null;} another LocalsArray
     * @return {@code non-null;} the merge result, a new instance or this
     */
    public abstract LocalsArray merge(LocalsArray other);

    /**
     * Merges this instance with a {@code LocalsSet} from a subroutine
     * caller. To be used when merging in the first block of a subroutine.
     *
     * @param other {@code other non-null;} another LocalsArray. The final locals
     * state of a subroutine caller.
     * @param predLabel the label of the subroutine caller block.
     * @return {@code non-null;} the merge result, a new instance or this
     */
    public abstract LocalsArraySet mergeWithSubroutineCaller
            (LocalsArray other, int predLabel);

    /**
     * Gets the locals set appropriate for the current execution context.
     * That is, if this is a {@code OneLocalsArray} instance, then return
     * {@code this}, otherwise return {@code LocalsArraySet}'s
     * primary.
     *
     * @return locals for this execution context.
     */
    protected abstract OneLocalsArray getPrimary();

}
