1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/*
2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project
3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License.
6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at
7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and
14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License.
15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */
16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.dex.code;
18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.Constant;
20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.type.Type;
21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.HashSet;
23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/**
25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Container for all the pieces of a concrete method. Each instance
26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * corresponds to a {@code code} structure in a {@code .dex} file.
27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */
28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class DalvCode {
29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * how much position info to preserve; one of the static
31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * constants in {@link PositionList}
32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private final int positionInfo;
34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@code null-ok;} the instruction list, ready for final processing;
37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * nulled out in {@link #finishProcessingIfNecessary}
38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private OutputFinisher unprocessedInsns;
40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@code non-null;} unprocessed catch table;
43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * nulled out in {@link #finishProcessingIfNecessary}
44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private CatchBuilder unprocessedCatches;
46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@code null-ok;} catch table; set in
49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@link #finishProcessingIfNecessary}
50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private CatchTable catches;
52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@code null-ok;} source positions list; set in
55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@link #finishProcessingIfNecessary}
56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private PositionList positions;
58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@code null-ok;} local variable list; set in
61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@link #finishProcessingIfNecessary}
62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private LocalList locals;
64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@code null-ok;} the processed instruction list; set in
67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@link #finishProcessingIfNecessary}
68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private DalvInsnList insns;
70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Constructs an instance.
73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param positionInfo how much position info to preserve; one of the
75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * static constants in {@link PositionList}
76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param unprocessedInsns {@code non-null;} the instruction list, ready
77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * for final processing
78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param unprocessedCatches {@code non-null;} unprocessed catch
79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * (exception handler) table
80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public DalvCode(int positionInfo, OutputFinisher unprocessedInsns,
82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            CatchBuilder unprocessedCatches) {
83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (unprocessedInsns == null) {
84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            throw new NullPointerException("unprocessedInsns == null");
85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (unprocessedCatches == null) {
88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            throw new NullPointerException("unprocessedCatches == null");
89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.positionInfo = positionInfo;
92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.unprocessedInsns = unprocessedInsns;
93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.unprocessedCatches = unprocessedCatches;
94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.catches = null;
95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.positions = null;
96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.locals = null;
97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.insns = null;
98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Finish up processing of the method.
102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private void finishProcessingIfNecessary() {
104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (insns != null) {
105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            return;
106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        insns = unprocessedInsns.finishProcessingAndGetList();
109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        positions = PositionList.make(insns, positionInfo);
110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        locals = LocalList.make(insns);
111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        catches = unprocessedCatches.build();
112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        // Let them be gc'ed.
114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        unprocessedInsns = null;
115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        unprocessedCatches = null;
116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Assign indices in all instructions that need them, using the
120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * given callback to perform lookups. This must be called before
121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@link #getInsns}.
122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param callback {@code non-null;} callback object
124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void assignIndices(AssignIndicesCallback callback) {
126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        unprocessedInsns.assignIndices(callback);
127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets whether this instance has any position data to represent.
131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code true} iff this instance has any position
133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * data to represent
134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public boolean hasPositions() {
136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return (positionInfo != PositionList.NONE)
137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            && unprocessedInsns.hasAnyPositionInfo();
138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets whether this instance has any local variable data to represent.
142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code true} iff this instance has any local variable
144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * data to represent
145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public boolean hasLocals() {
147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return unprocessedInsns.hasAnyLocalInfo();
148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets whether this instance has any catches at all (either typed
152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * or catch-all).
153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return whether this instance has any catches at all
155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public boolean hasAnyCatches() {
157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return unprocessedCatches.hasAnyCatches();
158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the set of catch types handled anywhere in the code.
162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} the set of catch types
164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public HashSet<Type> getCatchTypes() {
166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return unprocessedCatches.getCatchTypes();
167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the set of all constants referred to by instructions in
171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * the code.
172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} the set of constants
174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public HashSet<Constant> getInsnConstants() {
176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return unprocessedInsns.getAllConstants();
177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the list of instructions.
181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} the instruction list
183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public DalvInsnList getInsns() {
185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        finishProcessingIfNecessary();
186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return insns;
187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the catch (exception handler) table.
191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} the catch table
193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public CatchTable getCatches() {
195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        finishProcessingIfNecessary();
196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return catches;
197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the source positions list.
201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} the source positions list
203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public PositionList getPositions() {
205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        finishProcessingIfNecessary();
206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return positions;
207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the source positions list.
211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} the source positions list
213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public LocalList getLocals() {
215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        finishProcessingIfNecessary();
216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return locals;
217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Class used as a callback for {@link #assignIndices}.
221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static interface AssignIndicesCallback {
223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        /**
224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson         * Gets the index for the given constant.
225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson         *
226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson         * @param cst {@code non-null;} the constant
227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson         * @return {@code >= -1;} the index or {@code -1} if the constant
228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson         * shouldn't actually be reified with an index
229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson         */
230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        public int getIndex(Constant cst);
231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson}
233