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.util.FixedSizeList;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * List of "line number" entries, which are the contents of
2399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code LineNumberTable} attributes.
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class LineNumberList extends FixedSizeList {
2699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} zero-size instance */
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final LineNumberList EMPTY = new LineNumberList(0);
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns an instance which is the concatenation of the two given
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * instances.
32de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
3399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param list1 {@code non-null;} first instance
3499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param list2 {@code non-null;} second instance
3599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} combined instance
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static LineNumberList concat(LineNumberList list1,
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                        LineNumberList list2) {
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (list1 == EMPTY) {
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // easy case
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return list2;
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz1 = list1.size();
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz2 = list2.size();
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LineNumberList result = new LineNumberList(sz1 + sz2);
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz1; i++) {
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result.set(i, list1.get(i));
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz2; i++) {
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result.set(sz1 + i, list2.get(i));
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
61de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param count the number of elements to be in the list
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public LineNumberList(int count) {
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super(count);
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the indicated item.
70de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
7199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param n {@code >= 0;} which item
7299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the indicated item
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Item get(int n) {
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (Item) get0(n);
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the item at the given index.
80de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
8199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param n {@code >= 0, < size();} which element
8299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param item {@code non-null;} the item
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void set(int n, Item item) {
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (item == null) {
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("item == null");
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set0(n, item);
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the item at the given index.
94de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
9599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param n {@code >= 0, < size();} which element
9699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param startPc {@code >= 0;} start pc of this item
9799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param lineNumber {@code >= 0;} corresponding line number
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void set(int n, int startPc, int lineNumber) {
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        set0(n, new Item(startPc, lineNumber));
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the line number associated with the given address.
105de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
10699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param pc {@code >= 0;} the address to look up
10799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= -1;} the associated line number, or {@code -1} if
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * none is known
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int pcToLine(int pc) {
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Line number entries don't have to appear in any particular
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * order, so we have to do a linear search. TODO: If
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * this turns out to be a bottleneck, consider sorting the
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * list prior to use.
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz = size();
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int bestPc = -1;
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int bestLine = -1;
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < sz; i++) {
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Item one = get(i);
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int onePc = one.getStartPc();
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((onePc <= pc) && (onePc > bestPc)) {
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                bestPc = onePc;
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                bestLine = one.getLineNumber();
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (bestPc == pc) {
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // We can't do better than this
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return bestLine;
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Item in a line number table.
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static class Item {
14199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /** {@code >= 0;} start pc of this item */
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final int startPc;
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
14499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /** {@code >= 0;} corresponding line number */
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final int lineNumber;
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Constructs an instance.
149de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro         *
15099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param startPc {@code >= 0;} start pc of this item
15199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param lineNumber {@code >= 0;} corresponding line number
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public Item(int startPc, int lineNumber) {
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (startPc < 0) {
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IllegalArgumentException("startPc < 0");
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (lineNumber < 0) {
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IllegalArgumentException("lineNumber < 0");
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.startPc = startPc;
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.lineNumber = lineNumber;
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Gets the start pc of this item.
168de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro         *
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return the start pc
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public int getStartPc() {
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return startPc;
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Gets the line number of this item.
177de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro         *
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return the line number
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public int getLineNumber() {
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return lineNumber;
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
185