/*
 * 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();

}
