1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.cf.code;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstType;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.StdTypeList;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.FixedSizeList;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.IntList;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * List of catch entries, that is, the elements of an "exception table,"
2799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * which is part of a standard {@code Code} attribute.
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class ByteCatchList extends FixedSizeList {
3099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} convenient zero-entry instance */
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final ByteCatchList EMPTY = new ByteCatchList(0);
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param count the number of elements to be in the table
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ByteCatchList(int count) {
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super(count);
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the total length of this structure in bytes, when included in
4499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * a {@code Code} attribute. The returned value includes the
4599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * two bytes for {@code exception_table_length}.
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
4799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 2;} the total length, in bytes
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int byteLength() {
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 2 + size() * 8;
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the indicated item.
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
5699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param n {@code >= 0;} which item
5799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the indicated item
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Item get(int n) {
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (Item) get0(n);
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the item at the given index.
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
6699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param n {@code >= 0, < size();} which entry to set
6799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param item {@code non-null;} the item
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void set(int n, Item item) {
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (item == null) {
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("item == null");
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set0(n, item);
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the item at the given index.
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
8099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param n {@code >= 0, < size();} which entry to set
8199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param startPc {@code >= 0;} the start pc (inclusive) of the handler's range
8299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param endPc {@code >= startPc;} the end pc (exclusive) of the
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * handler's range
8499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param handlerPc {@code >= 0;} the pc of the exception handler
8599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param exceptionClass {@code null-ok;} the exception class or
8699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null} to catch all exceptions with this handler
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void set(int n, int startPc, int endPc, int handlerPc,
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            CstType exceptionClass) {
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set0(n, new Item(startPc, endPc, handlerPc, exceptionClass));
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the list of items active at the given address. The result is
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * automatically made immutable.
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param pc which address
9899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} list of exception handlers active at
9999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code pc}
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ByteCatchList listFor(int pc) {
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz = size();
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Item[] resultArr = new Item[sz];
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int resultSz = 0;
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz; i++) {
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Item one = get(i);
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (one.covers(pc) && typeNotFound(one, resultArr, resultSz)) {
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                resultArr[resultSz] = one;
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                resultSz++;
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (resultSz == 0) {
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return EMPTY;
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ByteCatchList result = new ByteCatchList(resultSz);
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < resultSz; i++) {
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result.set(i, resultArr[i]);
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result.setImmutable();
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Helper method for {@link #listFor}, which tells whether a match
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is <i>not</i> found for the exception type of the given item in
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the given array. A match is considered to be either an exact type
13199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * match or the class {@code Object} which represents a catch-all.
132de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
13399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param item {@code non-null;} item with the exception type to look for
13499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param arr {@code non-null;} array to search in
13599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param count {@code non-null;} maximum number of elements in the array to check
13699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code true} iff the exception type is <i>not</i> found
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static boolean typeNotFound(Item item, Item[] arr, int count) {
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CstType type = item.getExceptionClass();
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < count; i++) {
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            CstType one = arr[i].getExceptionClass();
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((one == type) || (one == CstType.OBJECT)) {
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return false;
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a target list corresponding to this instance. The result
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is a list of all the exception handler addresses, with the given
15499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code noException} address appended if appropriate. The
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * result is automatically made immutable.
156de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
15799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param noException {@code >= -1;} the no-exception address to append, or
15899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code -1} not to append anything
15999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} list of exception targets, with
16099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code noException} appended if necessary
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public IntList toTargetList(int noException) {
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (noException < -1) {
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("noException < -1");
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean hasDefault = (noException >= 0);
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz = size();
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sz == 0) {
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (hasDefault) {
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * The list is empty, but there is a no-exception
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * address; so, the result is just that address.
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return IntList.makeImmutable(noException);
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * The list is empty and there isn't even a no-exception
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * address.
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return IntList.EMPTY;
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        IntList result = new IntList(sz + (hasDefault ? 1 : 0));
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz; i++) {
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result.add(get(i).getHandlerPc());
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (hasDefault) {
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result.add(noException);
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result.setImmutable();
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a rop-style catches list equivalent to this one.
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
20299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the converted instance
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public TypeList toRopCatchList() {
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz = size();
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sz == 0) {
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return StdTypeList.EMPTY;
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StdTypeList result = new StdTypeList(sz);
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz; i++) {
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result.set(i, get(i).getExceptionClass().getClassType());
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result.setImmutable();
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Item in an exception handler list.
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static class Item {
22499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /** {@code >= 0;} the start pc (inclusive) of the handler's range */
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final int startPc;
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
22799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /** {@code >= startPc;} the end pc (exclusive) of the handler's range */
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final int endPc;
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
23099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /** {@code >= 0;} the pc of the exception handler */
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final int handlerPc;
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
23399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /** {@code null-ok;} the exception class or {@code null} to catch all
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * exceptions with this handler */
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final CstType exceptionClass;
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Constructs an instance.
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
24099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param startPc {@code >= 0;} the start pc (inclusive) of the
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * handler's range
24299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param endPc {@code >= startPc;} the end pc (exclusive) of the
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * handler's range
24499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param handlerPc {@code >= 0;} the pc of the exception handler
24599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param exceptionClass {@code null-ok;} the exception class or
24699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * {@code null} to catch all exceptions with this handler
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public Item(int startPc, int endPc, int handlerPc,
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                CstType exceptionClass) {
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (startPc < 0) {
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IllegalArgumentException("startPc < 0");
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (endPc < startPc) {
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IllegalArgumentException("endPc < startPc");
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (handlerPc < 0) {
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IllegalArgumentException("handlerPc < 0");
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.startPc = startPc;
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.endPc = endPc;
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.handlerPc = handlerPc;
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.exceptionClass = exceptionClass;
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Gets the start pc (inclusive) of the handler's range.
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
27199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @return {@code >= 0;} the start pc (inclusive) of the handler's range.
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public int getStartPc() {
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return startPc;
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Gets the end pc (exclusive) of the handler's range.
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
28099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @return {@code >= startPc;} the end pc (exclusive) of the
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * handler's range.
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public int getEndPc() {
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return endPc;
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Gets the pc of the exception handler.
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
29099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @return {@code >= 0;} the pc of the exception handler
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public int getHandlerPc() {
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return handlerPc;
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Gets the class of exception handled.
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
29999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @return {@code non-null;} the exception class; {@link CstType#OBJECT}
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * if this entry handles all possible exceptions
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public CstType getExceptionClass() {
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return (exceptionClass != null) ?
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                exceptionClass : CstType.OBJECT;
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Returns whether the given address is in the range of this item.
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param pc the address
31199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @return {@code true} iff this item covers {@code pc}
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public boolean covers(int pc) {
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return (pc >= startPc) && (pc < endPc);
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
318