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