Home | History | Annotate | Download | only in code
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.dx.cf.code;
     18 
     19 import com.android.dex.util.ExceptionWithContext;
     20 import com.android.dx.rop.code.RegisterSpec;
     21 import com.android.dx.rop.type.Type;
     22 import com.android.dx.rop.type.TypeBearer;
     23 import com.android.dx.util.MutabilityControl;
     24 import com.android.dx.util.ToHuman;
     25 
     26 /**
     27  * Representation of an array of local variables, with Java semantics.
     28  *
     29  * <p><b>Note:</b> For the most part, the documentation for this class
     30  * ignores the distinction between {@link Type} and {@link
     31  * TypeBearer}.</p>
     32  */
     33 public abstract class LocalsArray extends MutabilityControl implements ToHuman {
     34 
     35     /**
     36      * Constructs an instance, explicitly indicating the mutability.
     37      *
     38      * @param mutable {@code true} if this instance is mutable
     39      */
     40     protected LocalsArray(boolean mutable) {
     41         super(mutable);
     42     }
     43 
     44     /**
     45      * Makes and returns a mutable copy of this instance.
     46      *
     47      * @return {@code non-null;} the copy
     48      */
     49     public abstract LocalsArray copy();
     50 
     51     /**
     52      * Annotates (adds context to) the given exception with information
     53      * about this instance.
     54      *
     55      * @param ex {@code non-null;} the exception to annotate
     56      */
     57     public abstract void annotate(ExceptionWithContext ex);
     58 
     59     /**
     60      * Replaces all the occurrences of the given uninitialized type in
     61      * this array with its initialized equivalent.
     62      *
     63      * @param type {@code non-null;} type to replace
     64      */
     65     public abstract void makeInitialized(Type type);
     66 
     67     /**
     68      * Gets the maximum number of locals this instance can refer to.
     69      *
     70      * @return the max locals
     71      */
     72     public abstract int getMaxLocals();
     73 
     74     /**
     75      * Sets the type stored at the given local index. If the given type
     76      * is category-2, then (a) the index must be at least two less than
     77      * {@link #getMaxLocals} and (b) the next index gets invalidated
     78      * by the operation. In case of either category, if the <i>previous</i>
     79      * local contains a category-2 value, then it too is invalidated by
     80      * this operation.
     81      *
     82      * @param idx {@code >= 0, < getMaxLocals();} which local
     83      * @param type {@code non-null;} new type for the local at {@code idx}
     84      */
     85     public abstract void set(int idx, TypeBearer type);
     86 
     87     /**
     88      * Sets the type for the local indicated by the given register spec
     89      * to that register spec (which includes type and optional name
     90      * information). This is identical to calling
     91      * {@code set(spec.getReg(), spec)}.
     92      *
     93      * @param spec {@code non-null;} register spec to use as the basis for the update
     94      */
     95     public abstract void set(RegisterSpec spec);
     96 
     97     /**
     98      * Invalidates the local at the given index.
     99      *
    100      * @param idx {@code >= 0, < getMaxLocals();} which local
    101      */
    102     public abstract void invalidate(int idx);
    103 
    104     /**
    105      * Gets the type stored at the given local index, or {@code null}
    106      * if the given local is uninitialized / invalid.
    107      *
    108      * @param idx {@code >= 0, < getMaxLocals();} which local
    109      * @return {@code null-ok;} the type of value stored in that local
    110      */
    111     public abstract TypeBearer getOrNull(int idx);
    112 
    113     /**
    114      * Gets the type stored at the given local index, only succeeding if
    115      * the given local contains a valid type (though it is allowed to
    116      * be an uninitialized instance).
    117      *
    118      * @param idx {@code >= 0, < getMaxLocals();} which local
    119      * @return {@code non-null;} the type of value stored in that local
    120      * @throws SimException thrown if {@code idx} is valid, but
    121      * the contents are invalid
    122      */
    123     public abstract TypeBearer get(int idx);
    124 
    125     /**
    126      * Gets the type stored at the given local index, which is expected
    127      * to be an initialized category-1 value.
    128      *
    129      * @param idx {@code >= 0, < getMaxLocals();} which local
    130      * @return {@code non-null;} the type of value stored in that local
    131      * @throws SimException thrown if {@code idx} is valid, but
    132      * one of the following holds: (a) the local is invalid; (b) the local
    133      * contains an uninitialized instance; (c) the local contains a
    134      * category-2 value
    135      */
    136     public abstract TypeBearer getCategory1(int idx);
    137 
    138     /**
    139      * Gets the type stored at the given local index, which is expected
    140      * to be a category-2 value.
    141      *
    142      * @param idx {@code >= 0, < getMaxLocals();} which local
    143      * @return {@code non-null;} the type of value stored in that local
    144      * @throws SimException thrown if {@code idx} is valid, but
    145      * one of the following holds: (a) the local is invalid; (b) the local
    146      * contains a category-1 value
    147      */
    148     public abstract TypeBearer getCategory2(int idx);
    149 
    150     /**
    151      * Merges this instance with {@code other}. If the merged result is
    152      * the same as this instance, then this is returned (not a copy).
    153      *
    154      * @param other {@code non-null;} another LocalsArray
    155      * @return {@code non-null;} the merge result, a new instance or this
    156      */
    157     public abstract LocalsArray merge(LocalsArray other);
    158 
    159     /**
    160      * Merges this instance with a {@code LocalsSet} from a subroutine
    161      * caller. To be used when merging in the first block of a subroutine.
    162      *
    163      * @param other {@code other non-null;} another LocalsArray. The final locals
    164      * state of a subroutine caller.
    165      * @param predLabel the label of the subroutine caller block.
    166      * @return {@code non-null;} the merge result, a new instance or this
    167      */
    168     public abstract LocalsArraySet mergeWithSubroutineCaller
    169             (LocalsArray other, int predLabel);
    170 
    171     /**
    172      * Gets the locals set appropriate for the current execution context.
    173      * That is, if this is a {@code OneLocalsArray} instance, then return
    174      * {@code this}, otherwise return {@code LocalsArraySet}'s
    175      * primary.
    176      *
    177      * @return locals for this execution context.
    178      */
    179     protected abstract OneLocalsArray getPrimary();
    180 
    181 }
    182