1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 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.rop; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstType; 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.type.StdTypeList; 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.type.TypeList; 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.FixedSizeList; 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.IntList; 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * List of catch entries, that is, the elements of an "exception table," 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * which is part of a standard {@code Code} attribute. 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class ByteCatchList extends FixedSizeList { 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} convenient zero-entry instance */ 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final ByteCatchList EMPTY = new ByteCatchList(0); 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance. 35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param count the number of elements to be in the table 37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public ByteCatchList(int count) { 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul super(count); 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the total length of this structure in bytes, when included in 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * a {@code Code} attribute. The returned value includes the 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * two bytes for {@code exception_table_length}. 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 2;} the total length, in bytes 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int byteLength() { 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return 2 + size() * 8; 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the indicated item. 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param n {@code >= 0;} which item 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code null-ok;} the indicated item 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Item get(int n) { 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (Item) get0(n); 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Sets the item at the given index. 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param n {@code >= 0, < size();} which entry to set 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param item {@code non-null;} the item 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public void set(int n, Item item) { 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (item == null) { 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("item == null"); 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul set0(n, item); 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Sets the item at the given index. 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param n {@code >= 0, < size();} which entry to set 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param startPc {@code >= 0;} the start pc (inclusive) of the handler's range 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param endPc {@code >= startPc;} the end pc (exclusive) of the 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * handler's range 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param handlerPc {@code >= 0;} the pc of the exception handler 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param exceptionClass {@code null-ok;} the exception class or 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code null} to catch all exceptions with this handler 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public void set(int n, int startPc, int endPc, int handlerPc, 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul CstType exceptionClass) { 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul set0(n, new Item(startPc, endPc, handlerPc, exceptionClass)); 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the list of items active at the given address. The result is 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * automatically made immutable. 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param pc which address 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} list of exception handlers active at 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code pc} 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public ByteCatchList listFor(int pc) { 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int sz = size(); 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Item[] resultArr = new Item[sz]; 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int resultSz = 0; 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < sz; i++) { 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Item one = get(i); 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (one.covers(pc) && typeNotFound(one, resultArr, resultSz)) { 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul resultArr[resultSz] = one; 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul resultSz++; 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (resultSz == 0) { 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return EMPTY; 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul ByteCatchList result = new ByteCatchList(resultSz); 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < resultSz; i++) { 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.set(i, resultArr[i]); 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.setImmutable(); 124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return result; 125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Helper method for {@link #listFor}, which tells whether a match 129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * is <i>not</i> found for the exception type of the given item in 130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * the given array. A match is considered to be either an exact type 131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * match or the class {@code Object} which represents a catch-all. 132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param item {@code non-null;} item with the exception type to look for 134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param arr {@code non-null;} array to search in 135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param count {@code non-null;} maximum number of elements in the array to check 136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code true} iff the exception type is <i>not</i> found 137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private static boolean typeNotFound(Item item, Item[] arr, int count) { 139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul CstType type = item.getExceptionClass(); 140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < count; i++) { 142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul CstType one = arr[i].getExceptionClass(); 143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if ((one == type) || (one == CstType.OBJECT)) { 144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return true; 149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns a target list corresponding to this instance. The result 153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * is a list of all the exception handler addresses, with the given 154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code noException} address appended if appropriate. The 155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * result is automatically made immutable. 156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param noException {@code >= -1;} the no-exception address to append, or 158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code -1} not to append anything 159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} list of exception targets, with 160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code noException} appended if necessary 161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 162917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public IntList toTargetList(int noException) { 163917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (noException < -1) { 164917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("noException < -1"); 165917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 166917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 167917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul boolean hasDefault = (noException >= 0); 168917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int sz = size(); 169917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 170917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (sz == 0) { 171917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (hasDefault) { 172917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /* 173917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * The list is empty, but there is a no-exception 174917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * address; so, the result is just that address. 175917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 176917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return IntList.makeImmutable(noException); 177917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 178917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /* 179917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * The list is empty and there isn't even a no-exception 180917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * address. 181917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 182917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return IntList.EMPTY; 183917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 184917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 185917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul IntList result = new IntList(sz + (hasDefault ? 1 : 0)); 186917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 187917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < sz; i++) { 188917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.add(get(i).getHandlerPc()); 189917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 190917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 191917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (hasDefault) { 192917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.add(noException); 193917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 194917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 195917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.setImmutable(); 196917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return result; 197917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 198917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 199917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 200917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns a rop-style catches list equivalent to this one. 201917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 202917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the converted instance 203917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 204917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public TypeList toRopCatchList() { 205917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int sz = size(); 206917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (sz == 0) { 207917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return StdTypeList.EMPTY; 208917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 209917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 210917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul StdTypeList result = new StdTypeList(sz); 211917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 212917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < sz; i++) { 213917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.set(i, get(i).getExceptionClass().getClassType()); 214917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 215917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 216917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.setImmutable(); 217917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return result; 218917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 219917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 220917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 221917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Item in an exception handler list. 222917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 223917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static class Item { 224917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code >= 0;} the start pc (inclusive) of the handler's range */ 225917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final int startPc; 226917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 227917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code >= startPc;} the end pc (exclusive) of the handler's range */ 228917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final int endPc; 229917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 230917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code >= 0;} the pc of the exception handler */ 231917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final int handlerPc; 232917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 233917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code null-ok;} the exception class or {@code null} to catch all 234917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * exceptions with this handler */ 235917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final CstType exceptionClass; 236917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 237917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 238917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance. 239917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 240917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param startPc {@code >= 0;} the start pc (inclusive) of the 241917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * handler's range 242917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param endPc {@code >= startPc;} the end pc (exclusive) of the 243917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * handler's range 244917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param handlerPc {@code >= 0;} the pc of the exception handler 245917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param exceptionClass {@code null-ok;} the exception class or 246917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code null} to catch all exceptions with this handler 247917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 248917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Item(int startPc, int endPc, int handlerPc, 249917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul CstType exceptionClass) { 250917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (startPc < 0) { 251917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("startPc < 0"); 252917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 253917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 254917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (endPc < startPc) { 255917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("endPc < startPc"); 256917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 257917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 258917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (handlerPc < 0) { 259917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("handlerPc < 0"); 260917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 261917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 262917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.startPc = startPc; 263917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.endPc = endPc; 264917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.handlerPc = handlerPc; 265917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.exceptionClass = exceptionClass; 266917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 267917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 268917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 269917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the start pc (inclusive) of the handler's range. 270917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 271917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the start pc (inclusive) of the handler's range. 272917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 273917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getStartPc() { 274917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return startPc; 275917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 276917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 277917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 278917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the end pc (exclusive) of the handler's range. 279917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 280917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= startPc;} the end pc (exclusive) of the 281917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * handler's range. 282917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 283917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getEndPc() { 284917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return endPc; 285917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 286917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 287917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 288917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the pc of the exception handler. 289917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 290917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the pc of the exception handler 291917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 292917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int getHandlerPc() { 293917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return handlerPc; 294917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 295917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 296917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 297917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the class of exception handled. 298917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 299917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the exception class; {@link CstType#OBJECT} 300917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * if this entry handles all possible exceptions 301917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 302917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public CstType getExceptionClass() { 303917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (exceptionClass != null) ? 304917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul exceptionClass : CstType.OBJECT; 305917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 306917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 307917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 308917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns whether the given address is in the range of this item. 309917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 310917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param pc the address 311917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code true} iff this item covers {@code pc} 312917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 313917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean covers(int pc) { 314917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (pc >= startPc) && (pc < endPc); 315917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 316917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 317917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul} 318