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