1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2008 The Android Open Source Project 3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License"); 5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License. 6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at 7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * http://www.apache.org/licenses/LICENSE-2.0 9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software 11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS, 12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and 14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License. 15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.dex.code; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstType; 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.FixedSizeList; 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Table of catch entries. Each entry includes a range of code 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * addresses for which it is valid and an associated {@link 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * CatchHandlerList}. 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class CatchTable extends FixedSizeList 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul implements Comparable<CatchTable> { 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} empty instance */ 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final CatchTable EMPTY = new CatchTable(0); 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance. All indices initially contain {@code null}. 34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param size {@code >= 0;} the size of the table 36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public CatchTable(int size) { 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul super(size); 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the element at the given index. It is an error to call 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * this with the index for an element which was never set; if you 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * do that, this will throw {@code NullPointerException}. 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param n {@code >= 0, < size();} which index 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} element at that index 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Entry get(int n) { 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (Entry) get0(n); 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Sets the entry at the given index. 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param n {@code >= 0, < size();} which index 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param entry {@code non-null;} the entry to set at {@code n} 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public void set(int n, Entry entry) { 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul set0(n, entry); 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int compareTo(CatchTable other) { 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (this == other) { 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul // Easy out. 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return 0; 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int thisSize = size(); 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int otherSize = other.size(); 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int checkSize = Math.min(thisSize, otherSize); 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < checkSize; i++) { 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Entry thisEntry = get(i); 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Entry otherEntry = other.get(i); 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int compare = thisEntry.compareTo(otherEntry); 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (compare != 0) { 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return compare; 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (thisSize < otherSize) { 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return -1; 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } else if (thisSize > otherSize) { 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return 1; 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return 0; 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Entry in a catch list. 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static class Entry implements Comparable<Entry> { 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code >= 0;} start address */ 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final int start; 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code > start;} end address (exclusive) */ 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final int end; 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} list of catch handlers */ 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final CatchHandlerList handlers; 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance. 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param start {@code >= 0;} start address 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param end {@code > start;} end address (exclusive) 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param handlers {@code non-null;} list of catch handlers 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Entry(int start, int end, CatchHandlerList handlers) { 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (start < 0) { 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("start < 0"); 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (end <= start) { 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("end <= start"); 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (handlers.isMutable()) { 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("handlers.isMutable()"); 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.start = start; 126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.end = end; 127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.handlers = handlers; 128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul @Override 132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int hashCode() { 133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int hash = (start * 31) + end; 134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul hash = (hash * 31) + handlers.hashCode(); 135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return hash; 136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul @Override 140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean equals(Object other) { 141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (other instanceof Entry) { 142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (compareTo((Entry) other) == 0); 143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int compareTo(Entry other) { 150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (start < other.start) { 151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return -1; 152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } else if (start > other.start) { 153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return 1; 154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (end < other.end) { 157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return -1; 158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } else if (end > other.end) { 159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return 1; 160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 162917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return handlers.compareTo(other.handlers); 163917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 164917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 165917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 166917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the start address. 167917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 168917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the start address 169917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 170917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getStart() { 171917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return start; 172917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 173917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 174917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 175917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the end address (exclusive). 176917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 177917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code > start;} the end address (exclusive) 178917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 179917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getEnd() { 180917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return end; 181917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 182917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 183917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 184917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the handlers. 185917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 186917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the handlers 187917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 188917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public CatchHandlerList getHandlers() { 189917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return handlers; 190917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 191917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 192917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul} 193