LocalsArray.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
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</code> 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 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 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 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     * 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     * <code>getMaxLocals()</code> 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 &gt;= 0, &lt; getMaxLocals(); which local
83     * @param type non-null; new type for the local at <code>idx</code>
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)</code>.
92     *
93     * @param spec 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 &gt;= 0, &lt; 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</code>
106     * if the given local is uninitialized / invalid.
107     *
108     * @param idx &gt;= 0, &lt; getMaxLocals(); which local
109     * @return 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 &gt;= 0, &lt; getMaxLocals(); which local
119     * @return non-null; the type of value stored in that local
120     * @throws SimException thrown if <code>idx</code> 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 &gt;= 0, &lt; getMaxLocals(); which local
130     * @return non-null; the type of value stored in that local
131     * @throws SimException thrown if <code>idx</code> 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 &gt;= 0, &lt; getMaxLocals(); which local
143     * @return non-null; the type of value stored in that local
144     * @throws SimException thrown if <code>idx</code> 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</code>. If the merged result is
152     * the same as this instance, then this is returned (not a copy).
153     *
154     * @param other non-null; another LocalsArray
155     * @return 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</code> from a subroutine
161     * caller. To be used when merging in the first block of a subroutine.
162     *
163     * @param other 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 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</code> instance, then return
174     * <code>this</code>, otherwise return <code>LocalsArraySet</code>'s
175     * primary.
176     *
177     * @return locals for this execution context.
178     */
179    protected abstract OneLocalsArray getPrimary();
180
181}
182