1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2008 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.CstType; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.FixedSizeList; 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Table of catch entries. Each entry includes a range of code 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * addresses for which it is valid and an associated {@link 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * CatchHandlerList}. 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class CatchTable extends FixedSizeList 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson implements Comparable<CatchTable> { 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} empty instance */ 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static final CatchTable EMPTY = new CatchTable(0); 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance. All indices initially contain {@code null}. 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param size {@code >= 0;} the size of the table 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public CatchTable(int size) { 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson super(size); 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the element at the given index. It is an error to call 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * this with the index for an element which was never set; if you 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * do that, this will throw {@code NullPointerException}. 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param n {@code >= 0, < size();} which index 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} element at that index 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Entry get(int n) { 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (Entry) get0(n); 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Sets the entry at the given index. 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param n {@code >= 0, < size();} which index 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param entry {@code non-null;} the entry to set at {@code n} 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void set(int n, Entry entry) { 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson set0(n, entry); 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int compareTo(CatchTable other) { 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (this == other) { 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Easy out. 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return 0; 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int thisSize = size(); 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int otherSize = other.size(); 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int checkSize = Math.min(thisSize, otherSize); 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < checkSize; i++) { 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Entry thisEntry = get(i); 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Entry otherEntry = other.get(i); 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int compare = thisEntry.compareTo(otherEntry); 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (compare != 0) { 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return compare; 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (thisSize < otherSize) { 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return -1; 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else if (thisSize > otherSize) { 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return 1; 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return 0; 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Entry in a catch list. 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static class Entry implements Comparable<Entry> { 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code >= 0;} start address */ 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final int start; 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code > start;} end address (exclusive) */ 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final int end; 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} list of catch handlers */ 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final CatchHandlerList handlers; 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance. 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param start {@code >= 0;} start address 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param end {@code > start;} end address (exclusive) 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param handlers {@code non-null;} list of catch handlers 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Entry(int start, int end, CatchHandlerList handlers) { 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (start < 0) { 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("start < 0"); 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (end <= start) { 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("end <= start"); 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (handlers.isMutable()) { 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("handlers.isMutable()"); 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.start = start; 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.end = end; 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.handlers = handlers; 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int hashCode() { 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int hash = (start * 31) + end; 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson hash = (hash * 31) + handlers.hashCode(); 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return hash; 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean equals(Object other) { 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (other instanceof Entry) { 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (compareTo((Entry) other) == 0); 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return false; 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int compareTo(Entry other) { 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (start < other.start) { 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return -1; 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else if (start > other.start) { 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return 1; 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (end < other.end) { 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return -1; 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else if (end > other.end) { 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return 1; 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return handlers.compareTo(other.handlers); 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the start address. 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the start address 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getStart() { 171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return start; 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the end address (exclusive). 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code > start;} the end address (exclusive) 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getEnd() { 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return end; 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the handlers. 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the handlers 187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public CatchHandlerList getHandlers() { 189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return handlers; 190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 193